Servlet&JSP 第四章 会话管理

本文详细介绍了Servlet和JSP中的会话管理技术,包括隐藏域、Cookie、URL重写和HttpSession的使用。重点讲解了Cookie的创建、设置、读取以及HttpSession的工作原理,如何处理浏览器禁用Cookie的情况,并强调了会话管理中的安全性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、会话管理

  记得此次请求与之后请求之间关系的方式,基本方式有隐藏域、Cookie与URL重写的实现方式(必须自行处理对浏览器的响应,决定哪些信息必须送至浏览器,以便在之后的请求一并发送相关信息,供Web应用程序辨识请求间的关联)。

二、使用隐藏域

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

2、使用隐藏域的方式,在关掉网页后,会遗失先前请求的信息,所以仅适用于一些简单的状态管理,如在线问卷。由于在查看网页源代码时,就可以看到隐藏域的值,因此这个方法不适合用于隐密性较高的数据。隐藏域不是Servlet/JSP实际管理会话时的机制,由浏览器主动告知必要的信息,为实现Web应用程序会话管理的基本原理。

二、使用Cookie

  Web应用程序会话管理的基本方式,就是在此次请求中,将下一次请求时服务器应知道的信息,先响应给浏览器,由浏览器在之后的请求再一并发送给应用程序,这样应用程序就可以“得知”多次请求的相关数据。

1、Cookie是在浏览器存储信息学的一种方式,服务器可以响应浏览器set-cookie标头,浏览器收到这个标头与数值后,会将它以文件的形式存储在计算机上,这个文件就成为Cookie。可以设定给Cookie一个存活期限,保留一些有用的信息在客户端,如果关闭浏览器之后,再次打开浏览器并连接服服务器时,这些Cookie仍在有效期限之内,浏览器会使用Cookie标头自动将Cookie发送给服务器,服务器就可以得知一些先前浏览器请求的相关信息,所以在客户端存储的信息可以存活的更久一些(除非用户主动清除Cookie信息)。

2、Servlet本身提供了创建、设置与读取Cookie的API,如果要创建Cookie,可以使用Cookie类,创建时指定Cookie中的名称与数值,并使用HttpServletResponse的addCookie()方法在响应中新增Cookie。HTTP中Cookie的设定是通过set-cookie标头,所以必须在实际响应浏览器之前使用adddCookie()来新增Cookie实例,在浏览器输出HTML响应之后再运行addCookie()是没有作用的。

例1、Cookie cookie=new Cookie("user","caterpillar");
     cookie.setMaxAge(7*24*60*60);  //单位为s,所以一星期内有效。默认关闭浏览器之后Cookie就失效。
     response.addCookie(cookie);
3、如果要取得浏览器上存储的Cookie,则可以从HttpServletRequest的getCookies()方法来取得,这可以取得属于该网页所属域的所有Cookie。取得Cookie对象后,可以使用Cookie的getName()与getValue()方法,分别取得Cookie的名称与数值。

例2、Cookie[] cookies=request.getCookies();
if(cookies!=null){
for(Cookie cookie:cookies){
String name=cookie.getName();
String value=cookie.getValue();
  }
}

4、Cookie另一个常见的应用,就是实现用户自动登录功能。

5、Cookie类的setHttpOnly()方法,可以将Cookie标示为仅用于HTTP,这会在set-cookie标头上附加HttpOnly属性,在浏览器支持的情况下,这个Cookie将不会被客户端脚本读取,可以使用isHttpOnly()来得知一个Cookie是否被setHttpOnly()标示为仅用于HTTP。

三、使用URL重写

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

2、URL重写是在超链接之后附加信息的方式,所以必须以GET方式发送请求,再加上GET本身可以携带的请求参数长度有限,因此大量的客户端信息保留,并不适合使用URL重写。

四、HttpSession会话管理

可以将会话期间必须共享的数据,保存在HttpSession中成为属性,如果用户关掉浏览器接受Cookie的功能,HttpSession也可以改用URL重写继续其会话管理功能。

1、使用HttpSession

(1)在Servlet/JSP中,如果想要进行会话管理,可以使用HttpServletRequest的getSession()方法取得HttpSession对象。

例3、HttpSession session=request.getSession();
getSession()另一个版本可以传入布尔值,默认值为true,表示若尚未存在HttpSession实例时,直接创建一个新的对象;若传入false,若尚未存在HttpSession实例,则直接返回null。

