
「JavaWeb学习笔记05」会话及其技术应用
¶Chapter 8. 会话技术
¶8.1 会话机制
HTTP 是无状态的协议(对于事务处理没有记忆能力),必须在 HTTP 请求中加入一些额外的用于跟踪客户状态的数据。
在 Web 开发中,会话机制,便是用于跟踪客户状态的普遍解决方案(使用 ASP、PHP 或 JSP 开发的 Web 应用都可以运用会话机制)。
会话,指在一段时间内,单个客户与 Web 应用的一连串相关的交互过程。在一个会话中,客户可能会多次请求访问 Web 应用的同一个网页,也有可能请求方法同一个 Web 应用中的多个网页。
¶8.2 Cookie
¶8.2.1 Cookie基本运作机制
Cookie,是在客户端访问 Web 服务器时,服务器在客户端硬盘上存放的信息。而服务器可根据 Cookie 来跟踪客户状态,这对于需区别客户的场合十分有用。
当客户端首次请求访问服务器时,服务器现在客户端存放包含该客户的相关信息的Cookie,以后客户端每次请求访问服务器时,都会在 HTTP 请求数据中包含 Cookie,服务器解析 HTTP 请求中的 Cookie,便能获得关于客户的少量相关信息。(在不登录的情况下,完成服务器对客户的身份识别)

Cookie 作用,就类似于健身馆向会员发送的会员卡(存储了该会员的编号、姓名等信息),以后每次客户到健身馆需出示会员卡,健身馆依据会员卡信息判断是否允许客户健身。
服务器对客户端进行读写 Cookie 操作,会给客户端带来安全隐患,服务器可能会向客户端发送包含恶意代码的 Cookie 数据,此外,服务器可能会依据客户端的 Cookie 来窃取用户的保密信息。
¶8.2.2 Cookie 相关方法
Tomcat 作为 Web 服务器,对 Cookie 提供良好支持,Java Servlet API 为 Servlet 访问 Cookie 提供简单易用的接口。
Cookie 用 javax.servlet.http.Cookie 类来表示,每个 Cookie 对象包含一个 Cookie 名字(调用 getName() 方法)及 Cookie 值(调用 getValue() 方法)。
Cookie 类的构造方法中,第一个参数为 Cookie 名字,第二个为 Cookie 值:
1
Cookie theCookie = new Cookie("username", "Luffy");调用
HttpServletResponse的方法,将 Cookie 添加到 HTTP 响应结果:1
response.addCookie(theCookie);调用
HttpServletResquest的方法,从 HTTP 请求中获取所有的 Cookie:1
Cookie cookies[] = request.getCookies();
代码演示如下:
1 | |
1 | |

¶共享问题
若 同一个Tomcat 服务器中,部署了多个 Web 应用,那么 默认情况下, Cookie 不能共享。
setPath(String path):设置 Cookie 的获取范围,默认情况下,设置当前的虚拟目录。若希望将该 Cookie 共享,则可将path设置为"/"(Tomcat 服务器根路径)
1
2
3
4
5
6//1. 创建Cookie对象
Cookie c = new Cookie("msg", "secret"); //传入的字符串尽量不要含空白符
//2. 设置path,让当前服务器下部署的所有项目均能够共享Cookie
c.setPath("/");
//3. 发送Cookie
response.addCookie(c);对于 不同的 Tomcat 服务器
setDomain(String path):若设置一级域名相同,则可以实现多个特定服务器间的 Cookie 共享,如:(注意,参数path必须以.开头)
1
2cookie.setDomain(".baidu.com");
//此时,tieba.baidu.com和news.baidu.com中可共享该Cookie
¶细节问题
- 能够创建多个 Cookie 对象,多次调用
addCookie()方法发送 Cookie 即可 - Cookie 若要存储 中文数据、特殊字符,应使用 URL 编码存储。读取 Cookie 时,再解码解析信息
¶8.2.3 Cookie 有效期
当 Servlet 向客户端写 Cookie 时,还可通过 Cookie 类的 setMaxAge(int expiry) 方法来设置 Cookie 的有效期。
传入参数 expiry 以秒为单位,它的值具有以下含义:
- 正数:指示浏览器在客户端硬盘上保存 Cookie 的时间为
expiry - 零:指示浏览器删除当前 Cookie
- 负数(默认值):指示浏览器不要把 Cookie 保存到客户端硬盘,Cookie 仅仅存在于 当前浏览器进程 中,当浏览器进程关闭,Cookie 也消失。
1 | |
¶8.2.4 案例演示:记忆上次访问时间
需求:
访问一个 Servlet ,若是首次访问,则提示:您好,欢迎您首次访问;若非首次访问,则提示:欢迎回来,您上次访问时间为:yyyy年MM月dd日 HH:mm:ss
此处只给出 Servlet 的代码:
1 | |
¶8.3 Session
¶8.3.1 会话的运作机制
Servlet 规范指定了基于 Java 的会话的具体运作机制,在 Servlet API 中定义了代表会话的 javax.servlet.http.HttpSession 接口,Servlet 容器必须实现这一接口。
会话的运作流程如下:

