使用HttpSession进行会话管理十分方便,让Web应用程序看似可以“记得”浏览器发出的请求,连接数个请求间的关系。但是无论如何,Web应用程序基于HTTP协议的事实并没有改变,实际上如何“取得”数个请求间的关系,这件工作是由Web容器帮你执行。
当运行HttpServletRequest的getSession()时,Web容器会创建HttpSession对象,每个HttpSession对象都会有一个特殊ID,称为Session ID,其值可以通过HttpSession对象的getId()取得,Session ID默认使用Cookie存放在浏览器。在Tomcat中,Cookie的名称是JSESSIONID,数值则是getId()所取得的SessionID
由于Web容器本身是执行于JVM中的一个java程序,通过getSession()取得HttpSession,是Web容器中的一个java对象,HttpSession中存放的属性,自然也就存放于服务端的Web容器之中。当浏览器请求应用程序时,会将cookie中存放的Session ID一并发给应用程序,Web容器会根据Session ID来找到对应的HttpSession对象,这样就可以取得个浏览器个别的会话数据,如图所示。
所以使用HttpSession来进行会话管理时,设定为属性的对象时存储在服务器端,而Session ID默认使用的Cookie存放于浏览器端。Web容器存储Session ID的Cookie“默认”为关闭浏览器就失效,所以重新启动浏览器请求应用程序时,通过getSession()取得的是新的HttpSession对象。
每次请求来到应用程序,容器会根据发送过来的Session ID取得对应的HttpSession。由于HttpSession对象会占用内存空间,所以HttpSession的属性中尽量不要存储耗资源的大型对象,必要时将属性移除,或者不需使用HttpSession时,执行invalidate()让HttpSession失效。