Session 会话机制原理及 Tomcat 实现分析
HTTP 协议与 Cookie
HTTP 是无状态协议,客户端请求服务器,服务器回答客户端。为了区分客户端并维持状态,需要引入 Cookie 和 Session。
Cookie 原理
Cookie 分为两类:
- 会话性质:存放在浏览器内存中,未指定过期时间时不会持久化在硬盘上。
- 持久化:指定了过期时间,会生成文件存储在客户端临时文件中。
当服务器端代码写入 Cookie(如 response.cookie["mycookie"]="mytestcookie")时,HTTP 响应头中加入 Cookie 信息。浏览器收到后建立 Cookie。客户端每次 HTTP 请求都会携带该域下的所有有效 Cookie。
Session 原理
Session 依赖于会话性 Cookie。服务器端维护一张表(通常存在于进程内存中),对应客户端的 SessionID。当客户端首次请求时,服务器分配一个 SessionID 并通过 Cookie 返回给客户端。后续请求携带此 ID,服务器据此检索对应的 Session 对象。
Session 的其他实现方式
如果不依赖 Cookie,SessionID 可通过以下方式传递:
- URL 重写:将 SessionID 附加在 URL 路径或查询字符串后面(如
http://www.testwebsite.com/(-sessionID-)/test.aspx)。注意绝对路径链接可能导致会话丢失。 - 表单隐藏字段:服务器自动修改表单,添加隐藏字段传递 SessionID(较少应用)。
- GET 参数:PHP 等语言支持在 GET 参数中携带 SessionID。
Session 生命周期与结束
- 创建:调用
HttpServletRequest.getSession(true)时创建。 - 销毁:
- 程序调用
HttpSession.invalidate()。 - 超过设定的超时时间(默认通常为 30 分钟,Tomcat 默认为 60 秒配置不同)。
- 服务器进程停止且未持久化。
- 程序调用
- 关闭浏览器:仅关闭浏览器不会立即删除 Server 端 Session,除非使用会话 Cookie 且浏览器关闭导致 Cookie 丢失。若 Cookie 被保存或使用 URL 重写保留 ID,再次打开仍可恢复会话。
Tomcat 中的 Session 实现
Tomcat 通过 Manager 类管理 Session。核心流程如下:
- 查找 Session:检查请求中是否包含 SessionID(来自 Cookie 或 URL)。
if (requestedSessionId != null) { session = manager.findSession(requestedSessionId); } - 存储结构:使用
HashMap存储 Session 对象,Key 为 SessionID,Value 为 Session 实例。private HashMap attributes = new ();

