0001 /*
0002 * Copyright 2004 The Apache Software Foundation
0003 *
0004 * Licensed under the Apache License, Version 2.0 (the "License");
0005 * you may not use this file except in compliance with the License.
0006 * You may obtain a copy of the License at
0007 *
0008 * http://www.apache.org/licenses/LICENSE-2.0
0009 *
0010 * Unless required by applicable law or agreed to in writing, software
0011 * distributed under the License is distributed on an "AS IS" BASIS,
0012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013 * See the License for the specific language governing permissions and
0014 * limitations under the License.
0015 */
0016 package javax.servlet.http;
0017
0018 import java.io.IOException;
0019 import java.io.PrintWriter;
0020 import java.io.OutputStreamWriter;
0021 import java.io.UnsupportedEncodingException;
0022 import java.lang.reflect.Method;
0023 import java.text.MessageFormat;
0024 import java.util.Enumeration;
0025 import java.util.Locale;
0026 import java.util.ResourceBundle;
0027
0028 import javax.servlet.GenericServlet;
0029 import javax.servlet.ServletException;
0030 import javax.servlet.ServletOutputStream;
0031 import javax.servlet.ServletRequest;
0032 import javax.servlet.ServletResponse;
0033
0034 /**
0035 *
0036 * Provides an abstract class to be subclassed to create
0037 * an HTTP servlet suitable for a Web site. A subclass of
0038 * <code>HttpServlet</code> must override at least
0039 * one method, usually one of these:
0040 *
0041 * <ul>
0042 * <li> <code>doGet</code>, if the servlet supports HTTP GET requests
0043 * <li> <code>doPost</code>, for HTTP POST requests
0044 * <li> <code>doPut</code>, for HTTP PUT requests
0045 * <li> <code>doDelete</code>, for HTTP DELETE requests
0046 * <li> <code>init</code> and <code>destroy</code>,
0047 * to manage resources that are held for the life of the servlet
0048 * <li> <code>getServletInfo</code>, which the servlet uses to
0049 * provide information about itself
0050 * </ul>
0051 *
0052 * <p>There's almost no reason to override the <code>service</code>
0053 * method. <code>service</code> handles standard HTTP
0054 * requests by dispatching them to the handler methods
0055 * for each HTTP request type (the <code>do</code><i>XXX</i>
0056 * methods listed above).
0057 *
0058 * <p>Likewise, there's almost no reason to override the
0059 * <code>doOptions</code> and <code>doTrace</code> methods.
0060 *
0061 * <p>Servlets typically run on multithreaded servers,
0062 * so be aware that a servlet must handle concurrent
0063 * requests and be careful to synchronize access to shared resources.
0064 * Shared resources include in-memory data such as
0065 * instance or class variables and external objects
0066 * such as files, database connections, and network
0067 * connections.
0068 * See the
0069 * <a href="http://java.sun.com/Series/Tutorial/java/threads/multithreaded.html">
0070 * Java Tutorial on Multithreaded Programming</a> for more
0071 * information on handling multiple threads in a Java program.
0072 *
0073 * @author Various
0074 * @version $Version$
0075 *
0076 */
0077
0078 public abstract class HttpServlet extends GenericServlet implements
0079 java.io.Serializable {
0080 private static final String METHOD_DELETE = "DELETE";
0081 private static final String METHOD_HEAD = "HEAD";
0082 private static final String METHOD_GET = "GET";
0083 private static final String METHOD_OPTIONS = "OPTIONS";
0084 private static final String METHOD_POST = "POST";
0085 private static final String METHOD_PUT = "PUT";
0086 private static final String METHOD_TRACE = "TRACE";
0087
0088 private static final String HEADER_IFMODSINCE = "If-Modified-Since";
0089 private static final String HEADER_LASTMOD = "Last-Modified";
0090
0091 private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings";
0092 private static ResourceBundle lStrings = ResourceBundle
0093 .getBundle(LSTRING_FILE);
0094
0095 /**
0096 * Does nothing, because this is an abstract class.
0097 *
0098 */
0099
0100 public HttpServlet() {
0101 }
0102
0103 /**
0104 *
0105 * Called by the server (via the <code>service</code> method) to
0106 * allow a servlet to handle a GET request.
0107 *
0108 * <p>Overriding this method to support a GET request also
0109 * automatically supports an HTTP HEAD request. A HEAD
0110 * request is a GET request that returns no body in the
0111 * response, only the request header fields.
0112 *
0113 * <p>When overriding this method, read the request data,
0114 * write the response headers, get the response's writer or
0115 * output stream object, and finally, write the response data.
0116 * It's best to include content type and encoding. When using
0117 * a <code>PrintWriter</code> object to return the response,
0118 * set the content type before accessing the
0119 * <code>PrintWriter</code> object.
0120 *
0121 * <p>The servlet container must write the headers before
0122 * committing the response, because in HTTP the headers must be sent
0123 * before the response body.
0124 *
0125 * <p>Where possible, set the Content-Length header (with the
0126 * {@link javax.servlet.ServletResponse#setContentLength} method),
0127 * to allow the servlet container to use a persistent connection
0128 * to return its response to the client, improving performance.
0129 * The content length is automatically set if the entire response fits
0130 * inside the response buffer.
0131 *
0132 * <p>When using HTTP 1.1 chunked encoding (which means that the response
0133 * has a Transfer-Encoding header), do not set the Content-Length header.
0134 *
0135 * <p>The GET method should be safe, that is, without
0136 * any side effects for which users are held responsible.
0137 * For example, most form queries have no side effects.
0138 * If a client request is intended to change stored data,
0139 * the request should use some other HTTP method.
0140 *
0141 * <p>The GET method should also be idempotent, meaning
0142 * that it can be safely repeated. Sometimes making a
0143 * method safe also makes it idempotent. For example,
0144 * repeating queries is both safe and idempotent, but
0145 * buying a product online or modifying data is neither
0146 * safe nor idempotent.
0147 *
0148 * <p>If the request is incorrectly formatted, <code>doGet</code>
0149 * returns an HTTP "Bad Request" message.
0150 *
0151 *
0152 * @param req an {@link HttpServletRequest} object that
0153 * contains the request the client has made
0154 * of the servlet
0155 *
0156 * @param resp an {@link HttpServletResponse} object that
0157 * contains the response the servlet sends
0158 * to the client
0159 *
0160 * @exception IOException if an input or output error is
0161 * detected when the servlet handles
0162 * the GET request
0163 *
0164 * @exception ServletException if the request for the GET
0165 * could not be handled
0166 *
0167 *
0168 * @see javax.servlet.ServletResponse#setContentType
0169 *
0170 */
0171
0172 protected void doGet(HttpServletRequest req,
0173 HttpServletResponse resp) throws ServletException,
0174 IOException {
0175 String protocol = req.getProtocol();
0176 String msg = lStrings
0177 .getString("http.method_get_not_supported");
0178 if (protocol.endsWith("1.1")) {
0179 resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED,
0180 msg);
0181 } else {
0182 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
0183 }
0184 }
0185
0186 /**
0187 *
0188 * Returns the time the <code>HttpServletRequest</code>
0189 * object was last modified,
0190 * in milliseconds since midnight January 1, 1970 GMT.
0191 * If the time is unknown, this method returns a negative
0192 * number (the default).
0193 *
0194 * <p>Servlets that support HTTP GET requests and can quickly determine
0195 * their last modification time should override this method.
0196 * This makes browser and proxy caches work more effectively,
0197 * reducing the load on server and network resources.
0198 *
0199 *
0200 * @param req the <code>HttpServletRequest</code>
0201 * object that is sent to the servlet
0202 *
0203 * @return a <code>long</code> integer specifying
0204 * the time the <code>HttpServletRequest</code>
0205 * object was last modified, in milliseconds
0206 * since midnight, January 1, 1970 GMT, or
0207 * -1 if the time is not known
0208 *
0209 */
0210
0211 protected long getLastModified(HttpServletRequest req) {
0212 return -1;
0213 }
0214
0215 /**
0216 *
0217 *
0218 * <p>Receives an HTTP HEAD request from the protected
0219 * <code>service</code> method and handles the
0220 * request.
0221 * The client sends a HEAD request when it wants
0222 * to see only the headers of a response, such as
0223 * Content-Type or Content-Length. The HTTP HEAD
0224 * method counts the output bytes in the response
0225 * to set the Content-Length header accurately.
0226 *
0227 * <p>If you override this method, you can avoid computing
0228 * the response body and just set the response headers
0229 * directly to improve performance. Make sure that the
0230 * <code>doHead</code> method you write is both safe
0231 * and idempotent (that is, protects itself from being
0232 * called multiple times for one HTTP HEAD request).
0233 *
0234 * <p>If the HTTP HEAD request is incorrectly formatted,
0235 * <code>doHead</code> returns an HTTP "Bad Request"
0236 * message.
0237 *
0238 *
0239 * @param req the request object that is passed
0240 * to the servlet
0241 *
0242 * @param resp the response object that the servlet
0243 * uses to return the headers to the clien
0244 *
0245 * @exception IOException if an input or output error occurs
0246 *
0247 * @exception ServletException if the request for the HEAD
0248 * could not be handled
0249 */
0250
0251 protected void doHead(HttpServletRequest req,
0252 HttpServletResponse resp) throws ServletException,
0253 IOException {
0254 NoBodyResponse response = new NoBodyResponse(resp);
0255
0256 doGet(req, response);
0257 response.setContentLength();
0258 }
0259
0260 /**
0261 *
0262 * Called by the server (via the <code>service</code> method)
0263 * to allow a servlet to handle a POST request.
0264 *
0265 * The HTTP POST method allows the client to send
0266 * data of unlimited length to the Web server a single time
0267 * and is useful when posting information such as
0268 * credit card numbers.
0269 *
0270 * <p>When overriding this method, read the request data,
0271 * write the response headers, get the response's writer or output
0272 * stream object, and finally, write the response data. It's best
0273 * to include content type and encoding. When using a
0274 * <code>PrintWriter</code> object to return the response, set the
0275 * content type before accessing the <code>PrintWriter</code> object.
0276 *
0277 * <p>The servlet container must write the headers before committing the
0278 * response, because in HTTP the headers must be sent before the
0279 * response body.
0280 *
0281 * <p>Where possible, set the Content-Length header (with the
0282 * {@link javax.servlet.ServletResponse#setContentLength} method),
0283 * to allow the servlet container to use a persistent connection
0284 * to return its response to the client, improving performance.
0285 * The content length is automatically set if the entire response fits
0286 * inside the response buffer.
0287 *
0288 * <p>When using HTTP 1.1 chunked encoding (which means that the response
0289 * has a Transfer-Encoding header), do not set the Content-Length header.
0290 *
0291 * <p>This method does not need to be either safe or idempotent.
0292 * Operations requested through POST can have side effects for
0293 * which the user can be held accountable, for example,
0294 * updating stored data or buying items online.
0295 *
0296 * <p>If the HTTP POST request is incorrectly formatted,
0297 * <code>doPost</code> returns an HTTP "Bad Request" message.
0298 *
0299 *
0300 * @param req an {@link HttpServletRequest} object that
0301 * contains the request the client has made
0302 * of the servlet
0303 *
0304 * @param resp an {@link HttpServletResponse} object that
0305 * contains the response the servlet sends
0306 * to the client
0307 *
0308 * @exception IOException if an input or output error is
0309 * detected when the servlet handles
0310 * the request
0311 *
0312 * @exception ServletException if the request for the POST
0313 * could not be handled
0314 *
0315 *
0316 * @see javax.servlet.ServletOutputStream
0317 * @see javax.servlet.ServletResponse#setContentType
0318 *
0319 *
0320 */
0321
0322 protected void doPost(HttpServletRequest req,
0323 HttpServletResponse resp) throws ServletException,
0324 IOException {
0325 String protocol = req.getProtocol();
0326 String msg = lStrings
0327 .getString("http.method_post_not_supported");
0328 if (protocol.endsWith("1.1")) {
0329 resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED,
0330 msg);
0331 } else {
0332 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
0333 }
0334 }
0335
0336 /**
0337 * Called by the server (via the <code>service</code> method)
0338 * to allow a servlet to handle a PUT request.
0339 *
0340 * The PUT operation allows a client to
0341 * place a file on the server and is similar to
0342 * sending a file by FTP.
0343 *
0344 * <p>When overriding this method, leave intact
0345 * any content headers sent with the request (including
0346 * Content-Length, Content-Type, Content-Transfer-Encoding,
0347 * Content-Encoding, Content-Base, Content-Language, Content-Location,
0348 * Content-MD5, and Content-Range). If your method cannot
0349 * handle a content header, it must issue an error message
0350 * (HTTP 501 - Not Implemented) and discard the request.
0351 * For more information on HTTP 1.1, see RFC 2616
0352 * <a href="http://www.ietf.org/rfc/rfc2616.txt"></a>.
0353 *
0354 * <p>This method does not need to be either safe or idempotent.
0355 * Operations that <code>doPut</code> performs can have side
0356 * effects for which the user can be held accountable. When using
0357 * this method, it may be useful to save a copy of the
0358 * affected URL in temporary storage.
0359 *
0360 * <p>If the HTTP PUT request is incorrectly formatted,
0361 * <code>doPut</code> returns an HTTP "Bad Request" message.
0362 *
0363 *
0364 * @param req the {@link HttpServletRequest} object that
0365 * contains the request the client made of
0366 * the servlet
0367 *
0368 * @param resp the {@link HttpServletResponse} object that
0369 * contains the response the servlet returns
0370 * to the client
0371 *
0372 * @exception IOException if an input or output error occurs
0373 * while the servlet is handling the
0374 * PUT request
0375 *
0376 * @exception ServletException if the request for the PUT
0377 * cannot be handled
0378 *
0379 */
0380
0381 protected void doPut(HttpServletRequest req,
0382 HttpServletResponse resp) throws ServletException,
0383 IOException {
0384 String protocol = req.getProtocol();
0385 String msg = lStrings
0386 .getString("http.method_put_not_supported");
0387 if (protocol.endsWith("1.1")) {
0388 resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED,
0389 msg);
0390 } else {
0391 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
0392 }
0393 }
0394
0395 /**
0396 *
0397 * Called by the server (via the <code>service</code> method)
0398 * to allow a servlet to handle a DELETE request.
0399 *
0400 * The DELETE operation allows a client to remove a document
0401 * or Web page from the server.
0402 *
0403 * <p>This method does not need to be either safe
0404 * or idempotent. Operations requested through
0405 * DELETE can have side effects for which users
0406 * can be held accountable. When using
0407 * this method, it may be useful to save a copy of the
0408 * affected URL in temporary storage.
0409 *
0410 * <p>If the HTTP DELETE request is incorrectly formatted,
0411 * <code>doDelete</code> returns an HTTP "Bad Request"
0412 * message.
0413 *
0414 *
0415 * @param req the {@link HttpServletRequest} object that
0416 * contains the request the client made of
0417 * the servlet
0418 *
0419 *
0420 * @param resp the {@link HttpServletResponse} object that
0421 * contains the response the servlet returns
0422 * to the client
0423 *
0424 *
0425 * @exception IOException if an input or output error occurs
0426 * while the servlet is handling the
0427 * DELETE request
0428 *
0429 * @exception ServletException if the request for the
0430 * DELETE cannot be handled
0431 *
0432 */
0433
0434 protected void doDelete(HttpServletRequest req,
0435 HttpServletResponse resp) throws ServletException,
0436 IOException {
0437 String protocol = req.getProtocol();
0438 String msg = lStrings
0439 .getString("http.method_delete_not_supported");
0440 if (protocol.endsWith("1.1")) {
0441 resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED,
0442 msg);
0443 } else {
0444 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
0445 }
0446 }
0447
0448 private static Method[] getAllDeclaredMethods(Class c) {
0449
0450 if (c.equals(javax.servlet.http.HttpServlet.class)) {
0451 return null;
0452 }
0453
0454 Method[] parentMethods = getAllDeclaredMethods(c
0455 .getSuperclass());
0456 Method[] this Methods = c.getDeclaredMethods();
0457
0458 if ((parentMethods != null) && (parentMethods.length > 0)) {
0459 Method[] allMethods = new Method[parentMethods.length
0460 + this Methods.length];
0461 System.arraycopy(parentMethods, 0, allMethods, 0,
0462 parentMethods.length);
0463 System.arraycopy(this Methods, 0, allMethods,
0464 parentMethods.length, this Methods.length);
0465
0466 this Methods = allMethods;
0467 }
0468
0469 return this Methods;
0470 }
0471
0472 /**
0473 * Called by the server (via the <code>service</code> method)
0474 * to allow a servlet to handle a OPTIONS request.
0475 *
0476 * The OPTIONS request determines which HTTP methods
0477 * the server supports and
0478 * returns an appropriate header. For example, if a servlet
0479 * overrides <code>doGet</code>, this method returns the
0480 * following header:
0481 *
0482 * <p><code>Allow: GET, HEAD, TRACE, OPTIONS</code>
0483 *
0484 * <p>There's no need to override this method unless the
0485 * servlet implements new HTTP methods, beyond those
0486 * implemented by HTTP 1.1.
0487 *
0488 * @param req the {@link HttpServletRequest} object that
0489 * contains the request the client made of
0490 * the servlet
0491 *
0492 *
0493 * @param resp the {@link HttpServletResponse} object that
0494 * contains the response the servlet returns
0495 * to the client
0496 *
0497 *
0498 * @exception IOException if an input or output error occurs
0499 * while the servlet is handling the
0500 * OPTIONS request
0501 *
0502 * @exception ServletException if the request for the
0503 * OPTIONS cannot be handled
0504 *
0505 */
0506
0507 protected void doOptions(HttpServletRequest req,
0508 HttpServletResponse resp) throws ServletException,
0509 IOException {
0510 Method[] methods = getAllDeclaredMethods(this .getClass());
0511
0512 boolean ALLOW_GET = false;
0513 boolean ALLOW_HEAD = false;
0514 boolean ALLOW_POST = false;
0515 boolean ALLOW_PUT = false;
0516 boolean ALLOW_DELETE = false;
0517 boolean ALLOW_TRACE = true;
0518 boolean ALLOW_OPTIONS = true;
0519
0520 for (int i = 0; i < methods.length; i++) {
0521 Method m = methods[i];
0522
0523 if (m.getName().equals("doGet")) {
0524 ALLOW_GET = true;
0525 ALLOW_HEAD = true;
0526 }
0527 if (m.getName().equals("doPost"))
0528 ALLOW_POST = true;
0529 if (m.getName().equals("doPut"))
0530 ALLOW_PUT = true;
0531 if (m.getName().equals("doDelete"))
0532 ALLOW_DELETE = true;
0533
0534 }
0535
0536 String allow = null;
0537 if (ALLOW_GET)
0538 if (allow == null)
0539 allow = METHOD_GET;
0540 if (ALLOW_HEAD)
0541 if (allow == null)
0542 allow = METHOD_HEAD;
0543 else
0544 allow += ", " + METHOD_HEAD;
0545 if (ALLOW_POST)
0546 if (allow == null)
0547 allow = METHOD_POST;
0548 else
0549 allow += ", " + METHOD_POST;
0550 if (ALLOW_PUT)
0551 if (allow == null)
0552 allow = METHOD_PUT;
0553 else
0554 allow += ", " + METHOD_PUT;
0555 if (ALLOW_DELETE)
0556 if (allow == null)
0557 allow = METHOD_DELETE;
0558 else
0559 allow += ", " + METHOD_DELETE;
0560 if (ALLOW_TRACE)
0561 if (allow == null)
0562 allow = METHOD_TRACE;
0563 else
0564 allow += ", " + METHOD_TRACE;
0565 if (ALLOW_OPTIONS)
0566 if (allow == null)
0567 allow = METHOD_OPTIONS;
0568 else
0569 allow += ", " + METHOD_OPTIONS;
0570
0571 resp.setHeader("Allow", allow);
0572 }
0573
0574 /**
0575 * Called by the server (via the <code>service</code> method)
0576 * to allow a servlet to handle a TRACE request.
0577 *
0578 * A TRACE returns the headers sent with the TRACE
0579 * request to the client, so that they can be used in
0580 * debugging. There's no need to override this method.
0581 *
0582 *
0583 *
0584 * @param req the {@link HttpServletRequest} object that
0585 * contains the request the client made of
0586 * the servlet
0587 *
0588 *
0589 * @param resp the {@link HttpServletResponse} object that
0590 * contains the response the servlet returns
0591 * to the client
0592 *
0593 *
0594 * @exception IOException if an input or output error occurs
0595 * while the servlet is handling the
0596 * TRACE request
0597 *
0598 * @exception ServletException if the request for the
0599 * TRACE cannot be handled
0600 *
0601 */
0602
0603 protected void doTrace(HttpServletRequest req,
0604 HttpServletResponse resp) throws ServletException,
0605 IOException {
0606
0607 int responseLength;
0608
0609 String CRLF = "\r\n";
0610 String responseString = "TRACE " + req.getRequestURI() + " "
0611 + req.getProtocol();
0612
0613 Enumeration reqHeaderEnum = req.getHeaderNames();
0614
0615 while (reqHeaderEnum.hasMoreElements()) {
0616 String headerName = (String) reqHeaderEnum.nextElement();
0617 responseString += CRLF + headerName + ": "
0618 + req.getHeader(headerName);
0619 }
0620
0621 responseString += CRLF;
0622
0623 responseLength = responseString.length();
0624
0625 resp.setContentType("message/http");
0626 resp.setContentLength(responseLength);
0627 ServletOutputStream out = resp.getOutputStream();
0628 out.print(responseString);
0629 out.close();
0630 return;
0631 }
0632
0633 /**
0634 *
0635 * Receives standard HTTP requests from the public
0636 * <code>service</code> method and dispatches
0637 * them to the <code>do</code><i>XXX</i> methods defined in
0638 * this class. This method is an HTTP-specific version of the
0639 * {@link javax.servlet.Servlet#service} method. There's no
0640 * need to override this method.
0641 *
0642 *
0643 *
0644 * @param req the {@link HttpServletRequest} object that
0645 * contains the request the client made of
0646 * the servlet
0647 *
0648 *
0649 * @param resp the {@link HttpServletResponse} object that
0650 * contains the response the servlet returns
0651 * to the client
0652 *
0653 *
0654 * @exception IOException if an input or output error occurs
0655 * while the servlet is handling the
0656 * HTTP request
0657 *
0658 * @exception ServletException if the HTTP request
0659 * cannot be handled
0660 *
0661 * @see javax.servlet.Servlet#service
0662 *
0663 */
0664
0665 protected void service(HttpServletRequest req,
0666 HttpServletResponse resp) throws ServletException,
0667 IOException {
0668 String method = req.getMethod();
0669
0670 if (method.equals(METHOD_GET)) {
0671 long lastModified = getLastModified(req);
0672 if (lastModified == -1) {
0673 // servlet doesn't support if-modified-since, no reason
0674 // to go through further expensive logic
0675 doGet(req, resp);
0676 } else {
0677 long ifModifiedSince = req
0678 .getDateHeader(HEADER_IFMODSINCE);
0679 if (ifModifiedSince < (lastModified / 1000 * 1000)) {
0680 // If the servlet mod time is later, call doGet()
0681 // Round down to the nearest second for a proper compare
0682 // A ifModifiedSince of -1 will always be less
0683 maybeSetLastModified(resp, lastModified);
0684 doGet(req, resp);
0685 } else {
0686 resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
0687 }
0688 }
0689
0690 } else if (method.equals(METHOD_HEAD)) {
0691 long lastModified = getLastModified(req);
0692 maybeSetLastModified(resp, lastModified);
0693 doHead(req, resp);
0694
0695 } else if (method.equals(METHOD_POST)) {
0696 doPost(req, resp);
0697
0698 } else if (method.equals(METHOD_PUT)) {
0699 doPut(req, resp);
0700
0701 } else if (method.equals(METHOD_DELETE)) {
0702 doDelete(req, resp);
0703
0704 } else if (method.equals(METHOD_OPTIONS)) {
0705 doOptions(req, resp);
0706
0707 } else if (method.equals(METHOD_TRACE)) {
0708 doTrace(req, resp);
0709
0710 } else {
0711 //
0712 // Note that this means NO servlet supports whatever
0713 // method was requested, anywhere on this server.
0714 //
0715
0716 String errMsg = lStrings
0717 .getString("http.method_not_implemented");
0718 Object[] errArgs = new Object[1];
0719 errArgs[0] = method;
0720 errMsg = MessageFormat.format(errMsg, errArgs);
0721
0722 resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED,
0723 errMsg);
0724 }
0725 }
0726
0727 /*
0728 * Sets the Last-Modified entity header field, if it has not
0729 * already been set and if the value is meaningful. Called before
0730 * doGet, to ensure that headers are set before response data is
0731 * written. A subclass might have set this header already, so we
0732 * check.
0733 */
0734
0735 private void maybeSetLastModified(HttpServletResponse resp,
0736 long lastModified) {
0737 if (resp.containsHeader(HEADER_LASTMOD))
0738 return;
0739 if (lastModified >= 0)
0740 resp.setDateHeader(HEADER_LASTMOD, lastModified);
0741 }
0742
0743 /**
0744 *
0745 * Dispatches client requests to the protected
0746 * <code>service</code> method. There's no need to
0747 * override this method.
0748 *
0749 *
0750 * @param req the {@link HttpServletRequest} object that
0751 * contains the request the client made of
0752 * the servlet
0753 *
0754 *
0755 * @param res the {@link HttpServletResponse} object that
0756 * contains the response the servlet returns
0757 * to the client
0758 *
0759 *
0760 * @exception IOException if an input or output error occurs
0761 * while the servlet is handling the
0762 * HTTP request
0763 *
0764 * @exception ServletException if the HTTP request cannot
0765 * be handled
0766 *
0767 *
0768 * @see javax.servlet.Servlet#service
0769 *
0770 */
0771
0772 public void service(ServletRequest req, ServletResponse res)
0773 throws ServletException, IOException {
0774 HttpServletRequest request;
0775 HttpServletResponse response;
0776
0777 try {
0778 request = (HttpServletRequest) req;
0779 response = (HttpServletResponse) res;
0780 } catch (ClassCastException e) {
0781 throw new ServletException("non-HTTP request or response");
0782 }
0783 service(request, response);
0784 }
0785 }
0786
0787 /*
0788 * A response that includes no body, for use in (dumb) "HEAD" support.
0789 * This just swallows that body, counting the bytes in order to set
0790 * the content length appropriately. All other methods delegate directly
0791 * to the HTTP Servlet Response object used to construct this one.
0792 */
0793 // file private
0794 class NoBodyResponse implements HttpServletResponse {
0795 private HttpServletResponse resp;
0796 private NoBodyOutputStream noBody;
0797 private PrintWriter writer;
0798 private boolean didSetContentLength;
0799
0800 // file private
0801 NoBodyResponse(HttpServletResponse r) {
0802 resp = r;
0803 noBody = new NoBodyOutputStream();
0804 }
0805
0806 // file private
0807 void setContentLength() {
0808 if (!didSetContentLength)
0809 resp.setContentLength(noBody.getContentLength());
0810 }
0811
0812 // SERVLET RESPONSE interface methods
0813
0814 public void setContentLength(int len) {
0815 resp.setContentLength(len);
0816 didSetContentLength = true;
0817 }
0818
0819 public void setCharacterEncoding(String charset) {
0820 resp.setCharacterEncoding(charset);
0821 }
0822
0823 public void setContentType(String type) {
0824 resp.setContentType(type);
0825 }
0826
0827 public String getContentType() {
0828 return resp.getContentType();
0829 }
0830
0831 public ServletOutputStream getOutputStream() throws IOException {
0832 return noBody;
0833 }
0834
0835 public String getCharacterEncoding() {
0836 return resp.getCharacterEncoding();
0837 }
0838
0839 public PrintWriter getWriter() throws UnsupportedEncodingException {
0840 if (writer == null) {
0841 OutputStreamWriter w;
0842
0843 w = new OutputStreamWriter(noBody, getCharacterEncoding());
0844 writer = new PrintWriter(w);
0845 }
0846 return writer;
0847 }
0848
0849 public void setBufferSize(int size) throws IllegalStateException {
0850 resp.setBufferSize(size);
0851 }
0852
0853 public int getBufferSize() {
0854 return resp.getBufferSize();
0855 }
0856
0857 public void reset() throws IllegalStateException {
0858 resp.reset();
0859 }
0860
0861 public void resetBuffer() throws IllegalStateException {
0862 resp.resetBuffer();
0863 }
0864
0865 public boolean isCommitted() {
0866 return resp.isCommitted();
0867 }
0868
0869 public void flushBuffer() throws IOException {
0870 resp.flushBuffer();
0871 }
0872
0873 public void setLocale(Locale loc) {
0874 resp.setLocale(loc);
0875 }
0876
0877 public Locale getLocale() {
0878 return resp.getLocale();
0879 }
0880
0881 // HTTP SERVLET RESPONSE interface methods
0882
0883 public void addCookie(Cookie cookie) {
0884 resp.addCookie(cookie);
0885 }
0886
0887 public boolean containsHeader(String name) {
0888 return resp.containsHeader(name);
0889 }
0890
0891 /** @deprecated */
0892 public void setStatus(int sc, String sm) {
0893 resp.setStatus(sc, sm);
0894 }
0895
0896 public void setStatus(int sc) {
0897 resp.setStatus(sc);
0898 }
0899
0900 public void setHeader(String name, String value) {
0901 resp.setHeader(name, value);
0902 }
0903
0904 public void setIntHeader(String name, int value) {
0905 resp.setIntHeader(name, value);
0906 }
0907
0908 public void setDateHeader(String name, long date) {
0909 resp.setDateHeader(name, date);
0910 }
0911
0912 public void sendError(int sc, String msg) throws IOException {
0913 resp.sendError(sc, msg);
0914 }
0915
0916 public void sendError(int sc) throws IOException {
0917 resp.sendError(sc);
0918 }
0919
0920 public void sendRedirect(String location) throws IOException {
0921 resp.sendRedirect(location);
0922 }
0923
0924 public String encodeURL(String url) {
0925 return resp.encodeURL(url);
0926 }
0927
0928 public String encodeRedirectURL(String url) {
0929 return resp.encodeRedirectURL(url);
0930 }
0931
0932 public void addHeader(String name, String value) {
0933 resp.addHeader(name, value);
0934 }
0935
0936 public void addDateHeader(String name, long value) {
0937 resp.addDateHeader(name, value);
0938 }
0939
0940 public void addIntHeader(String name, int value) {
0941 resp.addIntHeader(name, value);
0942 }
0943
0944 /**
0945 * @deprecated As of Version 2.1, replaced by
0946 * {@link HttpServletResponse#encodeURL}.
0947 *
0948 */
0949
0950 public String encodeUrl(String url) {
0951 return this .encodeURL(url);
0952 }
0953
0954 /**
0955 * @deprecated As of Version 2.1, replaced by
0956 * {@link HttpServletResponse#encodeRedirectURL}.
0957 *
0958 */
0959
0960 public String encodeRedirectUrl(String url) {
0961 return this .encodeRedirectURL(url);
0962 }
0963
0964 }
0965
0966 /*
0967 * Servlet output stream that gobbles up all its data.
0968 */
0969
0970 // file private
0971 class NoBodyOutputStream extends ServletOutputStream {
0972
0973 private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings";
0974 private static ResourceBundle lStrings = ResourceBundle
0975 .getBundle(LSTRING_FILE);
0976
0977 private int contentLength = 0;
0978
0979 // file private
0980 NoBodyOutputStream() {
0981 }
0982
0983 // file private
0984 int getContentLength() {
0985 return contentLength;
0986 }
0987
0988 public void write(int b) {
0989 contentLength++;
0990 }
0991
0992 public void write(byte buf[], int offset, int len)
0993 throws IOException {
0994 if (len >= 0) {
0995 contentLength += len;
0996 } else {
0997 // XXX
0998 // isn't this really an IllegalArgumentException?
0999
1000 String msg = lStrings.getString("err.io.negativelength");
1001 throw new IOException("negative length");
1002 }
1003 }
1004 }
|