本文摘自:http://www.51testing.com/?uid-212931-action-viewspace-itemid-109962
一、cookie和session的区别与联系。
“让我们用几个例子来描述一下cookie和session机制之间的区别与联系。笔者曾经常去的一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微乎其微,这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案:
1、该店的店员很厉害,能记住每位顾客的消费数量,只要顾客一走进咖啡店,店员就知道该怎么对待了。这种做法就是协议本身支持状态。
2、发给顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。
3、发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次消费时,如果顾客出示该卡片,则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。
由于HTTP协议是无状态的,而出于种种考虑也不希望使之成为有状态的,因此,后面两种方案就成为现实的选择。具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。 ”
二、session是如何实现。
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。既然信息是保存在服务器中,那么现在主要问题是,作为查询关键字的session id如何产生以及如何在服务器和客户端间传递呢?方法有三种:
1、使用会话cookie。这种cookie不记录在磁盘中,由浏览器记录在内存中。这是session最主要的实现方式。
2、如果客户端禁用cookie,不能使用第一种方法,则通过改写URL的方式,将session id附加在url中回传给服务器。
3、使用表单的隐藏字段。这种方法用的比较少。
三、session何时创建
“ 一个常见的误解是以为session在有客户端访问时就被创建,然而事实是直到某server端程序调用HttpServletRequest.getSession(true)这样的语句时才被创建,注意如果JSP没有显示的使用 <%@pagesession="false"%> 关闭session,则JSP文件在编译成Servlet时将会自动加上这样一条语句HttpSession session = HttpServletRequest.getSession(true);这也是JSP中隐含的session对象的来历。由于session会消耗内存资源,因此,如果不打算使用session,应该在所有的JSP中关闭它。”
四、session何时销毁
“除非程序通知服务器删除一个session,否则服务器会一直保留,程序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭,之所以会有这种错觉,是大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个session id就消失了,再次连接服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然能够找到原来的session。(因此最好session不用的话就删除它,及时释放资源,而不需要等到超时再由web容器来删除)
恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间”(Tomcat可在web.xml中配置,也可以调用session的setMaxInactiveInterval方法进行设置)
五、开两个浏览器窗口访问应用程序会使用同一个session还是不同的session?
“不同的浏览器,不同的窗口打开方式以及不同的cookie存储方式都会对这个问题的答案有影响。对于保存在内存里的cookie(session就是通过这种方式实现的),不同的浏览器有不同的处理方式。对于IE,在一个打开的窗口上按Ctrl-N(或者从文件菜单)打开的窗口可以与原窗口共享,而使用其他方式新开的IE进程则不能共享已经打开的窗口的内存cookie;对于Mozilla Firefox0.8,所有的进程和标签页都可以共享同样的cookie。一般来说是用javascript的window.open打开的窗口会与原窗口共享内存cookie。”(也就是说,如果你是使用session进行身份验证的话,你使用Maxthon浏览器在一个标签的页面中登陆成功后,在另外一个新开的标签中也就登陆成功了,因为它们共用同一个session)
六、服务器关掉后,当前session会丢掉吗?
这个取决于你使用什么样的web服务器以及web服务器是如何配置的。tomcat在shutdown前默认会自动将session保存到指定的目录中,重新启动是重新加载,因此tomcat重新启动后,session是可以继续使用的。此外,你还何以将session保存到数据库中,这个要在server.xml中配置。