(2)HttpSession最常用的两个方法:setAttribute()与getAttribute(),可以在对象中设置及取得属性。

例4、session.setAttribute("p1",p1);
     session.getAttribute("p1",p1);
(3)如果想要在浏览器与Web应用程序的会话期间,保留请求之间的相关信息,可以使用HttpSession的setAttribute()方法将相关信息设置为属性,在会话期间,就可以当作Web应用程序“记得”客户端的信息,如果想要取出这些信息,则通过HttpSession的getAttribute()就可以取出。
(4)执行HttpSession的invalidata()方法之后,容器会销毁回收HttpSession对象,如果再次通过HttpServletRequest的getSession(),取得HttpSession就是另一个新对象了。

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

2、HttpSession会话管理原理

(1)运行HttpServletRequest的getSession()时,Web容器会创建HttpSession对象,关键在于每个HttpSession对象都会有个特殊的ID,称为Session ID,可以执行HttpSession的getId()来取得Session ID。这个Session ID默认会使用Cookie存放在浏览器中。

  通过getSession()取得HttpSession,是Web容器中的一个Java对象,HttpSession中存放的属性,也就存放于服务器端的Web容器之中,每个HttpSession各有特殊的Session ID,当浏览器请求应用程序时,会将Cookie中存放的Session ID一并发送给应用程序,Web容器会根据Session ID来找出对应的HttpSession对象,这样就可以取得各个浏览器个别的会话数据。

(2)使用HttpSession来进行会话管理时,设定属性的对象是存储在服务器端,而Session ID默认使用Cookie存放于浏览器端,Web容器存储Session ID的Cookie“默认”为关闭浏览器就失效,所以重新启动浏览器请求应用程序时,通过getSession()取得的是新的HttpSession对象。

(3)每次请求来到应用程序时,容器会根据发送过来的Session ID取得对应的HttpSession,由于HttpSession对象会占用内存空间,所以HttpSession的属性中尽量不要存储耗资源的大型对象,必要时将属性移除,或者不需要使用HttpSession时,执行invalidate()让HttpSession失效。
(4)默认关闭浏览器会马上失效的是浏览器的Cookie,不是HttpSession。因为Cookie失效了,就无法通过Cookie发送Session ID,所以尝试getSession()时,容器会产生新的HttpSession,要让HttpSession立即失效必须运行invalidate()方法,否则HttpSession会等到设定的失效期间过后才会被容器销毁回收。

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

3、HttpSession与URL重写

(1)HttpSession默认使用Cookie存储Session ID,如果用户关掉浏览器接收Cookie的功能,就无法使用Cookie在浏览器存储Session ID。如果在用户禁用Cookie的情况下,仍打算运用HttpSession来进行会话管理,那么可以搭配URL重写,向浏览器响应一段超链接,超链接URL后附加Session ID,当用户单击超链接,将Session ID以GET请求发送给Web应用程序。

(2)如果要使用URL重写的方式来发送Session ID,可以使用HttpServletResponse的encodeURL()协助产生所需的URL重写。当容器尝试取得HttpSession实例时,若能从HTTP请求中取得带有Session ID的Cookie,encodeURL()会将传入的URL原封不动的输出。如果容器尝试取得HttpSession实例时,无法从HTTP请求中取得带有Session ID的Cookie时(通常是浏览器禁用Cookie的情况),encodeURL()会自动产生带有Session ID的URL重写。

(3)如果执行encodeURL(),在浏览器第一次请求网站时,容器并不知道浏览器是否禁用Cookie,所以容器的做法是Cookie(发送set-cookie标头)与URL重写的方式,因此如果Servlet有以下语句,无论浏览器有无禁用Cookie,第一次请求时,则会显示在Session ID的URL。

request.getSession();
out.println(response.encodeURL("index.jsp"));
(4)当容器尝试取得HttpSession对象时,无法从Cookie中取得Session ID,使用encodeURL()就会为产生有Session ID的URL,以便于下次单击超链接时再次发送Session ID。另一个HttpServletResponse上的encodeRedirectURL()方法,则可以在要求浏览器重定向时,在URL上显示Session ID。

(5)在HttpSession存货期间,只要有人取得当次的Session ID,在另一浏览器相同的URL附上Session ID,就可以取得同一个HttpSession对象。建议加密敏感信息,并在不使用HttpSession时执行invalidate()明确使之失效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值