核心概念:HttpSession 对象
在 Java Web(特别是 Servlet 规范)中,HttpSession 对象代表用户与服务器之间的一次会话,它通常用于存储特定用户的状态信息(如登录用户信息、购物车等)。

要操作 Session,我们必须通过 HttpServletRequest 对象来获取它:
HttpSession session = request.getSession();
销毁整个 Session (最常用)
这是最直接的方法,它会立即使当前会话失效,并删除所有存储在 Session 中的所有属性,客户端后续的请求将获得一个全新的 Session ID。
方法:session.invalidate()
示例代码 (Servlet 中):

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取当前的 Session
HttpSession session = request.getSession(false); // 使用 false,session 不存在则返回 null,避免创建新 session
// 2. 检查 session 是否存在
if (session != null) {
// 3. 销毁 session
session.invalidate();
System.out.println("Session has been invalidated.");
}
// 4. 重定向到登录页面或首页
response.sendRedirect("login.html");
}
}
说明:
request.getSession(false)是一个良好的实践,当你只想销毁一个已存在的 session 而不是创建一个新的时,应该使用它,session 不存在,它会返回null。invalidate()是一个“原子性”操作,一旦调用,整个 session 就被彻底销毁了。- 客户端 Cookie:
invalidate()会使服务器端的 session 失效,但客户端通常仍然保存着名为JSESSIONID的 Cookie,客户端下次请求时,服务器会发现这个 ID 已失效,然后会创建一个全新的 session,并将新的JSESSIONID发送给客户端,覆盖旧的 Cookie,这个过程对用户是透明的。
移除 Session 中的单个属性
如果你只想删除 Session 中存储的某个特定数据,而不是整个会话,可以使用 removeAttribute() 方法。
方法:session.removeAttribute(String attributeName)
示例代码:
// 假设在登录时,我们将用户信息存入了 session
// request.getSession().setAttribute("user", new User("zhangsan"));
// 在某个业务逻辑中,需要清除用户信息,但保留其他 session 数据(比如购物车)
HttpSession session = request.getSession();
if (session != null) {
// 只移除 "user" 这个属性
session.removeAttribute("user");
System.out.println("User attribute has been removed from session.");
}
适用场景:
- 用户退出登录,但希望保留其购物车内容。
- 用户修改了个人资料,需要清除旧的缓存资料。
设置 Session 的最大不活动时间 (超时)
这是一种“被动”的清除方式,你设置一个时间,如果用户在这个时间内没有与服务器进行任何交互,服务器会自动销毁该 Session。
方法:session.setMaxInactiveInterval(int interval)
interval参数的单位是秒。- 如果设置为
0或负数,表示 session 永不过期(除非调用invalidate())。 - 如果不设置,Tomcat 等容器有其默认的超时时间(通常是 30 分钟)。
示例代码:
HttpSession session = request.getSession();
// 设置 session 在 10 分钟 (600 秒) 后不活动则自动失效
session.setMaxInactiveInterval(600);
// 获取当前 session 的超时时间(秒)
int timeout = session.getMaxInactiveInterval();
System.out.println("Current session timeout is: " + timeout + " seconds.");
配置文件方式 (推荐):
你可以在 web.xml 中为整个应用设置默认的 Session 超时时间,这比在代码中硬编码更好。
<!-- web.xml -->
<session-config>
<!-- 设置 session 超时时间为 20 分钟 (1200 秒) -->
<session-timeout>20</session-timeout>
</session-config>
使用框架提供的机制 (如 Spring Security)
在现代 Web 应用中,尤其是使用 Spring Boot 和 Spring Security 的项目,通常不会直接操作 HttpSession,而是由框架来管理。
在 Spring Security 中退出登录:
Spring Security 提供了标准化的退出登录机制,它会自动处理 session 清除、Cookie 清除等操作。
配置退出处理器
在 SecurityConfig 类中,你可以配置 LogoutConfigurer。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// ... 其他配置,如 formLogin() ...
.logout()
// 退出登录的 URL,默认是 /logout
.logoutUrl("/logout")
// 退出成功后跳转的页面
.logoutSuccessUrl("/login.html")
// 是否清除认证信息(默认是 true)
.clearAuthentication(true)
// 是否使 session 失效(默认是 true)
.invalidateHttpSession(true)
// 自定义退出成功处理器(可选)
.logoutSuccessHandler((request, response, authentication) -> {
System.out.println("User logged out successfully.");
response.sendRedirect("/welcome");
})
.permitAll(); // 允许所有人访问退出 URL
}
}
创建退出链接
在 HTML 页面中,创建一个指向 /logout 的链接。
<a href="/logout">退出登录</a>
说明:
- 当用户点击
/logout链接时,Spring Security 会拦截请求。 - 它会自动调用
invalidateHttpSession(true)来销毁 session。 - 它会清除
SecurityContext中的认证信息。 - 它会清除与 remember-me 相关的 Cookie(如果配置了)。
- 重定向到
logoutSuccessUrl指定的页面。
这种方式比手动操作 HttpSession 更安全、更符合框架的最佳实践。
总结与对比
| 方法 | 描述 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
invalidate() |
立即销毁整个 Session,删除所有属性。 | 用户彻底退出登录、强制重新登录。 | 简单、彻底,能立即释放所有资源。 | 会话中所有数据丢失,可能影响其他业务逻辑。 |
removeAttribute() |
移除 Session 中的单个属性。 | 只需清除部分会话数据,如用户信息,但保留购物车等。 | 精准控制,不影响其他数据。 | 需要明确知道要删除的属性名。 |
setMaxInactiveInterval() |
设置 Session 超时时间,超时后自动销毁。 | 自动清理长期不活跃的会话,节省服务器资源。 | 无需手动干预,自动化管理。 | 属于被动清理,无法立即生效。 |
| 框架机制 (如 Spring Security) | 框架提供的高级退出功能,自动处理 session 和安全上下文。 | 基于 Spring Security 的现代 Web 应用。 | 安全、标准,处理了 Cookie 和安全上下文,是最佳实践。 | 需要依赖特定框架。 |
选择建议:
- 用户退出登录:首选框架机制(如 Spring Security 的 Logout),如果不使用框架,则使用
session.invalidate()。 - 清除部分会话数据:使用
session.removeAttribute()。 - 服务器资源管理:配置
web.xml中的默认超时时间,或在代码中动态调整setMaxInactiveInterval()。
