HttpSession 的运行原理(基于 Java Web)
HttpSession
是 Java Web 开发中用于在服务器端存储用户会话数据的机制,它的核心作用是跟踪用户状态(如登录信息、购物车数据等)。
1. HttpSession 的基本概念
-
会话(Session):指用户从访问网站到关闭浏览器(或超时)期间的一系列交互过程。
-
Session ID :服务器为每个会话分配的唯一标识符(通常是一个
JSESSIONID
Cookie)。 -
存储位置 :Session 数据默认存储在 服务器内存 中(Tomcat/Jetty等),也可以配置到 Redis、数据库等。
2. HttpSession 的工作流程
(1)创建 Session
当客户端(浏览器)第一次访问服务器时:
-
服务器检查请求是否携带
JSESSIONID
Cookie。 -
如果没有,则创建一个新的 Session,并生成唯一的
JSESSIONID
-
服务器在响应头中返回
Set-Cookie: JSESSIONID=xxx
,浏览器保存该 Cookie。
(2)后续请求携带 Session ID
浏览器在后续请求中会自动带上 JSESSIONID
Cookie:
html
GET /home HTTP/1.1
Cookie: JSESSIONID=abc123
服务器根据 JSESSIONID
找到对应的 Session,并读取/写入数据。
(3)相关配置
在一些前后端分离的项目中,涉及跨域问题,这时如果想让会话携带Cookie等凭证,那么需要配置: withCredentials: true。withCredentials可以控制请求是否携带Cookie等凭证,同样的后端也需要设置。
前端代码实例:
html
fetch('http://api.example.com/login', {
method: 'POST',
credentials: 'include', // 等效于 withCredentials: true
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'user', password: 'pass' })
});
后端代码:
java
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: <具体域名>
注意前后端都需要配置,否则也会报错
(3)Session 失效
Session 会在以下情况被销毁:
-
超时 :
session.setMaxInactiveInterval(1800)
(30分钟无活动则失效)。 -
主动销毁 :调用
session.invalidate()
。 -
服务器重启(如果 Session 未持久化到外部存储)。
3. HttpSession 的核心 API
方法 | 说明 |
---|---|
request.getSession() |
获取 Session(如果没有则创建) |
request.getSession(false) |
获取 Session(如果没有则返回 null ) |
session.getId() |
获取 Session ID |
session.setAttribute("key", value) |
存储数据 |
session.getAttribute("key") |
读取数据 |
session.removeAttribute("key") |
删除数据 |
session.invalidate() |
销毁 Session |
session.setMaxInactiveInterval(seconds) |
设置超时时间(秒) |
4. HttpSession 的底层实现
(1)Session 存储方式
-
默认 :存储在 服务器内存 (Tomcat 使用
ConcurrentHashMap
)。 -
分布式环境 :使用 Redis 、数据库 或 Session 复制(如 Spring Session)。
(2)Session ID 的传递方式
-
Cookie(默认):
htmlSet-Cookie: JSESSIONID=abc123; Path=/; HttpOnly
-
URL 重写(禁用 Cookie 时):
html<a href="/home;jsessionid=abc123">Home</a>
5. 代码示例
(1)存储 Session 数据
java
@GetMapping("/login")
public String login(HttpServletRequest request) {
HttpSession session = request.getSession(); // 获取或创建 Session
session.setAttribute("user", "张三"); // 存储数据
session.setMaxInactiveInterval(1800); // 设置30分钟超时
return "登录成功";
}
(2)读取 Session 数据
java
@GetMapping("/profile")
public String profile(HttpServletRequest request) {
HttpSession session = request.getSession(false); // 不自动创建 Session
if (session == null) {
return "未登录";
}
String user = (String) session.getAttribute("user");
return "当前用户: " + user;
}
(3)销毁 Session(退出登录)
java
@GetMapping("/logout")
public String logout(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate(); // 销毁 Session
}
return "已退出登录";
}
6. 常见问题
(1)Session 和 Cookie 的区别
Session | Cookie | |
---|---|---|
存储位置 | 服务器 | 浏览器 |
安全性 | 较高(数据在服务端) | 较低(可能被篡改) |
存储大小 | 较大(依赖服务器内存) | 较小(一般 ≤4KB) |
生命周期 | 可设置超时时间 | 可设置过期时间 |
(2)如何防止 Session 劫持?
-
使用 HTTPS 加密传输
JSESSIONID
。 -
设置
HttpOnly
和Secure
标志,防止 XSS 攻击:java// Spring Boot 配置(application.properties) server.servlet.session.cookie.http-only=true server.servlet.session.cookie.secure=true
7. 总结
-
HttpSession 用于在服务器端存储用户会话数据 ,依赖
JSESSIONID
标识用户。 -
默认存储在内存,分布式环境可用 Redis 共享 Session。
-
核心操作 :
setAttribute()
、getAttribute()
、invalidate()
。 -
安全建议 :使用
HttpOnly
+Secure
Cookie,避免 Session 劫持。