HttpServlet继承于GenericServlet,,专门用于处理Http的请求:
方法一: HttpServlet复写了GenericServlet的service(ServletRequest rq,ServletResponse rp)并同时提供了了一个service(HttpServletRequest req,HttpServletRsponse rep),,,在service(ServletRequest rq,ServletResponse rp)方法内部调用了service(HttpServletRequest req,HttpServletRsponse rep),这样在服务器自动执行service(ServletRequest rq,ServletResponse rp)该生命周期方法时,也会同时调用到service(HttpServletRequest req,HttpServletRsponse rep)方法,而我们只需要子类中复写service(HttpServletRequest req,HttpServletRsponse rep)方法,在其中编写处理请求的代码,,[注]:在子类复写service(HttpServletRequest req,HttpServletRsponse rep)方法时,不能再该方法内写super.service(req,rep)调用该方法会输出一个错误信息.
方法二: HttpServlet复写了GenericServlet的service(ServletRequest rq,ServletResponse rp)并同时提供了了一个service(HttpServletRequest req,HttpServletRsponse rep),,,在service(ServletRequest rq,ServletResponse rp)方法内部调用了service(HttpServletRequest req,HttpServletRsponse rep),这样在服务器自动执行service(ServletRequest rq,ServletResponse rp)该生命周期方法时,也会同时调用到service(HttpServletRequest req,HttpServletRsponse rep)方法,,同时在service(HttpServletRequest req,HttpServletRsponse rep)方法内,还对请求类型进行了判断,如果根据不同的请求类型,在该方法内有调用了不同的方法对不同的请求类型进行处理,,,如针对get的doGet()方法,针对post的doPost()方法,,,,此时我们可以仅仅只在子类中分别复写针对不同请求类型的处理方法,如doGet()和doPost()等方法,,,这样即可在服务处理请求时根据service(ServletRequest rq,ServletResponse rp)------>service(HttpServletRequest req,HttpServletRsponse rep)的顺序自动找到相应的doGet()或doPost()方法进行对应的请求类型的处理...[注]:在子类中复写doGet()和doPost()等方法时不能在其方法内写super.doGet()或super.doPost()等方法,,,同样的,该调用同样是输出一个错误信息.
HttpServlet源代码
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.OutputStreamWriter; 21 import java.io.PrintWriter; 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>Method</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 */ 75 public abstract class HttpServlet extends GenericServlet { 76 77 private static final long serialVersionUID = 1L; 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 // NOOP 101 } 102 103 104 /** 105 * Called by the server (via the <code>service</code> method) to 106 * allow a servlet to handle a GET request. 107 * 108 * <p>Overriding this method to support a GET request also 109 * automatically supports an HTTP HEAD request. A HEAD 110 * request is a GET request that returns no body in the 111 * response, only the request header fields. 112 * 113 * <p>When overriding this method, read the request data, 114 * write the response headers, get the response‘s writer or 115 * output stream object, and finally, write the response data. 116 * It‘s best to include content type and encoding. When using 117 * a <code>PrintWriter</code> object to return the response, 118 * set the content type before accessing the 119 * <code>PrintWriter</code> object. 120 * 121 * <p>The servlet container must write the headers before 122 * committing the response, because in HTTP the headers must be sent 123 * before the response body. 124 * 125 * <p>Where possible, set the Content-Length header (with the 126 * {@link javax.servlet.ServletResponse#setContentLength} method), 127 * to allow the servlet container to use a persistent connection 128 * to return its response to the client, improving performance. 129 * The content length is automatically set if the entire response fits 130 * inside the response buffer. 131 * 132 * <p>When using HTTP 1.1 chunked encoding (which means that the response 133 * has a Transfer-Encoding header), do not set the Content-Length header. 134 * 135 * <p>The GET method should be safe, that is, without 136 * any side effects for which users are held responsible. 137 * For example, most form queries have no side effects. 138 * If a client request is intended to change stored data, 139 * the request should use some other HTTP method. 140 * 141 * <p>The GET method should also be idempotent, meaning 142 * that it can be safely repeated. Sometimes making a 143 * method safe also makes it idempotent. For example, 144 * repeating queries is both safe and idempotent, but 145 * buying a product online or modifying data is neither 146 * safe nor idempotent. 147 * 148 * <p>If the request is incorrectly formatted, <code>doGet</code> 149 * returns an HTTP "Bad Request" message. 150 * 151 * @param req an {@link HttpServletRequest} object that 152 * contains the request the client has made 153 * of the servlet 154 * 155 * @param resp an {@link HttpServletResponse} object that 156 * contains the response the servlet sends 157 * to the client 158 * 159 * @exception IOException if an input or output error is 160 * detected when the servlet handles 161 * the GET request 162 * 163 * @exception ServletException if the request for the GET 164 * could not be handled 165 * 166 * @see javax.servlet.ServletResponse#setContentType 167 */ 168 protected void doGet(HttpServletRequest req, HttpServletResponse resp) 169 throws ServletException, IOException 170 { 171 String protocol = req.getProtocol(); 172 String msg = lStrings.getString("http.method_get_not_supported"); 173 if (protocol.endsWith("1.1")) { 174 resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg); 175 } else { 176 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); 177 } 178 } 179 180 181 /** 182 * Returns the time the <code>HttpServletRequest</code> 183 * object was last modified, 184 * in milliseconds since midnight January 1, 1970 GMT. 185 * If the time is unknown, this method returns a negative 186 * number (the default). 187 * 188 * <p>Servlets that support HTTP GET requests and can quickly determine 189 * their last modification time should override this method. 190 * This makes browser and proxy caches work more effectively, 191 * reducing the load on server and network resources. 192 * 193 * @param req the <code>HttpServletRequest</code> 194 * object that is sent to the servlet 195 * 196 * @return a <code>long</code> integer specifying 197 * the time the <code>HttpServletRequest</code> 198 * object was last modified, in milliseconds 199 * since midnight, January 1, 1970 GMT, or 200 * -1 if the time is not known 201 */ 202 protected long getLastModified(HttpServletRequest req) { 203 return -1; 204 } 205 206 207 /** 208 * <p>Receives an HTTP HEAD request from the protected 209 * <code>service</code> method and handles the 210 * request. 211 * The client sends a HEAD request when it wants 212 * to see only the headers of a response, such as 213 * Content-Type or Content-Length. The HTTP HEAD 214 * method counts the output bytes in the response 215 * to set the Content-Length header accurately. 216 * 217 * <p>If you override this method, you can avoid computing 218 * the response body and just set the response headers 219 * directly to improve performance. Make sure that the 220 * <code>doHead</code> method you write is both safe 221 * and idempotent (that is, protects itself from being 222 * called multiple times for one HTTP HEAD request). 223 * 224 * <p>If the HTTP HEAD request is incorrectly formatted, 225 * <code>doHead</code> returns an HTTP "Bad Request" 226 * message. 227 * 228 * @param req the request object that is passed to the servlet 229 * 230 * @param resp the response object that the servlet 231 * uses to return the headers to the client 232 * 233 * @exception IOException if an input or output error occurs 234 * 235 * @exception ServletException if the request for the HEAD 236 * could not be handled 237 */ 238 protected void doHead(HttpServletRequest req, HttpServletResponse resp) 239 throws ServletException, IOException { 240 241 NoBodyResponse response = new NoBodyResponse(resp); 242 243 doGet(req, response); 244 response.setContentLength(); 245 } 246 247 248 /** 249 * Called by the server (via the <code>service</code> method) 250 * to allow a servlet to handle a POST request. 251 * 252 * The HTTP POST method allows the client to send 253 * data of unlimited length to the Web server a single time 254 * and is useful when posting information such as 255 * credit card numbers. 256 * 257 * <p>When overriding this method, read the request data, 258 * write the response headers, get the response‘s writer or output 259 * stream object, and finally, write the response data. It‘s best 260 * to include content type and encoding. When using a 261 * <code>PrintWriter</code> object to return the response, set the 262 * content type before accessing the <code>PrintWriter</code> object. 263 * 264 * <p>The servlet container must write the headers before committing the 265 * response, because in HTTP the headers must be sent before the 266 * response body. 267 * 268 * <p>Where possible, set the Content-Length header (with the 269 * {@link javax.servlet.ServletResponse#setContentLength} method), 270 * to allow the servlet container to use a persistent connection 271 * to return its response to the client, improving performance. 272 * The content length is automatically set if the entire response fits 273 * inside the response buffer. 274 * 275 * <p>When using HTTP 1.1 chunked encoding (which means that the response 276 * has a Transfer-Encoding header), do not set the Content-Length header. 277 * 278 * <p>This method does not need to be either safe or idempotent. 279 * Operations requested through POST can have side effects for 280 * which the user can be held accountable, for example, 281 * updating stored data or buying items online. 282 * 283 * <p>If the HTTP POST request is incorrectly formatted, 284 * <code>doPost</code> returns an HTTP "Bad Request" message. 285 * 286 * 287 * @param req an {@link HttpServletRequest} object that 288 * contains the request the client has made 289 * of the servlet 290 * 291 * @param resp an {@link HttpServletResponse} object that 292 * contains the response the servlet sends 293 * to the client 294 * 295 * @exception IOException if an input or output error is 296 * detected when the servlet handles 297 * the request 298 * 299 * @exception ServletException if the request for the POST 300 * could not be handled 301 * 302 * @see javax.servlet.ServletOutputStream 303 * @see javax.servlet.ServletResponse#setContentType 304 */ 305 protected void doPost(HttpServletRequest req, HttpServletResponse resp) 306 throws ServletException, IOException { 307 308 String protocol = req.getProtocol(); 309 String msg = lStrings.getString("http.method_post_not_supported"); 310 if (protocol.endsWith("1.1")) { 311 resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg); 312 } else { 313 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); 314 } 315 } 316 317 318 /** 319 * Called by the server (via the <code>service</code> method) 320 * to allow a servlet to handle a PUT request. 321 * 322 * The PUT operation allows a client to 323 * place a file on the server and is similar to 324 * sending a file by FTP. 325 * 326 * <p>When overriding this method, leave intact 327 * any content headers sent with the request (including 328 * Content-Length, Content-Type, Content-Transfer-Encoding, 329 * Content-Encoding, Content-Base, Content-Language, Content-Location, 330 * Content-MD5, and Content-Range). If your method cannot 331 * handle a content header, it must issue an error message 332 * (HTTP 501 - Not Implemented) and discard the request. 333 * For more information on HTTP 1.1, see RFC 2616 334 * <a href="http://www.ietf.org/rfc/rfc2616.txt"></a>. 335 * 336 * <p>This method does not need to be either safe or idempotent. 337 * Operations that <code>doPut</code> performs can have side 338 * effects for which the user can be held accountable. When using 339 * this method, it may be useful to save a copy of the 340 * affected URL in temporary storage. 341 * 342 * <p>If the HTTP PUT request is incorrectly formatted, 343 * <code>doPut</code> returns an HTTP "Bad Request" message. 344 * 345 * @param req the {@link HttpServletRequest} object that 346 * contains the request the client made of 347 * the servlet 348 * 349 * @param resp the {@link HttpServletResponse} object that 350 * contains the response the servlet returns 351 * to the client 352 * 353 * @exception IOException if an input or output error occurs 354 * while the servlet is handling the 355 * PUT request 356 * 357 * @exception ServletException if the request for the PUT 358 * cannot be handled 359 */ 360 protected void doPut(HttpServletRequest req, HttpServletResponse resp) 361 throws ServletException, IOException { 362 363 String protocol = req.getProtocol(); 364 String msg = lStrings.getString("http.method_put_not_supported"); 365 if (protocol.endsWith("1.1")) { 366 resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg); 367 } else { 368 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); 369 } 370 } 371 372 373 /** 374 * Called by the server (via the <code>service</code> method) 375 * to allow a servlet to handle a DELETE request. 376 * 377 * The DELETE operation allows a client to remove a document 378 * or Web page from the server. 379 * 380 * <p>This method does not need to be either safe 381 * or idempotent. Operations requested through 382 * DELETE can have side effects for which users 383 * can be held accountable. When using 384 * this method, it may be useful to save a copy of the 385 * affected URL in temporary storage. 386 * 387 * <p>If the HTTP DELETE request is incorrectly formatted, 388 * <code>doDelete</code> returns an HTTP "Bad Request" 389 * message. 390 * 391 * @param req the {@link HttpServletRequest} object that 392 * contains the request the client made of 393 * the servlet 394 * 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 * DELETE request 403 * 404 * @exception ServletException if the request for the 405 * DELETE cannot be handled 406 */ 407 protected void doDelete(HttpServletRequest req, 408 HttpServletResponse resp) 409 throws ServletException, IOException { 410 411 String protocol = req.getProtocol(); 412 String msg = lStrings.getString("http.method_delete_not_supported"); 413 if (protocol.endsWith("1.1")) { 414 resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg); 415 } else { 416 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg); 417 } 418 } 419 420 421 private static Method[] getAllDeclaredMethods(Class<?> c) { 422 423 if (c.equals(javax.servlet.http.HttpServlet.class)) { 424 return null; 425 } 426 427 Method[] parentMethods = getAllDeclaredMethods(c.getSuperclass()); 428 Method[] thisMethods = c.getDeclaredMethods(); 429 430 if ((parentMethods != null) && (parentMethods.length > 0)) { 431 Method[] allMethods = 432 new Method[parentMethods.length + thisMethods.length]; 433 System.arraycopy(parentMethods, 0, allMethods, 0, 434 parentMethods.length); 435 System.arraycopy(thisMethods, 0, allMethods, parentMethods.length, 436 thisMethods.length); 437 438 thisMethods = allMethods; 439 } 440 441 return thisMethods; 442 } 443 444 445 /** 446 * Called by the server (via the <code>service</code> method) 447 * to allow a servlet to handle a OPTIONS request. 448 * 449 * The OPTIONS request determines which HTTP methods 450 * the server supports and 451 * returns an appropriate header. For example, if a servlet 452 * overrides <code>doGet</code>, this method returns the 453 * following header: 454 * 455 * <p><code>Allow: GET, HEAD, TRACE, OPTIONS</code> 456 * 457 * <p>There‘s no need to override this method unless the 458 * servlet implements new HTTP methods, beyond those 459 * implemented by HTTP 1.1. 460 * 461 * @param req the {@link HttpServletRequest} object that 462 * contains the request the client made of 463 * the servlet 464 * 465 * @param resp the {@link HttpServletResponse} object that 466 * contains the response the servlet returns 467 * to the client 468 * 469 * @exception IOException if an input or output error occurs 470 * while the servlet is handling the 471 * OPTIONS request 472 * 473 * @exception ServletException if the request for the 474 * OPTIONS cannot be handled 475 */ 476 protected void doOptions(HttpServletRequest req, 477 HttpServletResponse resp) 478 throws ServletException, IOException { 479 480 Method[] methods = getAllDeclaredMethods(this.getClass()); 481 482 boolean ALLOW_GET = false; 483 boolean ALLOW_HEAD = false; 484 boolean ALLOW_POST = false; 485 boolean ALLOW_PUT = false; 486 boolean ALLOW_DELETE = false; 487 boolean ALLOW_TRACE = true; 488 boolean ALLOW_OPTIONS = true; 489 490 for (int i=0; i<methods.length; i++) { 491 Method m = methods[i]; 492 493 if (m.getName().equals("doGet")) { 494 ALLOW_GET = true; 495 ALLOW_HEAD = true; 496 } 497 if (m.getName().equals("doPost")) 498 ALLOW_POST = true; 499 if (m.getName().equals("doPut")) 500 ALLOW_PUT = true; 501 if (m.getName().equals("doDelete")) 502 ALLOW_DELETE = true; 503 } 504 505 String allow = null; 506 if (ALLOW_GET) 507 allow=METHOD_GET; 508 if (ALLOW_HEAD) 509 if (allow==null) allow=METHOD_HEAD; 510 else allow += ", " + METHOD_HEAD; 511 if (ALLOW_POST) 512 if (allow==null) allow=METHOD_POST; 513 else allow += ", " + METHOD_POST; 514 if (ALLOW_PUT) 515 if (allow==null) allow=METHOD_PUT; 516 else allow += ", " + METHOD_PUT; 517 if (ALLOW_DELETE) 518 if (allow==null) allow=METHOD_DELETE; 519 else allow += ", " + METHOD_DELETE; 520 if (ALLOW_TRACE) 521 if (allow==null) allow=METHOD_TRACE; 522 else allow += ", " + METHOD_TRACE; 523 if (ALLOW_OPTIONS) 524 if (allow==null) allow=METHOD_OPTIONS; 525 else allow += ", " + METHOD_OPTIONS; 526 527 resp.setHeader("Allow", allow); 528 } 529 530 531 /** 532 * Called by the server (via the <code>service</code> method) 533 * to allow a servlet to handle a TRACE request. 534 * 535 * A TRACE returns the headers sent with the TRACE 536 * request to the client, so that they can be used in 537 * debugging. There‘s no need to override this method. 538 * 539 * @param req the {@link HttpServletRequest} object that 540 * contains the request the client made of 541 * the servlet 542 * 543 * @param resp the {@link HttpServletResponse} object that 544 * contains the response the servlet returns 545 * to the client 546 * 547 * @exception IOException if an input or output error occurs 548 * while the servlet is handling the 549 * TRACE request 550 * 551 * @exception ServletException if the request for the 552 * TRACE cannot be handled 553 */ 554 protected void doTrace(HttpServletRequest req, HttpServletResponse resp) 555 throws ServletException, IOException 556 { 557 558 int responseLength; 559 560 String CRLF = "\r\n"; 561 StringBuilder buffer = new StringBuilder("TRACE ").append(req.getRequestURI()) 562 .append(" ").append(req.getProtocol()); 563 564 Enumeration<String> reqHeaderEnum = req.getHeaderNames(); 565 566 while( reqHeaderEnum.hasMoreElements() ) { 567 String headerName = reqHeaderEnum.nextElement(); 568 buffer.append(CRLF).append(headerName).append(": ") 569 .append(req.getHeader(headerName)); 570 } 571 572 buffer.append(CRLF); 573 574 responseLength = buffer.length(); 575 576 resp.setContentType("message/http"); 577 resp.setContentLength(responseLength); 578 ServletOutputStream out = resp.getOutputStream(); 579 out.print(buffer.toString()); 580 out.close(); 581 return; 582 } 583 584 585 /** 586 * Receives standard HTTP requests from the public 587 * <code>service</code> method and dispatches 588 * them to the <code>do</code><i>Method</i> methods defined in 589 * this class. This method is an HTTP-specific version of the 590 * {@link javax.servlet.Servlet#service} method. There‘s no 591 * need to override this method. 592 * 593 * @param req the {@link HttpServletRequest} object that 594 * contains the request the client made of 595 * the servlet 596 * 597 * @param resp the {@link HttpServletResponse} object that 598 * contains the response the servlet returns 599 * to the client 600 * 601 * @exception IOException if an input or output error occurs 602 * while the servlet is handling the 603 * HTTP request 604 * 605 * @exception ServletException if the HTTP request 606 * cannot be handled 607 * 608 * @see javax.servlet.Servlet#service 609 */ 610 protected void service(HttpServletRequest req, HttpServletResponse resp) 611 throws ServletException, IOException { 612 613 String method = req.getMethod(); 614 615 if (method.equals(METHOD_GET)) { 616 long lastModified = getLastModified(req); 617 if (lastModified == -1) { 618 // servlet doesn‘t support if-modified-since, no reason 619 // to go through further expensive logic 620 doGet(req, resp); 621 } else { 622 long ifModifiedSince; 623 try { 624 ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); 625 } catch (IllegalArgumentException iae) { 626 // Invalid date header - proceed as if none was set 627 ifModifiedSince = -1; 628 } 629 if (ifModifiedSince < (lastModified / 1000 * 1000)) { 630 // If the servlet mod time is later, call doGet() 631 // Round down to the nearest second for a proper compare 632 // A ifModifiedSince of -1 will always be less 633 maybeSetLastModified(resp, lastModified); 634 doGet(req, resp); 635 } else { 636 resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); 637 } 638 } 639 640 } else if (method.equals(METHOD_HEAD)) { 641 long lastModified = getLastModified(req); 642 maybeSetLastModified(resp, lastModified); 643 doHead(req, resp); 644 645 } else if (method.equals(METHOD_POST)) { 646 doPost(req, resp); 647 648 } else if (method.equals(METHOD_PUT)) { 649 doPut(req, resp); 650 651 } else if (method.equals(METHOD_DELETE)) { 652 doDelete(req, resp); 653 654 } else if (method.equals(METHOD_OPTIONS)) { 655 doOptions(req,resp); 656 657 } else if (method.equals(METHOD_TRACE)) { 658 doTrace(req,resp); 659 660 } else { 661 // 662 // Note that this means NO servlet supports whatever 663 // method was requested, anywhere on this server. 664 // 665 666 String errMsg = lStrings.getString("http.method_not_implemented"); 667 Object[] errArgs = new Object[1]; 668 errArgs[0] = method; 669 errMsg = MessageFormat.format(errMsg, errArgs); 670 671 resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg); 672 } 673 } 674 675 676 /* 677 * Sets the Last-Modified entity header field, if it has not 678 * already been set and if the value is meaningful. Called before 679 * doGet, to ensure that headers are set before response data is 680 * written. A subclass might have set this header already, so we 681 * check. 682 */ 683 private void maybeSetLastModified(HttpServletResponse resp, 684 long lastModified) { 685 if (resp.containsHeader(HEADER_LASTMOD)) 686 return; 687 if (lastModified >= 0) 688 resp.setDateHeader(HEADER_LASTMOD, lastModified); 689 } 690 691 692 /** 693 * Dispatches client requests to the protected 694 * <code>service</code> method. There‘s no need to 695 * override this method. 696 * 697 * @param req the {@link HttpServletRequest} object that 698 * contains the request the client made of 699 * the servlet 700 * 701 * @param res the {@link HttpServletResponse} object that 702 * contains the response the servlet returns 703 * to the client 704 * 705 * @exception IOException if an input or output error occurs 706 * while the servlet is handling the 707 * HTTP request 708 * 709 * @exception ServletException if the HTTP request cannot 710 * be handled 711 * 712 * @see javax.servlet.Servlet#service 713 */ 714 @Override 715 public void service(ServletRequest req, ServletResponse res) 716 throws ServletException, IOException { 717 718 HttpServletRequest request; 719 HttpServletResponse response; 720 721 try { 722 request = (HttpServletRequest) req; 723 response = (HttpServletResponse) res; 724 } catch (ClassCastException e) { 725 throw new ServletException("non-HTTP request or response"); 726 } 727 service(request, response); 728 } 729 } 730 731 732 /* 733 * A response wrapper for use in (dumb) "HEAD" support. 734 * This just swallows that body, counting the bytes in order to set 735 * the content length appropriately. All other methods delegate to the 736 * wrapped HTTP Servlet Response object. 737 */ 738 // file private 739 class NoBodyResponse extends HttpServletResponseWrapper { 740 private NoBodyOutputStream noBody; 741 private PrintWriter writer; 742 private boolean didSetContentLength; 743 744 // file private 745 NoBodyResponse(HttpServletResponse r) { 746 super(r); 747 noBody = new NoBodyOutputStream(); 748 } 749 750 // file private 751 void setContentLength() { 752 if (!didSetContentLength) { 753 if (writer != null) { 754 writer.flush(); 755 } 756 super.setContentLength(noBody.getContentLength()); 757 } 758 } 759 760 761 // SERVLET RESPONSE interface methods 762 763 @Override 764 public void setContentLength(int len) { 765 super.setContentLength(len); 766 didSetContentLength = true; 767 } 768 769 @Override 770 public void setHeader(String name, String value) { 771 super.setHeader(name, value); 772 checkHeader(name); 773 } 774 775 @Override 776 public void addHeader(String name, String value) { 777 super.addHeader(name, value); 778 checkHeader(name); 779 } 780 781 @Override 782 public void setIntHeader(String name, int value) { 783 super.setIntHeader(name, value); 784 checkHeader(name); 785 } 786 787 @Override 788 public void addIntHeader(String name, int value) { 789 super.addIntHeader(name, value); 790 checkHeader(name); 791 } 792 793 private void checkHeader(String name) { 794 if ("content-length".equalsIgnoreCase(name)) { 795 didSetContentLength = true; 796 } 797 } 798 799 @Override 800 public ServletOutputStream getOutputStream() throws IOException { 801 return noBody; 802 } 803 804 @Override 805 public PrintWriter getWriter() throws UnsupportedEncodingException { 806 807 if (writer == null) { 808 OutputStreamWriter w; 809 810 w = new OutputStreamWriter(noBody, getCharacterEncoding()); 811 writer = new PrintWriter(w); 812 } 813 return writer; 814 } 815 } 816 817 818 /* 819 * Servlet output stream that gobbles up all its data. 820 */ 821 822 // file private 823 class NoBodyOutputStream extends ServletOutputStream { 824 825 private static final String LSTRING_FILE = 826 "javax.servlet.http.LocalStrings"; 827 private static ResourceBundle lStrings = 828 ResourceBundle.getBundle(LSTRING_FILE); 829 830 private int contentLength = 0; 831 832 // file private 833 NoBodyOutputStream() { 834 // NOOP 835 } 836 837 // file private 838 int getContentLength() { 839 return contentLength; 840 } 841 842 @Override 843 public void write(int b) { 844 contentLength++; 845 } 846 847 @Override 848 public void write(byte buf[], int offset, int len) throws IOException { 849 if (buf == null) { 850 throw new NullPointerException( 851 lStrings.getString("err.io.nullArray")); 852 } 853 854 if (offset < 0 || len < 0 || offset+len > buf.length) { 855 String msg = lStrings.getString("err.io.indexOutOfBounds"); 856 Object[] msgArgs = new Object[3]; 857 msgArgs[0] = Integer.valueOf(offset); 858 msgArgs[1] = Integer.valueOf(len); 859 msgArgs[2] = Integer.valueOf(buf.length); 860 msg = MessageFormat.format(msg, msgArgs); 861 throw new IndexOutOfBoundsException(msg); 862 } 863 864 contentLength += len; 865 } 866 }