HttpServletRequest, HttpServletResponse and HttpSession
HttpServletRequest, HttpServletResponse
With servlets, requests are represented by HttpServletRequests and responses are represented by HttpServletResponses.
Whenever a client such as a browser, or a curl command, sends in a request, the container creates a new HttpServletRequest and HttpServletResponse object. It then passes on these new objects to the servlet’s service method. Based on the HttpServletRequest‘s method attribute, this method determines which of the doXXX methods should be called.
Apart from the information about the method, the request object also carries other information such as headers, parameters, and body. Similarly, the HttpServletResponse object also carries headers, parameters, and body – we can set them up in our servlet’s doXXX method.
These objects are short-lived. When the client gets the response back, the server marks the request and response objects for garbage collection.
When exactly is a HttpServletRequest
created?

Reference: https://stackoverflow.com/questions/26036459/what-is-a-life-of-httpservletrequest-object
The lifetime of an HttpServletRequest
object is just that: the time of serving an HTTP Servlet request.
It may be created right before calling the servlet’s doGet()
, doPost()
etc. methods, and may be destroyed right after that. It is only valid to use it during serving a request.
Note: However Servlet containers may reuse HttpServletRequest
objects for multiple requests (and this is typically the case), but they will be “cleaned” or reset so no objects (like parameters or attributes) will leak between requests. This is simply due to performance issue: it is much faster and cheaper to reset an HttpServletRequest
object than to throw away an existing one and create a new one.
In a typical Servlet container implementation if an HTTP request comes in, an HttpServletRequest
is created right when the HTTP input data of the request is parsed by the Servlet container. The whole request might be lazily initialized (e.g. parameters might only be parsed and populated if they are really accessed e.g. via getParameter() method). Then this HttpServletRequest
(which extends ServletRequest
) is passed through the Servlet filters and then passed on to Servlet.service()
which will dispatch the call to doGet()
, doPost()
etc based on the HTTP method (GET
, POST
, PUT
etc.). Then the request will still be alive until the request-response pair cycles back throughout the filter chain. And then it will be destroyed or reset (before it is used for another HTTP request).
Note:
When HttpServletRequest is passed around via spring’s @Async
, the request’s fields will get cleared.
HttpSession
How would we then maintain a state between subsequent client requests or connections? HttpSession is the answer to this riddle.
This basically binds objects to a user session, so that information pertaining to a particular user can be persisted across multiple requests. This is generally achieved using the concept of cookies, using JSESSIONID as a unique identifier for a given session. We can specify the timeout for the session in web.xml:
<session-config>
<session-timeout>10</session-timeout>
</session-config>
This means if our session has been idle for 10 minutes, the server will discard it. Any subsequent request would create a new session.
How Do Servlets Share Data
There’re various ways in which servlets can share data, based on the required scope.
Different objects have different lifetimes. HttpServletRequest and HttpServletResponse objects only live between one servlet call. HttpSession lives as long as it’s active and hasn’t timed out.
ServletContext‘s lifespan is the longest. It’s born with the web application and gets destroyed only when the application itself shuts down. Since servlet, filter, and listener instances are tied to the context, they also live as long as the web application is up and running.
Consequently, if our requirement is to share data between all servlets (e.g. to count the number of visitors to our site), then we should put the variable in the ServletContext. If we need to share data within a session, then we’d save it in the session scope. A user’s name would be an example in this case.
Lastly, there’s the request scope pertaining to data for a single request, such as the request payload.
Handling Multithreading
Multiple HttpServletRequest objects share servlets among each other such that each request operates with its own thread of the servlet instance.
What that effectively means in terms of thread-safety is that we should not assign a request or session scoped data as an instance variable of the servlet.
In this case, all requests in the session share instanceMessage, whereas message is unique to a given request object. Consequently, in the case of concurrent requests, the data in instanceMessage could be inconsistent.
public class ExampleThree extends HttpServlet {
private String instanceMessage;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String message = request.getParameter("message");
instanceMessage = request.getParameter("message");
request.setAttribute("text", message);
request.setAttribute("unsafeText", instanceMessage);
request.getRequestDispatcher("/jsp/ExampleThree.jsp").forward(request, response);
}
}
Sample implementation
https://github.com/explorer436/programming-playground/tree/main/java-playground/spring-http-demo