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 ServletFilter 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 @WebServletclassloading. 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 HttpSessionobject, 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 and HttpServletResponse lives as long as the client has sent it until the complete response (the webpage) is arrived. It is not being shared elsewhere.
  • Any ServletFilter and Listener lives as long as the webapp lives. They are being shared among all requests in all sessions.
  • Any attribute which you set in ServletContextHttpServletRequest and HttpSession 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 an attribute 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]的更多相关文章

  1. 创建一个dynamics 365 CRM online plugin (八) - 使用Shared Variables 在plugins 之前传递data

    CRM 可以实现plugin之前的值传递. 我们可以使用SharedVariables 把值在plugin之间传递 实现plugins之间的传递非常简单,我们只需要用key value pair来配对 ...

  2. Write thread-safe servlets [reproduced]

    If you write Web applications in Java, the servlet is your best friend. Whether you write Java Serve ...

  3. 【转】Application.mk 文件语法规范

    原文网址:http://blog.sina.com.cn/s/blog_4c451e0e0100s6q4.html Application.mk file syntax specification A ...

  4. 『TensorFlow』分布式训练_其二_单机多GPU并行&GPU模式设定

    建议比对『MXNet』第七弹_多GPU并行程序设计 一.tensorflow GPU设置 GPU指定占用 gpu_options = tf.GPUOptions(per_process_gpu_mem ...

  5. 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 ...

  6. Android NDK 学习之Application.mk

    Application.mk file syntax specification Introduction: This document describes the syntax of Applica ...

  7. Freemarker 程序开发

    Freemarker 程序开发 现在web开发中,多使用freemarker 来描述页面.通常会使用的macro来定义各种组件,从而达到UI组件的复用.结合使用其它的指定,可快速的描述一个html页面 ...

  8. Spark——共享变量

    Spark执行不少操作时都依赖于闭包函数的调用,此时如果闭包函数使用到了外部变量驱动程序在使用行动操作时传递到集群中各worker节点任务时就会进行一系列操作: 1.驱动程序使将闭包中使用变量封装成对 ...

  9. theano scan optimization

    selected from Theano Doc Optimizing Scan performance Minimizing Scan Usage performan as much of the ...

随机推荐

  1. Storm如何保证可靠的消息处理

    作者:Jack47 PS:如果喜欢我写的文章,欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. 本文主要翻译自Storm官方文档Guaranteeing messag ...

  2. Hyper-V无法文件拖拽解决方案~~~这次用一个取巧的方法架设一个FTP来访问某个磁盘,并方便的读写文件

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 服务器相关的知识点:http://www.cnblogs.com/dunitia ...

  3. Sublime的使用

    1.一个可扩展性强的编辑工具 2.如何安装扩展 通过View->Show Console菜单打开命令行. 按图操作: 在控制台输入,然后回车: import urllib.request,os; ...

  4. 23种设计模式--观察者模式-Observer Pattern

    一.观察者模式的介绍      观察者模式从字面的意思上理解,肯定有两个对象一个是观察者,另外一个是被观察者,观察者模式就是当被观察者发生改变得时候发送通知给观察者,当然这个观察者可以是多个对象,在项 ...

  5. 【C#附源码】数据库文档生成工具支持(Excel+Html)

    [2015] 很多时候,我们在生成数据库文档时,使用某些工具,可效果总不理想,不是内容不详细,就是表现效果一般般.很多还是word.html的.看着真是别扭.本人习惯用Excel,所以闲暇时,就简单的 ...

  6. 通过AngularJS实现前端与后台的数据对接(一)——预备工作篇

    最近,笔者在做一个项目:使用AngularJS,从而实现前端与后台的数据对接.笔者这是第一次做前端与后台的数据对接的工作,因此遇到了许多问题.笔者在这些问题中,总结了一些如何实现前端与后台的数据对接的 ...

  7. php 基础代码大全(不断完善中)

    下面是基础的PHP的代码,不断完善中~ //语法错误(syntax error)在语法分析阶段,源代码并未被执行,故不会有任何输出. /* [命名规则] */ 常量名 类常量建议全大写,单词间用下划线 ...

  8. 升级npm

    查看npm的所有版本 运行命令: npm view npm versions 命令运行后,会输出到目前为止npm的所有版本. [ '1.1.25', '1.1.70', '1.1.71', '1.2. ...

  9. 15个C++项目列表

    实验楼上有很多C++的实战项目,从简单到进阶,学习每个项目都可以掌握相应的知识点. 如果你还是C++新手的话,那么这个C++的项目列表你可以拿去练手实战开发,毕竟学编程动手实践是少不了的! 如果你不知 ...

  10. BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 1280 MBSubmit: 3127  Solved: 795[Submit][Status][Discu ...