Save This Page
Home » glassfish-v2ur2-b04-src » javax » servlet » http » [javadoc | source]
    1   
    2   
    3   /*
    4    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    5    * 
    6    * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
    7    * 
    8    * Portions Copyright Apache Software Foundation.
    9    * 
   10    * The contents of this file are subject to the terms of either the GNU
   11    * General Public License Version 2 only ("GPL") or the Common Development
   12    * and Distribution License("CDDL") (collectively, the "License").  You
   13    * may not use this file except in compliance with the License. You can obtain
   14    * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
   15    * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
   16    * language governing permissions and limitations under the License.
   17    * 
   18    * When distributing the software, include this License Header Notice in each
   19    * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
   20    * Sun designates this particular file as subject to the "Classpath" exception
   21    * as provided by Sun in the GPL Version 2 section of the License file that
   22    * accompanied this code.  If applicable, add the following below the License
   23    * Header, with the fields enclosed by brackets [] replaced by your own
   24    * identifying information: "Portions Copyrighted [year]
   25    * [name of copyright owner]"
   26    * 
   27    * Contributor(s):
   28    * 
   29    * If you wish your version of this file to be governed by only the CDDL or
   30    * only the GPL Version 2, indicate your decision by adding "[Contributor]
   31    * elects to include this software in this distribution under the [CDDL or GPL
   32    * Version 2] license."  If you don't indicate a single choice of license, a
   33    * recipient has the option to distribute your version of this file under
   34    * either the CDDL, the GPL Version 2 or to extend the choice of license to
   35    * its licensees as provided above.  However, if you add GPL Version 2 code
   36    * and therefore, elected the GPL Version 2 license, then the option applies
   37    * only if the new code is made subject to such option by the copyright
   38    * holder.
   39    */
   40   
   41   
   42   package javax.servlet.http;
   43   
   44   import java.io.IOException;
   45   import java.io.PrintWriter;
   46   import java.io.OutputStreamWriter;
   47   import java.io.UnsupportedEncodingException;
   48   import java.lang.reflect.Method;
   49   import java.text.MessageFormat;
   50   import java.util.Enumeration;
   51   import java.util.Locale;
   52   import java.util.ResourceBundle;
   53   
   54   import javax.servlet.GenericServlet;
   55   import javax.servlet.ServletException;
   56   import javax.servlet.ServletOutputStream;
   57   import javax.servlet.ServletRequest;
   58   import javax.servlet.ServletResponse;
   59   
   60   
   61   /**
   62    *
   63    * Provides an abstract class to be subclassed to create
   64    * an HTTP servlet suitable for a Web site. A subclass of
   65    * <code>HttpServlet</code> must override at least 
   66    * one method, usually one of these:
   67    *
   68    * <ul>
   69    * <li> <code>doGet</code>, if the servlet supports HTTP GET requests
   70    * <li> <code>doPost</code>, for HTTP POST requests
   71    * <li> <code>doPut</code>, for HTTP PUT requests
   72    * <li> <code>doDelete</code>, for HTTP DELETE requests
   73    * <li> <code>init</code> and <code>destroy</code>, 
   74    * to manage resources that are held for the life of the servlet
   75    * <li> <code>getServletInfo</code>, which the servlet uses to
   76    * provide information about itself 
   77    * </ul>
   78    *
   79    * <p>There's almost no reason to override the <code>service</code>
   80    * method. <code>service</code> handles standard HTTP
   81    * requests by dispatching them to the handler methods
   82    * for each HTTP request type (the <code>do</code><i>XXX</i>
   83    * methods listed above).
   84    *
   85    * <p>Likewise, there's almost no reason to override the 
   86    * <code>doOptions</code> and <code>doTrace</code> methods.
   87    * 
   88    * <p>Servlets typically run on multithreaded servers,
   89    * so be aware that a servlet must handle concurrent
   90    * requests and be careful to synchronize access to shared resources.
   91    * Shared resources include in-memory data such as
   92    * instance or class variables and external objects
   93    * such as files, database connections, and network 
   94    * connections.
   95    * See the
   96    * <a href="http://java.sun.com/Series/Tutorial/java/threads/multithreaded.html">
   97    * Java Tutorial on Multithreaded Programming</a> for more
   98    * information on handling multiple threads in a Java program.
   99    *
  100    * @author	Various
  101    */
  102   
  103   
  104   
  105   public abstract class HttpServlet extends GenericServlet
  106       implements java.io.Serializable
  107   {
  108       private static final String METHOD_DELETE = "DELETE";
  109       private static final String METHOD_HEAD = "HEAD";
  110       private static final String METHOD_GET = "GET";
  111       private static final String METHOD_OPTIONS = "OPTIONS";
  112       private static final String METHOD_POST = "POST";
  113       private static final String METHOD_PUT = "PUT";
  114       private static final String METHOD_TRACE = "TRACE";
  115   
  116       private static final String HEADER_IFMODSINCE = "If-Modified-Since";
  117       private static final String HEADER_LASTMOD = "Last-Modified";
  118       
  119       private static final String LSTRING_FILE =
  120   	"javax.servlet.http.LocalStrings";
  121       private static ResourceBundle lStrings =
  122   	ResourceBundle.getBundle(LSTRING_FILE);
  123      
  124      
  125      
  126       
  127       /**
  128        * Does nothing, because this is an abstract class.
  129        * 
  130        */
  131   
  132       public HttpServlet() { }
  133       
  134       
  135   
  136       /**
  137        *
  138        * Called by the server (via the <code>service</code> method) to
  139        * allow a servlet to handle a GET request. 
  140        *
  141        * <p>Overriding this method to support a GET request also
  142        * automatically supports an HTTP HEAD request. A HEAD
  143        * request is a GET request that returns no body in the
  144        * response, only the request header fields.
  145        *
  146        * <p>When overriding this method, read the request data,
  147        * write the response headers, get the response's writer or 
  148        * output stream object, and finally, write the response data.
  149        * It's best to include content type and encoding. When using
  150        * a <code>PrintWriter</code> object to return the response,
  151        * set the content type before accessing the
  152        * <code>PrintWriter</code> object.
  153        *
  154        * <p>The servlet container must write the headers before
  155        * committing the response, because in HTTP the headers must be sent
  156        * before the response body.
  157        *
  158        * <p>Where possible, set the Content-Length header (with the
  159        * {@link javax.servlet.ServletResponse#setContentLength} method),
  160        * to allow the servlet container to use a persistent connection 
  161        * to return its response to the client, improving performance.
  162        * The content length is automatically set if the entire response fits
  163        * inside the response buffer.
  164        *
  165        * <p>When using HTTP 1.1 chunked encoding (which means that the response
  166        * has a Transfer-Encoding header), do not set the Content-Length header.
  167        *
  168        * <p>The GET method should be safe, that is, without
  169        * any side effects for which users are held responsible.
  170        * For example, most form queries have no side effects.
  171        * If a client request is intended to change stored data,
  172        * the request should use some other HTTP method.
  173        *
  174        * <p>The GET method should also be idempotent, meaning
  175        * that it can be safely repeated. Sometimes making a
  176        * method safe also makes it idempotent. For example, 
  177        * repeating queries is both safe and idempotent, but
  178        * buying a product online or modifying data is neither
  179        * safe nor idempotent. 
  180        *
  181        * <p>If the request is incorrectly formatted, <code>doGet</code>
  182        * returns an HTTP "Bad Request" message.
  183        * 
  184        *
  185        * @param req	an {@link HttpServletRequest} object that
  186        *			contains the request the client has made
  187        *			of the servlet
  188        *
  189        * @param resp	an {@link HttpServletResponse} object that
  190        *			contains the response the servlet sends
  191        *			to the client
  192        * 
  193        * @exception IOException	if an input or output error is 
  194        *				detected when the servlet handles
  195        *				the GET request
  196        *
  197        * @exception ServletException	if the request for the GET
  198        *					could not be handled
  199        *
  200        * 
  201        * @see javax.servlet.ServletResponse#setContentType
  202        *
  203        */
  204   
  205       protected void doGet(HttpServletRequest req, HttpServletResponse resp)
  206   	throws ServletException, IOException
  207       {
  208   	String protocol = req.getProtocol();
  209   	String msg = lStrings.getString("http.method_get_not_supported");
  210   	if (protocol.endsWith("1.1")) {
  211   	    resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
  212   	} else {
  213   	    resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
  214   	}
  215       }
  216   
  217   
  218   
  219   
  220   
  221       /**
  222        *
  223        * Returns the time the <code>HttpServletRequest</code>
  224        * object was last modified,
  225        * in milliseconds since midnight January 1, 1970 GMT.
  226        * If the time is unknown, this method returns a negative
  227        * number (the default).
  228        *
  229        * <p>Servlets that support HTTP GET requests and can quickly determine
  230        * their last modification time should override this method.
  231        * This makes browser and proxy caches work more effectively,
  232        * reducing the load on server and network resources.
  233        *
  234        *
  235        * @param req	the <code>HttpServletRequest</code> 
  236        *			object that is sent to the servlet
  237        *
  238        * @return		a <code>long</code> integer specifying
  239        *			the time the <code>HttpServletRequest</code>
  240        *			object was last modified, in milliseconds
  241        *			since midnight, January 1, 1970 GMT, or
  242        *			-1 if the time is not known
  243        *
  244        */
  245   
  246       protected long getLastModified(HttpServletRequest req) {
  247   	return -1;
  248       }
  249   
  250   
  251   
  252   
  253       /**
  254        * 
  255        *
  256        * <p>Receives an HTTP HEAD request from the protected
  257        * <code>service</code> method and handles the
  258        * request.
  259        * The client sends a HEAD request when it wants
  260        * to see only the headers of a response, such as
  261        * Content-Type or Content-Length. The HTTP HEAD
  262        * method counts the output bytes in the response
  263        * to set the Content-Length header accurately.
  264        *
  265        * <p>If you override this method, you can avoid computing
  266        * the response body and just set the response headers
  267        * directly to improve performance. Make sure that the
  268        * <code>doHead</code> method you write is both safe
  269        * and idempotent (that is, protects itself from being
  270        * called multiple times for one HTTP HEAD request).
  271        *
  272        * <p>If the HTTP HEAD request is incorrectly formatted,
  273        * <code>doHead</code> returns an HTTP "Bad Request"
  274        * message.
  275        *
  276        *
  277        * @param req	the request object that is passed
  278        *			to the servlet
  279        *			
  280        * @param resp	the response object that the servlet
  281        *			uses to return the headers to the clien
  282        *
  283        * @exception IOException		if an input or output error occurs
  284        *
  285        * @exception ServletException	if the request for the HEAD
  286        *					could not be handled
  287        */
  288   
  289       protected void doHead(HttpServletRequest req, HttpServletResponse resp)
  290   	throws ServletException, IOException
  291       {
  292   	NoBodyResponse response = new NoBodyResponse(resp);
  293   	
  294   	doGet(req, response);
  295           response.setContentLength();
  296       }
  297       
  298   
  299   
  300   
  301   
  302       /**
  303        *
  304        * Called by the server (via the <code>service</code> method)
  305        * to allow a servlet to handle a POST request.
  306        *
  307        * The HTTP POST method allows the client to send
  308        * data of unlimited length to the Web server a single time
  309        * and is useful when posting information such as
  310        * credit card numbers.
  311        *
  312        * <p>When overriding this method, read the request data,
  313        * write the response headers, get the response's writer or output
  314        * stream object, and finally, write the response data. It's best 
  315        * to include content type and encoding. When using a
  316        * <code>PrintWriter</code> object to return the response, set the 
  317        * content type before accessing the <code>PrintWriter</code> object. 
  318        *
  319        * <p>The servlet container must write the headers before committing the
  320        * response, because in HTTP the headers must be sent before the 
  321        * response body.
  322        *
  323        * <p>Where possible, set the Content-Length header (with the
  324        * {@link javax.servlet.ServletResponse#setContentLength} method),
  325        * to allow the servlet container to use a persistent connection 
  326        * to return its response to the client, improving performance.
  327        * The content length is automatically set if the entire response fits
  328        * inside the response buffer.  
  329        *
  330        * <p>When using HTTP 1.1 chunked encoding (which means that the response
  331        * has a Transfer-Encoding header), do not set the Content-Length header. 
  332        *
  333        * <p>This method does not need to be either safe or idempotent.
  334        * Operations requested through POST can have side effects for
  335        * which the user can be held accountable, for example, 
  336        * updating stored data or buying items online.
  337        *
  338        * <p>If the HTTP POST request is incorrectly formatted,
  339        * <code>doPost</code> returns an HTTP "Bad Request" message.
  340        *
  341        *
  342        * @param req	an {@link HttpServletRequest} object that
  343        *			contains the request the client has made
  344        *			of the servlet
  345        *
  346        * @param resp	an {@link HttpServletResponse} object that
  347        *			contains the response the servlet sends
  348        *			to the client
  349        * 
  350        * @exception IOException	if an input or output error is 
  351        *				detected when the servlet handles
  352        *				the request
  353        *
  354        * @exception ServletException	if the request for the POST
  355        *					could not be handled
  356        *
  357        *
  358        * @see javax.servlet.ServletOutputStream
  359        * @see javax.servlet.ServletResponse#setContentType
  360        *
  361        *
  362        */
  363   
  364       protected void doPost(HttpServletRequest req, HttpServletResponse resp)
  365   	throws ServletException, IOException
  366       {
  367   	String protocol = req.getProtocol();
  368   	String msg = lStrings.getString("http.method_post_not_supported");
  369   	if (protocol.endsWith("1.1")) {
  370   	    resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
  371   	} else {
  372   	    resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
  373   	}
  374       }
  375   
  376   
  377   
  378   
  379       /**
  380        * Called by the server (via the <code>service</code> method)
  381        * to allow a servlet to handle a PUT request.
  382        *
  383        * The PUT operation allows a client to 
  384        * place a file on the server and is similar to 
  385        * sending a file by FTP.
  386        *
  387        * <p>When overriding this method, leave intact
  388        * any content headers sent with the request (including
  389        * Content-Length, Content-Type, Content-Transfer-Encoding,
  390        * Content-Encoding, Content-Base, Content-Language, Content-Location,
  391        * Content-MD5, and Content-Range). If your method cannot
  392        * handle a content header, it must issue an error message
  393        * (HTTP 501 - Not Implemented) and discard the request.
  394        * For more information on HTTP 1.1, see RFC 2616
  395        * <a href="http://www.ietf.org/rfc/rfc2616.txt"></a>.
  396        *
  397        * <p>This method does not need to be either safe or idempotent.
  398        * Operations that <code>doPut</code> performs can have side
  399        * effects for which the user can be held accountable. When using
  400        * this method, it may be useful to save a copy of the
  401        * affected URL in temporary storage.
  402        *
  403        * <p>If the HTTP PUT request is incorrectly formatted,
  404        * <code>doPut</code> returns an HTTP "Bad Request" message.
  405        *
  406        *
  407        * @param req	the {@link HttpServletRequest} object that
  408        *			contains the request the client made of
  409        *			the servlet
  410        *
  411        * @param resp	the {@link HttpServletResponse} object that
  412        *			contains the response the servlet returns
  413        *			to the client
  414        *
  415        * @exception IOException	if an input or output error occurs
  416        *				while the servlet is handling the
  417        *				PUT request
  418        *
  419        * @exception ServletException	if the request for the PUT
  420        *					cannot be handled
  421        *
  422        */
  423     
  424       protected void doPut(HttpServletRequest req, HttpServletResponse resp)
  425   	throws ServletException, IOException
  426       {
  427   	String protocol = req.getProtocol();
  428   	String msg = lStrings.getString("http.method_put_not_supported");
  429   	if (protocol.endsWith("1.1")) {
  430   	    resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
  431   	} else {
  432   	    resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
  433   	}
  434       }
  435   
  436   
  437   
  438   
  439       /**
  440        * 
  441        * Called by the server (via the <code>service</code> method)
  442        * to allow a servlet to handle a DELETE request.
  443        *
  444        * The DELETE operation allows a client to remove a document
  445        * or Web page from the server.
  446        * 
  447        * <p>This method does not need to be either safe
  448        * or idempotent. Operations requested through
  449        * DELETE can have side effects for which users
  450        * can be held accountable. When using
  451        * this method, it may be useful to save a copy of the
  452        * affected URL in temporary storage.
  453        *
  454        * <p>If the HTTP DELETE request is incorrectly formatted,
  455        * <code>doDelete</code> returns an HTTP "Bad Request"
  456        * message.
  457        *
  458        *
  459        * @param req	the {@link HttpServletRequest} object that
  460        *			contains the request the client made of
  461        *			the servlet
  462        *
  463        *
  464        * @param resp	the {@link HttpServletResponse} object that
  465        *			contains the response the servlet returns
  466        *			to the client				
  467        *
  468        *
  469        * @exception IOException	if an input or output error occurs
  470        *				while the servlet is handling the
  471        *				DELETE request
  472        *
  473        * @exception ServletException	if the request for the
  474        *					DELETE cannot be handled
  475        *
  476        */
  477        
  478       protected void doDelete(HttpServletRequest req,
  479   			    HttpServletResponse resp)
  480   	throws ServletException, IOException
  481       {
  482   	String protocol = req.getProtocol();
  483   	String msg = lStrings.getString("http.method_delete_not_supported");
  484   	if (protocol.endsWith("1.1")) {
  485   	    resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
  486   	} else {
  487   	    resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
  488   	}
  489       }
  490       
  491   
  492   
  493   
  494   
  495       private Method[] getAllDeclaredMethods(Class c) {
  496   
  497           if (c.equals(javax.servlet.http.HttpServlet.class)) {
  498               return null;
  499           }
  500   
  501           Method[] parentMethods = getAllDeclaredMethods(c.getSuperclass());
  502           Method[] thisMethods = c.getDeclaredMethods();
  503   	
  504           if ((parentMethods != null) && (parentMethods.length > 0)) {
  505               Method[] allMethods =
  506                   new Method[parentMethods.length + thisMethods.length];
  507   	    System.arraycopy(parentMethods, 0, allMethods, 0,
  508                                parentMethods.length);
  509   	    System.arraycopy(thisMethods, 0, allMethods, parentMethods.length,
  510                                thisMethods.length);
  511   
  512   	    thisMethods = allMethods;
  513   	}
  514   
  515   	return thisMethods;
  516       }
  517   
  518   
  519   
  520   
  521   
  522   
  523       /**
  524        * Called by the server (via the <code>service</code> method)
  525        * to allow a servlet to handle a OPTIONS request.
  526        *
  527        * The OPTIONS request determines which HTTP methods 
  528        * the server supports and
  529        * returns an appropriate header. For example, if a servlet
  530        * overrides <code>doGet</code>, this method returns the
  531        * following header:
  532        *
  533        * <p><code>Allow: GET, HEAD, TRACE, OPTIONS</code>
  534        *
  535        * <p>There's no need to override this method unless the
  536        * servlet implements new HTTP methods, beyond those 
  537        * implemented by HTTP 1.1.
  538        *
  539        * @param req	the {@link HttpServletRequest} object that
  540        *			contains the request the client made of
  541        *			the servlet
  542        *
  543        *
  544        * @param resp	the {@link HttpServletResponse} object that
  545        *			contains the response the servlet returns
  546        *			to the client				
  547        *
  548        *
  549        * @exception IOException	if an input or output error occurs
  550        *				while the servlet is handling the
  551        *				OPTIONS request
  552        *
  553        * @exception ServletException	if the request for the
  554        *					OPTIONS cannot be handled
  555        *
  556        */
  557            
  558       protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
  559   	throws ServletException, IOException
  560       {
  561   	Method[] methods = getAllDeclaredMethods(this.getClass());
  562   	
  563   	boolean ALLOW_GET = false;
  564   	boolean ALLOW_HEAD = false;
  565   	boolean ALLOW_POST = false;
  566   	boolean ALLOW_PUT = false;
  567   	boolean ALLOW_DELETE = false;
  568   	boolean ALLOW_TRACE = true;
  569   	boolean ALLOW_OPTIONS = true;
  570   	
  571   	for (int i=0; i<methods.length; i++) {
  572   	    Method m = methods[i];
  573   	    
  574   	    if (m.getName().equals("doGet")) {
  575   		ALLOW_GET = true;
  576   		ALLOW_HEAD = true;
  577   	    }
  578   	    if (m.getName().equals("doPost")) 
  579   		ALLOW_POST = true;
  580   	    if (m.getName().equals("doPut"))
  581   		ALLOW_PUT = true;
  582   	    if (m.getName().equals("doDelete"))
  583   		ALLOW_DELETE = true;
  584   	    
  585   	}
  586   	
  587   	String allow = null;
  588   	if (ALLOW_GET)
  589   	    if (allow==null) allow=METHOD_GET;
  590   	if (ALLOW_HEAD)
  591   	    if (allow==null) allow=METHOD_HEAD;
  592   	    else allow += ", " + METHOD_HEAD;
  593   	if (ALLOW_POST)
  594   	    if (allow==null) allow=METHOD_POST;
  595   	    else allow += ", " + METHOD_POST;
  596   	if (ALLOW_PUT)
  597   	    if (allow==null) allow=METHOD_PUT;
  598   	    else allow += ", " + METHOD_PUT;
  599   	if (ALLOW_DELETE)
  600   	    if (allow==null) allow=METHOD_DELETE;
  601   	    else allow += ", " + METHOD_DELETE;
  602   	if (ALLOW_TRACE)
  603   	    if (allow==null) allow=METHOD_TRACE;
  604   	    else allow += ", " + METHOD_TRACE;
  605   	if (ALLOW_OPTIONS)
  606   	    if (allow==null) allow=METHOD_OPTIONS;
  607   	    else allow += ", " + METHOD_OPTIONS;
  608   	
  609   	resp.setHeader("Allow", allow);
  610       }
  611       
  612       
  613       
  614       
  615       /**
  616        * Called by the server (via the <code>service</code> method)
  617        * to allow a servlet to handle a TRACE request.
  618        *
  619        * A TRACE returns the headers sent with the TRACE
  620        * request to the client, so that they can be used in
  621        * debugging. There's no need to override this method. 
  622        *
  623        *
  624        *
  625        * @param req	the {@link HttpServletRequest} object that
  626        *			contains the request the client made of
  627        *			the servlet
  628        *
  629        *
  630        * @param resp	the {@link HttpServletResponse} object that
  631        *			contains the response the servlet returns
  632        *			to the client				
  633        *
  634        *
  635        * @exception IOException	if an input or output error occurs
  636        *				while the servlet is handling the
  637        *				TRACE request
  638        *
  639        * @exception ServletException	if the request for the
  640        *					TRACE cannot be handled
  641        *
  642        */
  643   
  644       protected void doTrace(HttpServletRequest req, HttpServletResponse resp) 
  645   	throws ServletException, IOException
  646       {
  647   	
  648   	int responseLength;
  649   	
  650   	String CRLF = "\r\n";
  651   	String responseString = "TRACE "+ req.getRequestURI()+
  652   	    " " + req.getProtocol();
  653   	
  654   	Enumeration reqHeaderEnum = req.getHeaderNames();
  655   	
  656   	while( reqHeaderEnum.hasMoreElements() ) {
  657   	    String headerName = (String)reqHeaderEnum.nextElement();
  658   	    responseString += CRLF + headerName + ": " +
  659   		req.getHeader(headerName); 
  660   	}
  661   	
  662   	responseString += CRLF;
  663   	
  664   	responseLength = responseString.length();
  665   	
  666   	resp.setContentType("message/http");
  667   	resp.setContentLength(responseLength);
  668   	ServletOutputStream out = resp.getOutputStream();
  669   	out.print(responseString);	
  670       }		
  671   
  672   
  673   
  674   
  675   
  676       /**
  677        *
  678        * Receives standard HTTP requests from the public
  679        * <code>service</code> method and dispatches
  680        * them to the <code>do</code><i>XXX</i> methods defined in 
  681        * this class. This method is an HTTP-specific version of the 
  682        * {@link javax.servlet.Servlet#service} method. There's no
  683        * need to override this method.
  684        *
  685        *
  686        *
  687        * @param req	the {@link HttpServletRequest} object that
  688        *			contains the request the client made of
  689        *			the servlet
  690        *
  691        *
  692        * @param resp	the {@link HttpServletResponse} object that
  693        *			contains the response the servlet returns
  694        *			to the client				
  695        *
  696        *
  697        * @exception IOException	if an input or output error occurs
  698        *				while the servlet is handling the
  699        *				HTTP request
  700        *
  701        * @exception ServletException	if the HTTP request
  702        *					cannot be handled
  703        * 
  704        * @see 				javax.servlet.Servlet#service
  705        *
  706        */
  707   
  708       protected void service(HttpServletRequest req, HttpServletResponse resp)
  709   	throws ServletException, IOException
  710       {
  711   	String method = req.getMethod();
  712   
  713   	if (method.equals(METHOD_GET)) {
  714   	    long lastModified = getLastModified(req);
  715   	    if (lastModified == -1) {
  716   		// servlet doesn't support if-modified-since, no reason
  717   		// to go through further expensive logic
  718   		doGet(req, resp);
  719   	    } else {
  720   		long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
  721   		if (ifModifiedSince < (lastModified / 1000 * 1000)) {
  722   		    // If the servlet mod time is later, call doGet()
  723                       // Round down to the nearest second for a proper compare
  724                       // A ifModifiedSince of -1 will always be less
  725   		    maybeSetLastModified(resp, lastModified);
  726   		    doGet(req, resp);
  727   		} else {
  728   		    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
  729   		}
  730   	    }
  731   
  732   	} else if (method.equals(METHOD_HEAD)) {
  733   	    long lastModified = getLastModified(req);
  734   	    maybeSetLastModified(resp, lastModified);
  735   	    doHead(req, resp);
  736   
  737   	} else if (method.equals(METHOD_POST)) {
  738   	    doPost(req, resp);
  739   	    
  740   	} else if (method.equals(METHOD_PUT)) {
  741   	    doPut(req, resp);	
  742   	    
  743   	} else if (method.equals(METHOD_DELETE)) {
  744   	    doDelete(req, resp);
  745   	    
  746   	} else if (method.equals(METHOD_OPTIONS)) {
  747   	    doOptions(req,resp);
  748   	    
  749   	} else if (method.equals(METHOD_TRACE)) {
  750   	    doTrace(req,resp);
  751   	    
  752   	} else {
  753   	    //
  754   	    // Note that this means NO servlet supports whatever
  755   	    // method was requested, anywhere on this server.
  756   	    //
  757   
  758   	    String errMsg = lStrings.getString("http.method_not_implemented");
  759   	    Object[] errArgs = new Object[1];
  760   	    errArgs[0] = method;
  761   	    errMsg = MessageFormat.format(errMsg, errArgs);
  762   	    
  763   	    resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
  764   	}
  765       }
  766       
  767   
  768   
  769   
  770   
  771       /*
  772        * Sets the Last-Modified entity header field, if it has not
  773        * already been set and if the value is meaningful.  Called before
  774        * doGet, to ensure that headers are set before response data is
  775        * written.  A subclass might have set this header already, so we
  776        * check.
  777        */
  778   
  779       private void maybeSetLastModified(HttpServletResponse resp,
  780   				      long lastModified) {
  781   	if (resp.containsHeader(HEADER_LASTMOD))
  782   	    return;
  783   	if (lastModified >= 0)
  784   	    resp.setDateHeader(HEADER_LASTMOD, lastModified);
  785       }
  786      
  787      
  788      
  789       
  790       /**
  791        *
  792        * Dispatches client requests to the protected
  793        * <code>service</code> method. There's no need to
  794        * override this method.
  795        *
  796        * 
  797        * @param req	the {@link HttpServletRequest} object that
  798        *			contains the request the client made of
  799        *			the servlet
  800        *
  801        *
  802        * @param res	the {@link HttpServletResponse} object that
  803        *			contains the response the servlet returns
  804        *			to the client				
  805        *
  806        *
  807        * @exception IOException	if an input or output error occurs
  808        *				while the servlet is handling the
  809        *				HTTP request
  810        *
  811        * @exception ServletException	if the HTTP request cannot
  812        *					be handled
  813        *
  814        * 
  815        * @see javax.servlet.Servlet#service
  816        *
  817        */
  818   
  819       public void service(ServletRequest req, ServletResponse res)
  820   	throws ServletException, IOException
  821       {
  822   	HttpServletRequest	request;
  823   	HttpServletResponse	response;
  824   	
  825   	try {
  826   	    request = (HttpServletRequest) req;
  827   	    response = (HttpServletResponse) res;
  828   	} catch (ClassCastException e) {
  829   	    throw new ServletException("non-HTTP request or response");
  830   	}
  831   	service(request, response);
  832       }
  833   }
  834   
  835   
  836   
  837   
  838   /*
  839    * A response that includes no body, for use in (dumb) "HEAD" support.
  840    * This just swallows that body, counting the bytes in order to set
  841    * the content length appropriately.  All other methods delegate directly
  842    * to the wrapped HTTP Servlet Response object.
  843    */
  844   // file private
  845   class NoBodyResponse extends HttpServletResponseWrapper {
  846   
  847       private static final ResourceBundle lStrings
  848           = ResourceBundle.getBundle("javax.servlet.http.LocalStrings");
  849   
  850       private NoBodyOutputStream		noBody;
  851       private PrintWriter			writer;
  852       private boolean			didSetContentLength;
  853       private boolean usingOutputStream;
  854   
  855       // file private
  856       NoBodyResponse(HttpServletResponse r) {
  857   	super(r);
  858   	noBody = new NoBodyOutputStream();
  859       }
  860   
  861       // file private
  862       void setContentLength() {
  863           if (!didSetContentLength) {
  864               if (writer != null) {
  865                   writer.flush();
  866               }
  867               setContentLength(noBody.getContentLength());
  868           }
  869       }
  870   
  871       public void setContentLength(int len) {
  872           super.setContentLength(len);
  873           didSetContentLength = true;
  874       }
  875   
  876       public ServletOutputStream getOutputStream() throws IOException {
  877   
  878           if (writer != null) {
  879               throw new IllegalArgumentException(
  880                   lStrings.getString("err.ise.getOutputStream"));
  881           }
  882           usingOutputStream = true;
  883   
  884           return noBody;
  885       }
  886   
  887       public PrintWriter getWriter() throws UnsupportedEncodingException {
  888   
  889           if (usingOutputStream) {
  890               throw new IllegalArgumentException(
  891                   lStrings.getString("err.ise.getWriter"));
  892           }
  893   
  894           if (writer == null) {
  895               OutputStreamWriter w = new OutputStreamWriter(
  896                   noBody, getCharacterEncoding());
  897               writer = new PrintWriter(w);
  898           }
  899   
  900           return writer;
  901       }
  902   }
  903   
  904   
  905   /*
  906    * Servlet output stream that gobbles up all its data.
  907    */
  908    
  909   // file private
  910   class NoBodyOutputStream extends ServletOutputStream {
  911   
  912       private static final String LSTRING_FILE =
  913   	"javax.servlet.http.LocalStrings";
  914       private static ResourceBundle lStrings =
  915   	ResourceBundle.getBundle(LSTRING_FILE);
  916   
  917       private int		contentLength = 0;
  918   
  919       // file private
  920       NoBodyOutputStream() {}
  921   
  922       // file private
  923       int getContentLength() {
  924   	return contentLength;
  925       }
  926   
  927       public void write(int b) {
  928   	contentLength++;
  929       }
  930   
  931       public void write(byte buf[], int offset, int len)
  932   	throws IOException
  933       {
  934   	if (len >= 0) {
  935   	    contentLength += len;
  936   	} else {
  937               // This should have thrown an IllegalArgumentException, but
  938               // changing this would break backwards compatibility
  939               throw new IOException(lStrings.getString("err.io.negativelength"));
  940   	}
  941       }
  942   }

Save This Page
Home » glassfish-v2ur2-b04-src » javax » servlet » http » [javadoc | source]