- 一个浏览器进程第一次请求访问某个 Web 应用中的任意一个支持会话的网页,Servlet 容器试图寻找 HTTP 请求中表示 Session ID 的 Cookie 。但由于还不存在该 Cookie,故认为一个新的会话开始,于是创建了一个
HttpSession对象,为它分配唯一的Session ID ,并将 Session ID 作为 Cookie 添加到 HTTP 响应结果中。 - 当浏览器接收到 HTTP 响应结果后,会把其中表示 Session ID 的 Cookie 保存到客户端
- 浏览器进程继续请求访问 刚刚 Web 应用中的任意一个支持会话的网页,在本次 HTTP 请求中会包含表示 Session ID 的Cookie。Servlet 容器同时也成功寻找了该 Cookie,于是认为本次请求已经处于一个会话了,故不再创建新的
HttpServlet对象,而是从 Cookie 中获取 Session ID,并根据其找到内存中对应的HttpServlet对象 - 浏览器进程重复步骤3,直到当前会话被销毁,
HttpServlet对象就会结束生命周期。
简而言之,Session 是基于 Cookie 实现的,Session 存储在 服务器端,而 Session ID 会被存储到客户端的 Cookie 中
¶8.3.2 HttpSession 相关方法
- 获取
HttpSession对象:
1 | |
HttpSession 接口的以下方法用于向会话范围内存取共享数据:
- 返回会话范围内与参数
name匹配的共享数据:Object getAttribute(String name) - 向会话范围内存放共享数据:
void setAttribute(String name, Object value) - 删除会话范围内的一个共享数据:
void removeAttribute(String name)
¶8.3.4 HttpSession 的生命周期
以下情况,会开始一个新的会话,即 Servlet 容器会创建一个新的 HttpSession 对象:
- 一个浏览器进程第一次访问 Web 应用中的支持会话的任意一个网页;
- 当浏览器进程与 Web 应用的一次会话已经被销毁后,浏览器进程再次访问 Web 应用中的支持会话的任意一个网页。
以下情况,会话被销毁,即 Servlet 容器使得 HttpSession 对象结束生命周期,并且存放在会话范围内的共享数据也都被销毁:
浏览器进程被终止;
当会话开始后,若浏览器进程突然关闭,Servlet 容器端无法立即执照浏览器进程已经被关闭,故 Servlet 容器端的
HttpSession对象不会立即结束生命周期,该对话进入不活动状态,等到超过了setMaxInactiveInterval(int interval)设置的时间,会话就会过期而被 Servlet 容器销毁。服务器端执行
HttpSession对象的invalidate()方法;当 Tomcat 中的 Web 应用被终止时,它的会话不会被销毁,而是被 Tomcat 持久化到永久性存储设备中,当 Web 应用重启时,Tomcat 会重新加载这些会话。
会话过期:当会话开始后,若一段时间内,客户一直没有和 Web 应用交互,即一直没有请求访问 Web 应用中的支持会话的任意一个网页,那么 Servlet 容器会自动销毁这个会话。
HttpSession类的setMaxInactiveInterval(int interval)方法,用于设置允许会话保持不活动状态的时间(以秒为单位)
¶8.3.5 Cookie 与 Session 的区别
| Cookie | Session | |
|---|---|---|
| 安全性 | 存储在客户端 | 存储在服务器端, 更加安全 |
| 存值类型 | 只支持字符串数据, 其他类型数据需转换为字符串 | 存任意数据类型 |
| 有效期 | 长时间保持 (如默认登陆) | 短时间 |
| 存储大小 | 单个 Cookie 不超过 4K | 比 Cookie 高 |
¶8.3.6 案例演示:验证码与页面跳转
需求:
- 带有验证码的登陆页面
login.jsp - 用户输入用户名、密码及验证码后:
- 若用户名和密码输入有误,跳转到登陆页面,并提示:用户名或密码错误
- 若验证码输入有误,跳转登陆页面,提示:验证码错误
- 若全部输入正确,跳转到主页
success.jsp,提示:用户名,欢迎您
此处只给出了 LoginServlet 代码:
1 | |