servlet之session工作原理简介_动力节点Java学院整理

 更新时间:2017年07月27日 10:12:41   作者:fjdingsd  
这篇文章主要介绍了servlet之session工作原理简介,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

要了解Session的底层工作原理。我们还是先看在一个会话过程中,同一个浏览器在访问多个web资源的情况好了,大致分为以下几个步骤:

1,浏览器访问某个Servlet,这时如果服务器要从请求对象中获取Session对象(第一次获取也是创建),那么服务器会为这个Session对象创建一个id:JSESSIONID

2,同时在对浏览器的响应过程中,这个Session会将JSESSIONID这个id以Cookie形式回送给客户端浏览器,记住,这时候Cookie服务器没有设置有效时间,因此是存在浏览器的缓存中,而不是在硬盘文件。

3,当用户继续在这个会话过程中访问其他Servlet,这时候这个Servlet再从请求对象中获取Session对象,注意这时候获取Session对象是从浏览器发来的请求中查询是否有名为JSESSIONID的这个Cookie,如果有,那么这个Session就不用再创建,而是直接根据查询服务器中这个相同JSESSIONID值的Session,换句话说就可以取得之前存在这个Session中的数据。

总结来说,Session是基于Cookie的。

(注:cookie并不是万能的,Session首先是依据cookie,但是有时候cookie不能用,这时候Session会查询发来请求的URL地址是否有JSESSIONID。)

Session的隐藏Cookie,我们可以做个小实验来验证下,在【myservlet】这个web工程下创建两个Servlet,分别命名为SessionDemo1和SessionDemo2:

在SessionDemo1代码为:

   HttpSession session = request.getSession();
   String data = "Message from SessionDemo";
   session.setAttribute("data", data);

在SessionDemo2代码为:

   HttpSession session = request.getSession();
   System.out.println((String)session.getAttribute("data"));

我们在浏览器中打开HttpWatch,来访问SessionDemo1,因为是首次访问Servlet,查看SessionDemo1给浏览器的响应:

确确实实服务器发送回浏览器有这个JSESSIONID名称的Cookie,这时候如果我们再在打开的浏览器去访问SessionDemo2,那么在HttpWatch中观察请求包的内容发现:

再次访问服务器时,浏览器就会带着这个名为JSESSIONID的Cookie给服务器,服务器正是通过这个cookie中的JSESSIONID值去服务器中查找之前为该浏览器创建的Session。

如果我们将浏览器关闭,由于这个cookie没有设置“setMaxAge”,因此这个cookie只存在于浏览器的缓冲,浏览器关闭即被销毁。如果想使关闭浏览器之后,Session还能存在,我们就要人为的覆盖这个Session的cookie,并设置覆盖cookie的有效时间和有效路径。而这个cookie的值,也就是JSESSIONID的值,可以通过Session的getId()方法得到

1,覆盖有效时间:

注意,服务器在为浏览器创建Session后,在用户没有操作的情况下(或者浏览器关闭后)默认为其维护30分钟。这点可以从Tomcat的【web.xml】文件中可以看出:

当然我们从这里也可以修改服务器默认的销毁无操作的Session时间。

当然如果我们不要全局设置所有服务器中Session的销毁时间,就在每个web应用中的web.xml文件中自定义添加<session-config>和<session-timeout>进行设置。

注:我们还可以通过Session对象的invalidate()方法,将某个Session进行立刻销毁。

对此,如果我们要覆盖一个Session的cookie并保存在硬盘文件中,我们设置的cookie有效时间就不要超过服务器默认的session-timeout时间。

2,覆盖有效路径:

如果我们创建一个Cookie对象,没有设置“setPath”,那么Cookie的有效路径为创建该Cookie的程序(通常为某个Servlet),即只有访问了这个程序时浏览器才会带着Cookie过去,那实在是“人脉不通”,访问这个web应用的其他资源就无法再使用Session了。

我们看看刚才的第一次访问Servlet时,服务器为浏览器创建的Session中的cookie的有效路径:

