关于session与cookie区别
cookie机制和session机制的区别
具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于在服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上还有其他选择。
会话cookie和持久cookie的区别
如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。
如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。有可能共享有可能不共享。
session在不同环境下的不同含义
session,中文经常翻译为会话,其本来的含义是指有始有终的一系列动作/消息,比如打电话是从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个session。
然而当session一词与网络协议相关联时,它又往往隐含了“面向连接”和/或“保持状态”这样两个含义。
session在Web开发环境下的语义又有了新的扩展,它的含义是指一类用来在客户端与服务器端之间保持状态的解决方案。有时候Session也用来指这种解决方案的存储结构。
session的机制
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
但程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否包含了一个session标识-称为sessionid,如果已经包含一个sessionid则说明以前已经为此客户创建过session,服务器就按照sessionid把这个session检索出来使用(如果检索不到,可能会新建一个,这种情况可能出现在服务端已经删除了该用户对应的session对象,但用户人为地在请求的URL后面附加上一个JSESSION的参数,以后将使用新的sessionId)。
如果客户请求不包含sessionid,则为此客户创建一个session并且生成一个与此session相关联的sessionid,这个sessionid将在本次响应中返回给客户端保存。
保存sessionid的几种方式
A.保存sessionid的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。
B.由于cookie可以被人为的禁止,必须有其它的机制以便在cookie被禁止时仍然能够把sessionid传递回服务器,经常采用的一种技术叫做URL重写,就是把sessionid附加在URL路径的后面,附加的方式也有两种,一种是作为URL路径的附加信息(不在URL上体现),另一种是作为查询字符串附加在URL后面。网络在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个sessionid。
C.另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把sessionid传递回服务器。
session什么时候被创建
一个常见的错误是以为session在有客户端访问时就被创建,然而事实是直到某server端程序(如Servlet)调用HttpServletRequest.getSession(true)这样的语句时才会被创建。
session何时被删除
session在下列情况下被删除:
A.程序调用HttpSession.invalidate()
B.距离上一次收到客户端发送的sessionid时间间隔超过了session的最大有效时间,默认30分钟,可以在web.xml中配置这个有效时间
C.服务器进程被停止
再次注意关闭浏览器只会使存储在客户端浏览器内存中的sessioncookie失效,不会使服务器端的session对象失效。只要用户的下次请求中包含正确的sessionid,session还是可以被正确使用。
getSession()/getSession(true)、getSession(false)的区别
getSession()/getSession(true):当session存在时返回该session,否则新建一个session并返回该对象
getSession(false):当session存在时返回该session,否则不会新建session,返回null
如何将信息与会话关联起来
setAttribute会替换任何之前设定的值;如果想要在不提供任何代替的情况下移除某个值,则应使用removeAttribute。这个方法会触发所有实现了HttpSessionBindingListener接口的值的valueUnbound方法。
如何废弃会话数据
A.只移除自己创建的数据:
调用removeAttribute(“key”)将指定键关联的值废弃
B.删除整个会话(在当前Web应用中):
调用invalidate,将整个会话废弃掉。这样做会丢失该用户的所有会话数据,而非仅仅由我们servlet或JSP页面创建的会话数据
使用isNew来判断用户是否为新旧用户的错误做法
publicbooleanisNew()方法如果会话尚未和客户程序(浏览器)发生任何联系,则这个方法返回true,这一般是因为会话是新建的,不是由输入的客户请求所引起的。
但如果isNew返回false,只不过是说明他之前曾经访问该Web应用,并不代表他们曾访问过我们的servlet或JSP页面。
因为session是与用户相关的,在用户之前访问的每一个页面都有可能创建了会话。因此isNew为false只能说用户之前访问过该Web应用,session可以是当前页面创建,也可能是由用户之前访问过的页面创建的。
正确的做法是判断某个session中是否存在某个特定的key且其value是否正确
Cookie的过期和Session的超时有什么区别
会话的超时由服务器来维护,它不同于Cookie的失效日期。首先,会话一般基于驻留内存的cookie不是持续性的cookie,因而也就没有截至日期。即使截取到JSESSIONIDcookie,并为它设定一个失效日期发送出去。浏览器会话和服务器会话也会截然不同。
sessioncookie和session对象的生命周期是一样的吗
当用户关闭了浏览器虽然sessioncookie已经消失,但session对象仍然保存在服务器端
是否只要关闭浏览器,session就消失了
程序一般都是在用户做logoff的时候发个指令去删除session,然而浏览器从来不会主动在关闭之前通知服务器它将要被关闭,因此服务器根本不会有机会知道浏览器已经关闭。服务器会一直保留这个会话对象直到它处于非活动状态超过设定的间隔为止。
之所以会有这种错误的认识,是因为大部分session机制都使用会话cookie来保存sessionid,而关闭浏览器后这个sessionid就消失了,再次连接到服务器时也就无法找到原来的session。
如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求报头,把原来的sessionid发送到服务器,则再次打开浏览器仍然能够找到原来的session。
恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为session设置了一个失效时间,当距离客户上一次使用session的时间超过了这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。
由此我们可以得出如下结论:
关闭浏览器,只会是浏览器端内存里的sessioncookie消失,但不会使保存在服务器端的session对象消失,同样也不会使已经保存到硬盘上的持久化cookie消失。
打开两个浏览器窗口访问应用程序会使用同一个session还是不同的session
通常sessioncookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的sessionid,这样我们信息共享的目的就达不到了。
此时我们可以先把sessionid保存在persistentcookie中(通过设置session的最大有效时间),然后在新窗口中读出来,就可以得到上一个窗口的sessionid了,这样通过sessioncookie和persistentcookie的结合我们就可以实现了跨窗口的会话跟踪。
不可更改对象和可更改对象在会话数据更新时的不同处理
不可更改对象因为一旦创建之后就不能更改,所以每次要修改会话中属性的值的时候,都需要调用setAttribute(“someIdentifier”,newValue)来代替原有的属性的值,否则属性的值不会被更新;
可更改对象因为其自身一般提供了修改自身属性的方法,所以每次要修改会话中属性的值的时候,只要调用该可更改对象的相关修改自身属性的方法就可以了。这意味着我们就不需要调用setAttribute方法了。