由于HTTP是一种无状态协议,当客户端的一次访问请求结束后,服务器无法知道下次来访问的还是不是上次访问的客户端。
Cookie与Session的作用都是保持客户端与服务器的交互状态。但是它们的优点和它们的使用场景是矛盾的。当使用Cookie来传递信息时,随着访问量的增加,Cookie个数越来越多,它占用的网络带宽会很大。面对大访问量的情况,可以用Session,但是Session的致命弱点是不容易在多台服务器之间共享,这限制了Session的使用。
理解Cookie
Cookie是HTTP头中的一个字段。当客户端通过HTTP访问服务端时,服务端会将一些Key/Value键值对返回给客户端,并加上一些限制条件,在条件符合后该客户端再次访问服务端时,数据又被完整地带回给服务端。也就是说,当请求某个URL路径时,浏览器会根据这个URL路径将符合条件的Cookie放在Request请求头中传回给服务端,服务端通过request对象的getCookies方法来取得所有Cookie。‘
Cookie存储在浏览器里,不同的浏览器对Cookie的存储在大小和数量方面有一些限制。
理解Session
同一个客户端每次和服务端交互时,不需要传回所有的Cookie值,只需传回一个SessionID。这个SessionID是客户端第一次访问服务端时生成的,对于每个客户端而言是唯一的,通常是NANE为JSESIONID的一个Cookie。
有了SessionID,服务端就可以创建HttpSession对象了,第一次触发是通过request对象的getSession方法。
有3种方式可以让Session正常工作:
1 基于URL路径参数,默认支持。
2 基于Cookie,默认支持。
3 基于SSL,默认不支持,只有connector.getAttribute("SSLEnabled")为TRUE时才支持。
每个Session对象都有一个有效时间,超过这个时间后Session对象会被清除。在Tomcat中这个有效时间是60s(通过maxInactiveInterval属性控制)。检查Session是否失效是在Tomcat的一个后台线程(backgroundProcess方法中)中完成的。同时,调用request对象的getSession方法时也会检查该Session是否过期,如果Session过期了则会创建新的Session对象。如果不想自动创建Session对象,可以通过request.getSession(boolean create)方法来判断Session是否过期。
Cookie安全问题
Cookie与Session工作方式不同。Cookie把数据通过HTTP头部从客户端传递给服务端,又从服务端传回给客户端,最终数据都存储在客户端的浏览器里,所以这些Cookie数据可以被访问,通过插件可以修改Cookie,因此Cookie是不安全的。而Session是将数据保存在服务端,只是通过Cookie传递一个SessionID,所以Session适合存储隐私数据。
参考资料
《深入分析Java Web技术内幕》 P263-274