会话管理的基本原理
Web应用程序中有些功能需要多次请求才能完成,所以需要某些方式来记得此次请求与之后请求之间的关系,这类方式称之为会话管理.
会话管理的基本方式有:隐藏域(Hidden Field),Cookie,URL重写等
使用隐藏域
在HTTP协议中,服务器并没有记忆功能,那么可以让浏览器在每次请求时"主动告知"服务器多次请求间的必要信息,服务器只需单纯处理请求中的信息就好.
隐藏域就是主动告知服务器多次请求间必要信息的方式之一.
使用隐藏域的缺点:
关掉网页后会丢失之前的信息,仅适合简单的状态管理,查看网页源码可以看到隐藏的信息,不适合用于隐秘性较高的数据.
隐藏域不是Servlet/JSP实际管理会话时的机制,实现Web应用程序会话的基本原理是由浏览器主动告知必要的信息.
使用 Cookie
Cookie 是在浏览器存储信息的一种方式,服务器可以响应浏览器 set-cookie 标头,浏览器收到标头与数值后会以文件的形式存储在计算机上,即 Cookie.
Cookie 可以设置存活期限.
Servlet可以通过Cookie
类的getMaxAge()
方法获取Cookie的有效期;
Servlet可以通过设置Cookie
类的setMaxAge( int expiry );
//expiry默认值为 -1;
1.如果expiry大于0,则保存有效期为expire时间长度,单位毫秒;
2.如果expiry等于0,则指示浏览器删除当前cookie;
3.如果expiry小于0,则指示浏览器不保存该cookie到硬盘,就保存在内存中,浏览器关闭就消失;
创建Cookie:
1 | Cookie cookie = new Cookie("user", "caterpillar"); |
获取Cookie
1 | Cookie[] cookies = request.getCookies(); |
Servlet 3.0 中,Cookie
增加了setHttpOnly()
方法,将Cookie标示为仅用于HTTP,如果浏览器支持,这个Cookie不会被客户端脚本读取,可以用isHttpOnly()
方法判断是否被标示
使用 URL 重写
URL重写就是GET请求参数的应用,当服务器响应浏览器的上一次请求时,将某些相关信息以超链接的方式响应给浏览器,超链接包括请求参数信息.
由于URL重写是在超链接之后附加信息,所以必须以GET方式发送请求.
通常URL重写是用在一些简单的客户端信息保留,或者辅助会话管理.
HttpSession 会话管理
Servlet/JSP中会话管理的机制:HttpSession
使用 HttpSession
获得HttpSession
实例:
1 | HttpSession session = request.getSession(); |
默认在浏览器关闭前,HttpSession
都是相同的实例,如果想要让目前的HttpSession
失效可以调用HttpSession
的invalidate()
方法,执行这个方法后,容器会销毁回收HttpSession
对象,再调用getSession()
取得的对象是另一个新对象.
设置与获得属性:
setAttribute()
:设置属性getAttribute()
:获得属性
HttpSession
不是线程安全,需要注意属性设定的共享存取问题
HttpSession 会话管理原理
尝试运行HttpSession
的getSession()
方法时,Web容器会创建HttpSession
对象,每个对象都有一个特殊的ID: Session ID,可以用HttpSession
的getId()
来取得Session ID,ID默认使用Cookie存储在浏览器中.
HttpSession
中存放的属性也存放在服务端的Web容器里,当浏览器请求应用程序时,会将Cookie中的Session ID 一同发送给应用程序里,Web容器会根据得到的ID找到对应的Session对象,这样就可以取得各浏览器的各自的会话数据.
Web容器存储Session ID的Cookie默认设置当浏览器被关闭就失效,浏览器重新启动后由于ID失效,尝试getSession()
后,容器会产生新的HttpSession
对象,如果不使用invalidate()
使对象立即失效,对象会等到设定的失效期间过后才会被销毁回收.
设置HttpSession
对象失效时间的方法:
调用该对象的
setMaxInactiveInterval()
方法,设定浏览器多久没请求应用程序的话就自动失效,单位为秒;也可以在web.xml中修改,设定的单位是分钟
1
2
3
4
5
6<web-app...>
...
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>
HttpSession
的属性中尽量不要存储耗资源的对象,必要时将属性移除(public void removeAttribute(String name)
),或者让其失效.
Servlet 3.0 中新增了SessonCookieConfig
接口,可以通过ServleContext
的getSessionCookieConfig()
取得该接口的对象,通过这个接口的实现对象可以设定存储Session ID的Cookie相关的信息,设定必须在ServletContext
初始化之前
- 在web.xml中设定
- 实现
ServletContextListener
HttpSession 与 URL 重写
因为HttpSession
默认使用Cookie来存储ID,如果浏览器禁用Cookie,还想使用HttpSession
来进行会话管理的话,可以搭配URL重写,向浏览器响应一段超链接,超链接URL附加上Session ID,单击超链接后将Session ID以GET请求发送给Web应用程序.
如果要使用URL重写的方式发送Session ID,可以使用HttpServletResponse
的encodeURL()
协助产生需要的URL,如果Cookie可用,将URL本身输出,如果不可以会自动产生带有Session ID的URL重写.