服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|编程技术|正则表达式|C/C++|

服务器之家 - 编程语言 - JAVA教程 - servlet之session工作原理简介_动力节点Java学院整理

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

2020-12-07 11:10fjdingsd JAVA教程

这篇文章主要介绍了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代码为:

?
1
2
3
httpsession session = request.getsession();
string data = "message from sessiondemo";
session.setattribute("data", data);

在sessiondemo2代码为:

?
1
2
httpsession session = request.getsession();
system.out.println((string)session.getattribute("data"));

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

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

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

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

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

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

1,覆盖有效时间:

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

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

当然我们从这里也可以修改服务器默认的销毁无操作的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的有效路径:

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

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

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

?
1
2
3
4
5
6
7
8
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:

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

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

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

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

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

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

延伸 · 阅读

精彩推荐