可以看到这个服务器默认将JSESSIONID这个cookie的有效路径设置为创建这个Session的web工程根目录。所以我们要覆盖Session中的cookie时也应该设置路径为该web工程根目录。

好,接下来对上面那个Servlet的例子进行改造,我们只需要在SessionDemo1中修改就行,因为这个首次将Session的cookie返回给客户端,修改后代码如下:

   HttpSession session = request.getSession();
   String data = "Message from SessionDemo";
   session.setAttribute("data", data);
     
   Cookie cookie = new Cookie("JSESSIONID", session.getId());
   cookie.setMaxAge(30*60);
   cookie.setPath("/myservlet");
   response.addCookie(cookie);

这样,当我们打开浏览器访问了SessionDemo1之后,就能在存放cookie的目录中找到该cookie,如果我们通过HttpWatch来查看可以看到重名的这个cookie:

虽然JSEESIONID这个cookie重名了,没有关系,因为其值都是一样的,并且如果我们将浏览器关闭后,没有设置cookie有效时间的(也是原先Session发来的)cookie将不复存在(存在浏览器缓存中,浏览器关闭就被销毁),这时重新打开一个浏览器,再去访问SessionDemo2依然能获取到原来Session中保存的内容:

注意,这是另外打开浏览器窗口访问的SessionDemo2!!另附:

通过这里我们可以看到,我们人为地将原先Session定义的cookie给替换了,而Session并不知道,只要能获得“JSESSIONID”这个cookie,它就认为cookie是存在的,可以从这个cookie中id值获取以前保存的信息,因此我们实现了一台主机共享一个Session,此时,当浏览器关闭,或者说结束一个会话后,依然能获取Session来获取之前保存的数据。

相关文章

  • Java实现Excel导入导出的步骤详解

    Java实现Excel导入导出的步骤详解

    这篇文章主要为大家详细介绍了java实现Excel的导入、导出,文中示例代码介绍的非常详细,对我们的学习或工作有一定的帮助,感兴趣的小伙伴们可以参考一下
    2023-06-06
  • idea中创建jsp项目的详细实战步骤

    idea中创建jsp项目的详细实战步骤

    才学javaWeb,以防自己忘记创建项目的过程,所以浅浅的记录一下吧,下面这篇文章主要给大家介绍了关于idea中创建jsp项目的详细步骤,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2022-09-09
  • win10下定时运行与开机自启动jar包的方法记录

    win10下定时运行与开机自启动jar包的方法记录

    这篇文章主要给大家介绍了关于win10下定时运行与开机自启动jar包的相关资料,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • SpringBoot Data JPA 关联表查询的方法

    SpringBoot Data JPA 关联表查询的方法

    这篇文章主要介绍了SpringBoot Data JPA 关联表查询的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • 高并发系统的限流详解及实现

    高并发系统的限流详解及实现

    这篇文章主要介绍了高并发系统的限流详解及实现,内容详细,小编觉得很不错,这里分享给大家,供需要的朋友参考。随小编一起看看吧。
    2017-11-11
  • Maven项目打包成可执行Jar文件步骤解析

    Maven项目打包成可执行Jar文件步骤解析

    这篇文章主要介绍了Maven项目如何打包成可执行Jar文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • 解决springboot中配置过滤器以及可能出现的问题

    解决springboot中配置过滤器以及可能出现的问题

    这篇文章主要介绍了解决springboot中配置过滤器以及可能出现的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • RabbitMQ 如何解决消息幂等性的问题

    RabbitMQ 如何解决消息幂等性的问题

    这篇文章主要介绍了RabbitMQ 如何解决消息幂等性的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • springcloud config配置读取优先级过程详解

    springcloud config配置读取优先级过程详解

    这篇文章主要介绍了springcloud config配置读取优先级过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Java实现枚举状态转换的方法详解

    Java实现枚举状态转换的方法详解

    在软件开发中,我们经常需要处理不同系统或模块间的状态转换,今天,我将通过一个电商订单与物流状态的转换案例,展示如何优雅地实现枚举间的互相转换,需要的朋友可以参考下
    2025-04-04

最新评论