什么是 Session?
Session(会话) 是一种在 Web 服务器上记录用户状态的技术,它的工作原理如下:

- 用户访问:当一个用户首次访问一个网站时,服务器会为其创建一个独一无二的 Session 对象。
- 分配 ID:服务器会给这个 Session 对象分配一个唯一的 ID,称为
SessionID。 - 传递 ID:服务器通过一个名为
JSESSIONID的 Cookie 将这个SessionID发送给客户端的浏览器,并保存在浏览器中。 - 后续请求:当该用户再次访问同一个网站的任何页面时,浏览器会自动携带这个
JSESSIONIDCookie。 - 服务器识别:服务器接收到请求后,会读取
JSESSIONID,然后根据这个 ID 找到之前为该用户创建的 Session 对象,从而实现跨页面的状态保持。
Session 就像一个服务器端的“购物车”,每个用户都有自己的专属购物车,通过 SessionID 这个“钥匙”来打开自己的购物车。
如何在 Java 中存取 Session?(Servlet API)
在标准的 Java Web 开发中(使用 Servlet),我们可以通过 HttpServletRequest 和 HttpSession 对象来操作 Session。
获取 Session 对象
在 Servlet 的 doGet 或 doPost 方法中,通过 request.getSession() 方法来获取当前用户的 Session 对象。
request.getSession(): 如果当前请求没有关联的 Session,此方法会创建一个新的 Session并返回,这是最常用的方式。request.getSession(false): 如果当前请求没有关联的 Session,此方法不会创建新的 Session,而是返回null,当你只想在有 Session 的情况下操作时,可以使用这个方法。
// 在 Servlet 的 service 方法中
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取 Session,如果不存在则创建一个新的
HttpSession session = request.getSession();
// 或者:如果不存在则不创建,返回 null
// HttpSession session = request.getSession(false);
}
向 Session 中存入数据(setAttribute)
获取到 HttpSession 对象后,我们可以使用 setAttribute(String name, Object value) 方法来存入数据。

name: 一个字符串,作为数据的键。value: 一个 Java 对象,作为值,注意:Session 中存储的对象必须是可序列化的(implements Serializable),因为服务器可能会在内存不足时将其序列化到硬盘上。
示例:
假设我们有一个登录功能,登录成功后将用户信息存入 Session。
// LoginServlet.java
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
// 假设验证成功
if ("admin".equals(username) && "password".equals(password)) {
// 1. 获取 Session
HttpSession session = request.getSession();
// 2. 创建一个用户对象 (假设 User 类已定义)
User user = new User(username, "admin@example.com");
// 3. 将用户对象存入 Session
// 键为 "user",值为 user 对象
session.setAttribute("user", user);
// 也可以存入简单的字符串
session.setAttribute("loginTime", new Date().toString());
// 重定向到主页
response.sendRedirect("home.jsp");
} else {
// 登录失败,返回登录页面
response.sendRedirect("login.jsp?error=1");
}
}
从 Session 中读取数据(getAttribute)
使用 getAttribute(String name) 方法可以从 Session 中读取数据。
name: 你之前存入数据时使用的键。- 返回值:
Object类型,你需要将其强制类型转换为你当初存入时的对象类型。 - 注意:如果指定的键不存在,此方法会返回
null,而不是抛出异常。
示例:

在主页 home.jsp 或另一个 Servlet 中获取并显示用户信息。
// HomeServlet.java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取 Session
HttpSession session = request.getSession();
// 2. 从 Session 中获取用户对象
// 需要将 Object 强制转换为 User 类型
User user = (User) session.getAttribute("user");
// 3. 判断 user 是否为 null(即用户是否已登录)
if (user != null) {
// 用户已登录,显示欢迎信息
request.setAttribute("welcomeMsg", "欢迎, " + user.getUsername() + "!");
request.getRequestDispatcher("/home.jsp").forward(request, response);
} else {
// 用户未登录,重定向到登录页面
response.sendRedirect("login.jsp");
}
}
从 Session 中移除数据(removeAttribute)
当用户注销或者某些数据不再需要时,应该及时从 Session 中移除,以节省服务器内存。
使用 removeAttribute(String name) 方法。
示例:
在注销 Servlet 中移除用户信息。
// LogoutServlet.java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取 Session
HttpSession session = request.getSession();
// 2. 移除 Session 中的用户信息
session.removeAttribute("user");
session.removeAttribute("loginTime");
// 3. 可选:使整个 Session 失效(销毁整个 Session 对象)
// session.invalidate();
// 重定向到登录页面
response.sendRedirect("login.jsp");
}
JSP 中的 Session 存取
在 JSP 页面中,Session 对象是内置对象之一,可以直接使用,无需获取。
存入数据
使用 JSP 的内置脚本或 EL 表达式。
<%-- 使用 JSP 脚本 --%>
<%
User user = new User("zhangsan", "zhangsan@example.com");
session.setAttribute("user", user); // 直接使用 session 对象
%>
<%-- 使用 EL 表达式 (更推荐) --%>
<%-- EL 表达式主要用于读取,但也可以配合 JSTL 的 <c:set> 来设置 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var="user" value="${new com.example.User('lisi', 'lisi@example.com')}" scope="session" />
读取数据
使用 EL 表达式是读取 Session 数据最简洁、最推荐的方式。
<%-- 使用 EL 表达式读取 --%>
<p>当前登录用户: ${sessionScope.user.username}</p>
<p>登录时间: ${sessionScope.loginTime}</p>
<%-- 也可以直接使用 ${user},因为 EL 会按 page -> request -> session -> application 的顺序查找 --%>
<p>简化写法: ${user.username}</p>
移除数据
同样可以使用 JSTL 的核心标签库。
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <c:remove var="user" scope="session" /> <c:remove var="loginTime" scope="session" />
Session 的生命周期和配置
- 创建时机:第一次调用
request.getSession()时。 - 销毁时机:
- 超时:如果一段时间内(30 分钟)用户没有发送任何请求,Session 会自动失效,超时时间可以在
web.xml中配置。<web-app> <session-config> <session-timeout>30</session-timeout> <!-- 单位:分钟 --> </session-config> </web-app> - 手动销毁:调用
session.invalidate()。 - 服务器关闭或重启:所有 Session 都会被销毁。
- 超时:如果一段时间内(30 分钟)用户没有发送任何请求,Session 会自动失效,超时时间可以在
- Cookie 禁用问题:如果用户禁用了浏览器的 Cookie,
JSESSIONID无法传递,Session 机制就会失效,解决方案是 URL 重写,即把SessionID直接附加在 URL 后面,Servlet 容器会自动处理,你只需要确保所有链接都使用response.encodeURL()或response.encodeRedirectURL()方法包装即可。
| 操作 | Servlet API | JSP (内置对象) |
|---|---|---|
| 获取 Session | request.getSession() |
直接使用 session |
| 存入数据 | session.setAttribute("key", value) |
<c:set var="key" value="value" scope="session" /> |
| 读取数据 | Object obj = session.getAttribute("key"); |
${sessionScope.key} 或 ${key} |
| 移除数据 | session.removeAttribute("key") |
<c:remove var="key" scope="session" /> |
| 销毁 Session | session.invalidate() |
无直接对应,可通过 Servlet 调用 |
理解 Session 的存取机制是进行 Web 应用开发的基础,它解决了 HTTP 协议无状态的核心问题,是实现用户登录、购物车、个性化设置等功能的基石。
