HttpServlet中的2种请求处理方式
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HttpServlet中的2种请求处理方式相关的知识,希望对你有一定的参考价值。
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以上是关于HttpServlet中的2种请求处理方式的主要内容,如果未能解决你的问题,请参考以下文章
javaweb三大组件之servlet---httpservlet
继承了httpservlet重写service()与重写doget()dopost()区别