How do servlets work-Instantiation, sessions, shared variables and multithreading[reproduced]
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
, or annotated with respectively @WebServlet
, @WebFilter
and @WebListener
, will be created once and kept in server's memory as well. For all filters, the init()
method will also be invoked immediately. When the servletcontainer shuts down, it will unload all webapplications, invoke the destroy()
of all initialized servlets and filters, and finally the ServletContext
and all Servlet
, Filter
and Listener
instances will be trashed.
When the Servlet
in question has a <servlet><load-on-startup>
or @WebServlet(loadOnStartup)
value greater than 0
, then its init()
method will also immediately be invoked during startup. Those servlets are initialized in the same order as "load-on-startup" value represents, or if they are the same, then the order in the web.xml
or @WebServlet
classloading. Or, if the "load-on-startup" value is absent, then the init()
method will only be invoked on very first HTTP request hitting the servlet in question.
HttpServletRequest and HttpServletResponse
The servletcontainer is attached to a webserver which listens on HTTP requests on a certain port number, which is usually 8080 in development and 80 in production. When a client (user with a webbrowser) sends a HTTP request, the servletcontainer will create new HttpServletRequest
and HttpServletResponse
objects 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.
In case of filters, the doFilter()
method will be invoked. When its code calls chain.doFilter(request, response)
, then the request and response will continue to the next filter, or if there is none, hit the servlet. In case of servlets, the service()
method will be invoked, which by default determines based on request.getMethod()
which one of the doXxx()
methods to invoke. If such method is absent on the actual servlet, then it will return HTTP 405 error.
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 (actually, most containers will cleanup the state and recycle the instance for reuse).
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 a new HttpSession
object, 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 Set-Cookie
header of 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 in the Cookie
header as long as the cookie is valid (i.e. is not expired and has the right domain and path). Using browser builtin HTTP traffic monitor you can check them (press F12 in Chrome / Firefox23+ / IE9+ and check Net/Network tab). The servletcontainer will determine the Cookie
header of every incoming HTTP request 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 until it has not been used for more than the <session-timeout>
time, a setting you can specify 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 on the client side has 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 sent anymore. A new request.getSession()
would return a brand new HttpSession
and set a cookie with a brand new session ID.
In a nutshell
- The
ServletContext
lives as long as the webapp lives. It's been shared among all requests inall 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
andHttpServletResponse
lives as long as the client has sent it until the complete response (the webpage) is arrived. It is not being shared elsewhere. - Any
Servlet
,Filter
andListener
lives as long as the webapp lives. They are being shared among all requests in all sessions. - Any
attribute
which you set inServletContext
,HttpServletRequest
andHttpSession
will live as long as the object in question lives. The object itself represents the "scope" in bean management frameworks such as JSF, CDI, Spring, etc. Those frameworks store their scoped beans as anattribute
of closest matching scope.
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, init()
and destroy()
it on every single request.
But you should also realize that you should never assign any request or session scoped data as aninstance variable of a servlet or filter. It will be shared among all other requests in other sessions. That's threadunsafe! The below example illustrates that:
public class ExampleServlet 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.
}
}
From:
http://stackoverflow.com/questions/3106452/how-do-servlets-work-instantiation-sessions-shared-variables-and-multithreadi/3106909#3106909
How do servlets work-Instantiation, sessions, shared variables and multithreading[reproduced]的更多相关文章
- 创建一个dynamics 365 CRM online plugin (八) - 使用Shared Variables 在plugins 之前传递data
CRM 可以实现plugin之前的值传递. 我们可以使用SharedVariables 把值在plugin之间传递 实现plugins之间的传递非常简单,我们只需要用key value pair来配对 ...
- Write thread-safe servlets [reproduced]
If you write Web applications in Java, the servlet is your best friend. Whether you write Java Serve ...
- 【转】Application.mk 文件语法规范
原文网址:http://blog.sina.com.cn/s/blog_4c451e0e0100s6q4.html Application.mk file syntax specification A ...
- 『TensorFlow』分布式训练_其二_单机多GPU并行&GPU模式设定
建议比对『MXNet』第七弹_多GPU并行程序设计 一.tensorflow GPU设置 GPU指定占用 gpu_options = tf.GPUOptions(per_process_gpu_mem ...
- How to choose from Viewstate, SessionState, Cookies and Cache
https://devshop.wordpress.com/2008/04/10/how-to-choose-from-viewstate-sessionstate-cookies-and-cache ...
- Android NDK 学习之Application.mk
Application.mk file syntax specification Introduction: This document describes the syntax of Applica ...
- Freemarker 程序开发
Freemarker 程序开发 现在web开发中,多使用freemarker 来描述页面.通常会使用的macro来定义各种组件,从而达到UI组件的复用.结合使用其它的指定,可快速的描述一个html页面 ...
- Spark——共享变量
Spark执行不少操作时都依赖于闭包函数的调用,此时如果闭包函数使用到了外部变量驱动程序在使用行动操作时传递到集群中各worker节点任务时就会进行一系列操作: 1.驱动程序使将闭包中使用变量封装成对 ...
- theano scan optimization
selected from Theano Doc Optimizing Scan performance Minimizing Scan Usage performan as much of the ...
随机推荐
- Http状态码之:301、302重定向
概念 301 Moved Permanently 被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一.如果可能,拥有链接编辑功能的客户端应当自动把请求的地 ...
- 学习ASP.NET Core, 怎能不了解请求处理管道[4]: 应用的入口——Startup
一个ASP.NET Core应用被启动之后就具有了针对请求的处理能力,而这个能力是由管道赋予的,所以应用的启动同时意味着管道的成功构建.由于管道是由注册的服务器和若干中间件构成的,所以应用启动过程中一 ...
- Spring Enable annotation – writing a custom Enable annotation
原文地址:https://www.javacodegeeks.com/2015/04/spring-enable-annotation-writing-a-custom-enable-annotati ...
- 免费道路 bzoj 3624
免费道路(1s 128MB)roads [输入样例] 5 7 21 3 04 5 13 2 05 3 14 3 01 2 14 2 1 [输出样例] 3 2 04 3 05 3 11 2 1 题解: ...
- Object是什么
Object是什么 .Net程序员们每天都在和Object在打交道如果你问一个.Net程序员什么是Object,他可能会信誓旦旦的告诉你"Object还不简单吗,就是所有类型的基类" ...
- 2015微软MVP全球峰会见闻
2015.10.31-2015.11.8 一周的时间完成微软MVP全球峰会旅程,这一周在不断的倒时差,行程安排非常的紧张,还好和大家请假了没有更新微信公众号,今天开始继续更新微信公众号,开始新的旅程, ...
- 几款主流 NoSql 数据库的对比
最近小组准备启动一个 node 开源项目,从前端亲和力.大数据下的IO性能.可扩展性几点入手挑选了 NoSql 数据库,但具体使用哪一款产品还需要做一次选型. 我们最终把选项范围缩窄在 HBase.R ...
- php杂记(二)
1.获取客户端真实IP if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $onlineip = $_SERVER['HTTP_CLIENT_IP']; } else ...
- MyBatis5:MyBatis集成Spring事物管理(上篇)
前言 有些日子没写博客了,主要原因一个是工作,另一个就是健身,因为我们不仅需要努力工作,也需要有健康的身体嘛. 那有看LZ博客的网友朋友们放心,LZ博客还是会继续保持更新,只是最近两三个月LZ写博客相 ...
- ABP源码分析二十三:Authorization
Permission:用于定义一个Permission,一个permission可以包含多个子Permission. PermissionDictionary:继承自Dictionary<str ...