在上一篇中我们学习了Session对象默认在一个会话过程中,由服务器创建,能保存在这个会话过程中用户访问多个web资源时产生的需要保存的数据,并在访问服务器中其他web资源时可以将这些数据从Session中取出并为之使用。

  然而在一个会话过程后就将无法再取到Session对象(因为cookie不存在了,原因下面将阐明),可能导致的是用户误将浏览器关闭而使保存在Session中的数据无法再取到,因此如果我们能将多个会话同时使用同一个Session对象就能满足用户“刁蛮”的需求。

  在前一篇的最开始就说过,在默认情况下,一个浏览器独享一个Session。请注意,这里是默认情况下, 而我们有了新需求,就要打破默认情况(比如默认情况下Cookie也是在一个会话结束后消失,但是我们设置了setMaxAge后就能在硬盘中生存),做到多个浏览器共享一个Session,同时这也意味着一台用户主机有一个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,具体请看《Servlet的学习之Session(3)》。)

  我们可以通过下面这个动图来看一看:

  

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

在SessionDemo1代码为:

     HttpSession session = request.getSession();
String data = "Message from SessionDemo1";
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,覆盖有效路径:

  我们在《Servlet的学习之Cookie》中知道,如果我们创建一个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 SessionDemo1";
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来获取之前保存的数据。

Servlet的学习之Session(2)的更多相关文章

  1. Servlet的学习之Session(3)

    在上一篇<Servlet的学习之Session(2)>我们知道了Session能实现一个会话过程中保存数据或者多个会话中实现同一个Session的关键因素就是Cookie,只是Cookie ...

  2. Servlet的学习之Session(1)

    在学习完了Servlet中的Cookie技术后,我们再来学习另一个能保存会话数据的技术——Session. Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其 ...

  3. Servlet的学习之Session(4)

    在本篇中,我们来使用Session完成一个用户登录的案例,前提声明:这个案例主要用于学习Session技术,是属于比较简单的类型,以后会采用MVC模式来开发登录,那就会比较复杂. 现在大多数网站都提供 ...

  4. Servlet的学习之Session(5)

    在上一篇中我们介绍了如果使用Session来做一个简单的用户登录案例,在本篇中我们继续使用Session技术来做一个防止表单重复提交的案例. 这是一个很重要的知识点,在很多框架中都有防止表单重复提交的 ...

  5. JavaWeb之Servlet:Cookie 和 Session

    会话 现实生活中我们会用手机跟对方对话,拿起手机,拨号,然后对面接听,跟着互相通话,最后会话结束. 这个过程也可以用我们的B/S模式来描述: 打开浏览器—>输入地址->发出请求->服 ...

  6. Servlet的学习之Cookie

    从本篇开始学习Servlet技术中的Cookie专题. 首先来了解什么是“会话”.会话是web技术中的一个术语,可以简单的理解为:用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭 ...

  7. Servlet的学习之Filter过滤器技术(1)

    本篇将讲诉Servlet中一项非常重要的技术,Filter过滤器技术.通过过滤器,可以对来自客户端的请求进行拦截,进行预处理或者对最终响应给客户端的数据进行处理后再输出. 要想使用Filter过滤器, ...

  8. Servlet的学习(四)

    在本篇的Servlet的学习中,主要来学习由使用MyEclipse来开发Servlet的一些小细节. 细节一:在web.xml中可以对同一个Servlet配置多个对外访问路径,并如果在web.xml中 ...

  9. Servlet的学习之Request请求对象(3)

    本篇接上一篇,将Servlet中的HttpServletRequest对象获取RequestDispatcher对象后能进行的[转发]forward功能和[包含]include功能介绍完. 首先来看R ...

随机推荐

  1. 兼容性问题( css)

    记录平时遇见的兼容性问题,有更好的解决办法希望各位提出,会持续更新 提出时间 问题描述 解决方案 2014/7/15 table下面使用img或者其他元素例如embed会产生,对应的空隙,假如使用文字 ...

  2. 用Verilog实现IIC通讯

    注意,此代码是错误代码,并不能实现想要的结果. 之所以留着,因为里面的enable 是独立开来的思想值得借鉴.就是控制单元和运算单元分开(我也是借鉴别人的实现思想).具体用verilogHDL实现II ...

  3. atlas z 轴

    问题源自一个帖子,因为上传的图比较多,就另开了这个贴写下自己的试验结果,原帖在下面链接中 http://game.ceeger.com/forum/read.php?tid=8911#info NGU ...

  4. linux 远程桌面工具NX

    1.在linux服务器上需要安装3个文件,下载地址为: http://www.nomachine.com/download-package.php?Prod_Id=1977 nxclient-3.4. ...

  5. Pison geeker

    Pison on scriptogr.am Pison Abraham Lincoln: "Nearly all men can stand adversity, but if you wa ...

  6. oracle scn浅析

    1. 系统SCN号 查询系统SCN号的方法: select dbms_flashback.get_system_change_number from dual commit后系统SCN号会增长,但是即 ...

  7. Aizu 1335 Eequal sum sets

    Let us consider sets of positive integers less than or equal to n. Note that all elements of a set a ...

  8. 设置VIM的配色方案

    [转]Ubuntu的VIM的默认颜色难看死了,蓝色的注释基本上看不到. 查看有多少配色方案: $ ls /usr/share/vim/vim72/colors  发现有以下文件 blue.vim    ...

  9. javascript获取页面各种高度

    网页可见区域宽: document.body.clientWidth网页可见区域高: document.body.clientHeight网页可见区域宽: document.body.offsetWi ...

  10. 旧版本mysql下载大全,爽~~

    http://mirror.cogentco.com/pub/mysql/MySQL-4.1/ http://mirror.cogentco.com/pub/mysql/MySQL-5.0/ http ...