HttpServlet.java
上传用户:sxlinghang
上传日期:2022-07-20
资源大小:1405k
文件大小:33k
源码类别:

数据库编程

开发平台:

Java

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