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

Save This Page
Home » apache-tomcat-6.0.26-src » javax » servlet » http » [javadoc | source]