杰瑞科技汇

Java session 如何正确清除?

核心概念:HttpSession 对象

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

Java session 如何正确清除?-图1
(图片来源网络,侵删)

要操作 Session,我们必须通过 HttpServletRequest 对象来获取它: HttpSession session = request.getSession();


销毁整个 Session (最常用)

这是最直接的方法,它会立即使当前会话失效,并删除所有存储在 Session 中的所有属性,客户端后续的请求将获得一个全新的 Session ID。

方法:session.invalidate()

示例代码 (Servlet 中):

Java session 如何正确清除?-图2
(图片来源网络,侵删)
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 就被彻底销毁了。
  • 客户端 Cookieinvalidate() 会使服务器端的 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()
分享:
扫描分享到社交APP
上一篇
下一篇