ServletContext
When the servletcontainer (like Apache Tomcat) starts up, it will deploy and load all webapplications. When a webapplication get loaded, the servletcontainer will create the ServletContext
once and keep in server's memory. The webapp's web.xml
will be parsed and every Servlet
, Filter
and Listener
found in web.xml
will be created once and kept in server's memory as well. When the servletcontainer shuts down, it will unload all webapplications and the ServletContext
and all Servlet
, Filter
and Listener
instances will be trashed.
HttpServletRequest and HttpServletResponse
The servletcontainer is attached to a webserver which listens on HTTP requests on a certain port number, which is usually 80. When a client (user with a webbrowser) sends a HTTP request, the servletcontainer will create a HttpServletRequest
and HttpServletResponse
and pass it through the methods of the already-created Filter
and Servlet
instances whose url-pattern
matches the request URL, all in the same thread.
The request object provides access to all information of the HTTP request, such as the request headers and the request body. The response object provides facility to control and send the HTTP response the way you want, such as setting headers and the body (usually with HTML content from a JSP file). When the HTTP response is committed and finished, then both the request and response objects will be trashed.
HttpSession
When a client visits the webapp for the first time and/or the HttpSession
is to be obtained for the first time by request.getSession()
, then the servletcontainer will create it, generate a long and unique ID (which you can get by session.getId()
) and store it in server's memory. The servletcontainer will also set a Cookie
in the HTTP response with JSESSIONID
as cookie name and the unique session ID as cookie value.
As per the HTTP cookie specification (a contract a decent webbrowser and webserver has to adhere), the client (the webbrowser) is required to send this cookie back in the subsequent requests as long as the cookie is valid. Using a HTTP header checker tool like Firebug you can check them. The servletcontainer will determine every incoming HTTP request header for the presence of the cookie with the name JSESSIONID
and use its value (the session ID) to get the associated HttpSession
from server's memory.
The HttpSession
lives as long until it has not been used for more than the time as you can specify in <session-timeout>
setting in web.xml
, which defaults to 30 minutes. So when the client doesn't visit the webapp anymore for over 30 minutes, then the servletcontainer will trash the session. Every subsequent request, even though with the cookie specified, will not have access to the same session anymore. The servletcontainer will create a new one.
On the other hand, the session cookie has on the client side a default lifetime which is as long as the browser instance is running. So when the client closes the browser instance (all tabs/windows), then the session will be trashed at the client side. In a new browser instance the cookie associated with the session won't be send anymore. A new request.getSession()
would return a brand new HttpSession
and set a cookie with a brand new session ID.
In a nut
- The
ServletContext
lives as long as the webapp lives. It's been shared among all requests in all sessions.
- The
HttpSession
lives as long as the client is interacting with the webapp with the same browser instance and the session hasn't timed out at the server side yet. It's been shared among all requests in the same session.
- The
HttpServletRequest
and HttpServletResponse
lives as long as the client has sent it until the complete response (the webpage) is arrived. It is not been shared elsewhere.
- Any
Servlet
, Filter
and Listener
lives as long as the webapp lives. They are been shared among all requests in all sessions.
- Any
attribute
which you set in ServletContext
, HttpServletRequest
and HttpSession
will live as long as the object in question lives.
Threadsafety
That said, your major concern is possibly threadsafety. You should now have learnt that Servlets and filters are shared among all requests. That's the nice thing of Java, it's multithreaded and different threads (read: HTTP requests) can make use of the same instance. It would otherwise have been too expensive to recreate it on every request.
But you should also realize that you should never assign any request or session scoped data as an instance variable of a servlet or filter. It would going to be shared among all other requests in other sessions. That's threadunsafe! The below example illustrates that:
public class MyServlet extends HttpServlet {
private Object thisIsNOTThreadSafe;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object thisIsThreadSafe;
thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
}
}
See also: