当前位置:文档之家› 会话管理

会话管理

会话管理1、会话管理基本原理实现会话管理的基本方式,如隐藏域(Hidden Field)、Cookie与URL重写(URL Rewriting)的实现方式。

1.使用隐藏域隐藏域就是主动告知服务器多次请求间必要信息的方式之一。

这个方法不适合用于隐密性较高的数据。

隐藏域不是Servlet/JSP实际管理会话时的机制。

2.使用CookieCookie是在浏览器存储信息的一种方式,服务器可以响应浏览器set-cookie标头,浏览器收到这个标头与数值后,会将它以文件的形式存储在计算机上,这个文件就称之为Cookie。

一个常见的应用,自动登录。

Cookie可以设定存活期限,所以在客户端存储的信息可以活得更久一些。

Servlet本身提供了创建、设置与读取Cookie的API。

如果你要创建Cookie,可以使用Cookie类,创建时指定Cookie中的名称与数值,并使用HttpServletResponse的addCookie()方法在响应中新增Cookie。

例:Cookie cookie = new Cookie("user","caterpillar");cookie.setMaxAge(7*24*60*60);//单位是秒response.addCookie(cookie);HTTP中Cookie的设定是通过set-cookie标头,所以必须在实际响应浏览器之前使用addCookie()来新增Cookie实例,在浏览器输出HTML响应之后再运行addCookie()是没有作用的。

要取得浏览器上存储的Cookie,则可以从HttpServletRequest的getCookies()来取得,这可取得属于该网页所属域(Domain)的所有Cookie,返回值是Cookie[]数组。

取得Cookie对象后,可以使用Cookie的getName()与getV alue()方法,分别取得Cooke的名称与数值。

例:Cookie[] cookies = request.getCookies();if(cookies != null){for(Cookie cookie : cookies){String name = cookie.getName();String value = cookie.getV alue();........}}在Servlet3.0中,Cookie类新增了setHttpOnly()方法,可以将Cookie标示为仅用于HTTP,这会在set-cookie标头上附和HttpOnly属性,在浏览器支持的情况下,这个Cookie将不会被客户端脚本读取,可以使用isHttpOnly()来得知一个Cookie是否被setHttpOnly()标示为仅用于HTTP。

3.使用URL重写所谓URL重写(URL Rewriting),其实就是GET请求参数的应用,当服务器响应浏览器上一次请求时,将某些相关信息以超链接方式响应给浏览器,超链接中包括请求参数信息。

2、HttpSession会话管理即使用户关掉浏览器接收Cookie的功能,HttpSession也可以改用URL重写断续其会话管理功能。

HttpSession并非线程安全,所以必须注意属性设定时共享存取的问题。

1.使用HttpSession进行会话管理,可以使用HttpServletRequest的getSession()方法取得HttpSession对象。

getSession()方法有两个版本,另一个版本可以传入布尔值,默认是true,表示若尚未存在HttpSession实例时,直接创建一个新的对象。

若传入false,若尚未存在HttpSession实例,则直接返回null。

最常使用的方法是setAttribute()与getAttribute(),invalidate()。

例:HttpSession session = request.getSession();//取得会话session.setAttribute("name",value);//存储会话值(简写:request.getSession().setAttribute("name",value);)——————————————————————————HttpSession session = request.getSession();//取得会话session.getAttribute("name");//取得会话值Session.invalidate();//使HttpSession失效2.HttpSession会话管理原理使用HttpSession进行会话管理十分方便,让Web应用程序看似可以“记得”浏览器发出的请求,连接数个请求间的关系。

但无论如何,Web应用程序其于HTTP协议的事实并没有改变,实际上如何“得知”数个请求之间的关系,这件工作是由Web容器帮你执行。

尝试运行HttpServletRequest的getSession()时,Web容器会创建HttpSession对象,关键在于每个HttpSession对象都会有个特殊的ID,称为Session ID,你可以执行HttpSession的getId()来取得Session ID。

这个Session ID默认会使用Cookie存放在浏览器中。

在Tomcat中,Cookie的名称是JSESSIONID,数值则是getId()所取得的Session ID。

由于Web容器本身是执行于JVM中的一个Java程序,通过getSession()取得HttpSession,是Web容器中的一个Java对象,HttpSession中存放的属性,自然也就存放于服务器端的Web容器之中。

每一个HttpSession各有特殊的Session ID,当浏览器请求应用程序时,会将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失效。

默认关闭浏览器会马上失效的是浏览器上的Cookie,不是HttpSession。

因为Cookie 失效了,就无法通过Cookie来发送Session ID,所以尝试getSession()时,容器会产生新的HttpSession。

要让HttpSession立即失效必须运行invalidate()方法,否则的话,HttpSession会等到设定的失效期间过后才会被容器销毁回收。

可以执行HttpSession的setMaxInactiveInterval()方法,设定浏览器多久没有请求应用程序的话,HttpSession就自动失效,设定的单位是“秒”。

你也可以在web.xml 中设定HttpSession默认的失效时间,但要特别注意!设定的时间单位是“分钟”。

例:<web-app>......<session-config><session-timeout>30</session-timeout></session-config></web-app>在Servlet3.0中新增了SessionCookieConfig接口,可以通过ServletContext的getSessionCookieConfig()来取得实现该接口的对象,ServletContext可以通过Servlet 实例的getServletContext()来取得。

通过SessionCookieConfig实现对象,你可以设定存储Session ID的Cookie相关信息,例如可以通过setName()将默认的Session ID名称修改为别的名称,通过setAge()设定存储Session ID的Cookie存活期限等,单位是“秒”。

但是要注意的是,设定SessionCookieConfig必须在ServletContext初始化之前,所以实际上要修改Session ID、存储Session ID的Cookie存活期限等信息时,必须在Web.xml中设定。

例:<web-app>......<session-config><session-timeout>30</session-timeout><cookie-config><name>sid-caterpillar</name><http-only>true</http-only></cookie-config></session-config><web-app>另一方法是实现ServletContextListener,容器在初始化ServletContext时会调用ServletContextListener的contextInitiallized()方法,可以在其中取得ServletContext 进行SessionCookieConfig设定。

3.HttpSession与URL重写如果要使用URL重写的方式来发送Session ID,可以使用HttpServletResponse的encodeURL()协助产生所需的URL重写。

当容器尝试取得HttpSession实例时,若能从HTTP请求中取得带有Session ID的Cookie,encodeURL()会将传入的URL 原封不地输出。

如果容器尝试取得HttpSession实例时,无法从HTTP请求中取得带有Session ID的Cookie时(通常是游览器禁用Cookie的情况),encodeURL()会自动产生带有Session ID的URL重写。

如果执行encodeURL(),在浏览器第一次请求网站时,容器并不知道浏览器是否禁用Cookie,所以容器的作法是Cookie(发送set-cookie标头)与URL重写的方法,因此若Servlet有以下语句,无论浏览器有无禁用Cookie,第一次请求时,都会显示在Session ID的URL:request.getSession();Out.println(response.encodeURL("URL"));小心保管Session ID。

相关主题