Abstract: original source: www.bysocket.com Com Mason BYSocket hopes to reprint and keep the summary, thank you!
Combined with the previous article:< Illustration & in simple terms: Java Web: Servlet must know>
1, Go back to the service method of HttpServlet
The Servlet basic interface defines the service method for client request processing. When the request reaches the Servlet container, the Servlet container routes it to a Servlet instance.
For example, javax servlet. http. The httpservlet class has a protected void service method as follows:
private static final String METHOD_DELETE = "DELETE"; private static final String METHOD_HEAD = "HEAD"; private static final String METHOD_GET = "GET"; private static final String METHOD_OPTIONS = "OPTIONS"; private static final String METHOD_POST = "POST"; private static final String METHOD_PUT = "PUT"; private static final String METHOD_TRACE = "TRACE"; private static final String HEADER_IFMODSINCE = "If-Modified-Since"; private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings"; private static ResourceBundle lStrings = ResourceBundle.getBundle(LSTRING_FILE); /** * HTTP Status code 304 */ public static final int SC_NOT_MODIFIED = 304; /** * Receive standard HTTP requests from public service methods, * And distribute them to the doXXX methods defined in this class. */ protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // Get request method name String method = req.getMethod(); // If it is a GET request if (method.equals(METHOD_GET)) { // The last time the HttpServletRequest object was modified long lastModified = getLastModified(req); // No change if (lastModified == -1) { doGet(req, resp); } else { long ifModifiedSince; try { // Get the server modification time in the request header ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); } catch (IllegalArgumentException iae) { // Invalid get ifModifiedSince = -1; } // If the request header server is modified late if (ifModifiedSince < (lastModified / 1000 * 1000)) { // Set the time to modify the HttpServletResponse object and reset the browser parameters //maybeSetLastModified(resp, lastModified); // Call the doGet method doGet(req, resp); } else { // 304 HTTP status code resp.setStatus(SC_NOT_MODIFIED); } } } else if (method.equals(METHOD_HEAD)) { long lastModified = getLastModified(req); //maybeSetLastModified(resp, lastModified); doHead(req, resp); } else if (method.equals(METHOD_POST)) { doPost(req, resp); } else if (method.equals(METHOD_PUT)) { doPut(req, resp); } else if (method.equals(METHOD_DELETE)) { doDelete(req, resp); } else if (method.equals(METHOD_OPTIONS)) { doOptions(req,resp); } else if (method.equals(METHOD_TRACE)) { doTrace(req,resp); } else { // If not requested String errMsg = lStrings.getString("http.method_not_implemented"); Object[] errArgs = new Object[1]; errArgs[0] = method; errMsg = MessageFormat.format(errMsg, errArgs); // 501 HTTP status code resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg); } }
The code logic is explained as follows:
1. The protected void service method of HttpServlet is used to accept standard HTTP requests received by the public service.
That is, HttpServlet overrides the service method of the parent GenericServlet. As shown in the figure, this method forcibly converts the ServletRequest and ServletResponse objects obtained from the container into HttpServletRequest and HttpServletResponse objects for HTTP processing. Then the two objects are routed to the protected void service method of HttpServlet (where the code is selected in the figure)

2. It is then distributed to the doXXX method defined by this class according to the requested method name. If it is not requested, the 501 HTTP status code is returned.
In this way, you seem to understand something, that is, if you override the doGet method in HelloServlet, you will distribute it to the doGet method of HelloServlet, a subclass of HttpServlet.
Oh ~ also, 501 HTTP status code - Not implemented means that the server does not support the functions required to implement the request. For example, the customer sends a PUT request that the server does not support. I see. What's the use of memorizing these HTTP status codes? Such memory is the most effective.
These are roughly the two steps. This is the workflow of the service:
1. Accept the standard HTTP request received by the public service. 2. Distribute to defined doXXX methods
2, GET request processing details
The above processing code for GET request is as follows:
// If it is a GET request if (method.equals(METHOD_GET)) { // The last time the HttpServletRequest object was modified long lastModified = getLastModified(req); // No change if (lastModified == -1) { doGet(req, resp); } else { long ifModifiedSince; try { // Get the server modification time in the request header ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); } catch (IllegalArgumentException iae) { // Invalid get ifModifiedSince = -1; } // If the request header server is modified late if (ifModifiedSince < (lastModified / 1000 * 1000)) { // Set the time to modify the HttpServletResponse object and reset the browser parameters //maybeSetLastModified(resp, lastModified); // Call the doGet method doGet(req, resp); } else { // 304 HTTP status code resp.setStatus(SC_NOT_MODIFIED); } } }
here,
1. The getLastModified(req) method is defined. Used to get the time when the HttpServletRequest object was last modified. If lastModified is the default – 1L, it is always refreshed.
This getLastModified is defined by HttpServlet to support conditional GET operations. That is, when the client obtains the resource through the GET request, the data will not occur again until the actual point at which the resource is obtained for the first time has changed. Otherwise, the data cached by the client will be used. In some appropriate occasions, the implementation of this method can make more effective use of network resources and reduce unnecessary data transmission.
2. If the return value of the getLastModified method is a positive number, it should be considered in the following two cases:
(1) If the request header does not contain the if modified since header field (it should be the first time the resource is accessed) or its getLastModified return value is newer than the time specified in the if modified since header field, call doGet to return the generated response and set the last modified message header.
(2) If the return value of getLastModified is older than the time specified in the if modified since header field, a 304 status is returned to the client, indicating that the client continues to use the previously cached page.
For example, I'm in 304< Small things to understand in Java EE: first, illustrate the Http protocol >The article mentioned that when you visit Baidu's home page for the first time, some resources will successfully obtain and return 200. Again, F5, if some resources or directly call the cached data of the client, 304 is returned.

3, Servlet thread problem
The Servlet container can route multiple requests to the service method of the Servlet concurrently. In order to handle these requests, the Servlet must handle concurrency and thread safety issues. Last< Servlet must know >It is mentioned that defining global variables can cause thread safety problems. When developing servlets, considering thread safety, the following solutions are proposed:
1. Implement SingleThreadModel interface Servlet2.4. It has been proposed not to use. Implementing this interface, the servlet container creates a separate servlet instance for each new request. This can have serious performance problems. 2. Synchronous lock Using the synchronized keyword can ensure that only one thread can access the protected section, which has achieved thread safety. However, the system performance and concurrency are greatly reduced. Undesirable~ 3. Avoid using instance variables, that is, global variables in servlets. Use local variables (recommended) The local variables in the method are allocated in the stack space, and each thread has a private stack space. Therefore, access is thread safe.
I thought of the following question:
Since the global variables of sevlets are thread unsafe, so is spring MVC Controller. Will defining an XXXService variable in the Controller cause thread safety? A: because this is a Spring Service Bean and is thread safe, it can be used as a singleton without causing thread safety.
4, Summary (don't forget to praise)
Main points of supplementary article:
Detailed explanation of HttpServlet service method Deeply understand the application of HTTP status code Thread safety of Servlet
If the above articles or links are helpful to you, don't forget to comment at the end of the article. You can also share and let more people read this article.