杰瑞科技汇

java session 清空

核心概念

要理解 Session 是什么:

java session 清空-图1
(图片来源网络,侵删)
  • Session 是服务器端的一种机制,用于在多个 HTTP 请求之间保持用户的状态信息。
  • 服务器会为每个用户创建一个唯一的 Session ID,并通过 Cookie 发送给客户端,后续请求客户端会携带这个 ID,服务器通过 ID 找到对应的 Session 对象。
  • HttpSession 是 Java Servlet API 中表示 Session 的接口。

“清空 Session” 的本质就是销毁这个 HttpSession 对象,使其在服务器端不再可用。


原生 Servlet API (最基础)

如果你没有使用任何高级框架(如 Spring, Spring MVC),而是直接使用 Servlet,操作非常直接。

使用 invalidate() (最彻底、最常用)

session.invalidate() 方法会立即销毁当前的 Session 对象,并释放所有与之绑定的资源,这是“清空 Session”最标准、最推荐的方式。

示例代码:

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") // 访问这个URL就会退出登录
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 获取当前的 HttpSession 对象
        HttpSession session = request.getSession(false); // 使用 false 参数,session 不存在则返回 null,避免创建新 session
        // 2. 检查 session 是否存在
        if (session != null) {
            // 3. 调用 invalidate() 方法销毁 session
            session.invalidate();
            System.out.println("Session has been invalidated.");
        }
        // 4. 重定向到登录页面
        response.sendRedirect(request.getContextPath() + "/login.html");
    }
}

代码解释:

  • request.getSession(false): 获取 Session,传入 false 是一个好习惯,表示“如果不存在就别新建,直接返回 null”,这可以避免在登出逻辑中意外创建一个新的 Session。
  • session.invalidate(): 核心方法,彻底销毁 Session。
  • response.sendRedirect(...): 销毁 Session 后,通常会将用户重定向到登录页面或其他页面。

手动移除所有属性 (不推荐)

你也可以遍历 Session 中的所有属性,并手动移除它们,这种方式并没有真正销毁 Session 对象,它只是一个空壳,服务器端的会话依然存在,会占用内存,直到超时。

示例代码 (不推荐):

HttpSession session = request.getSession();
java.util.Enumeration<String> attributeNames = session.getAttributeNames();
while (attributeNames.hasMoreElements()) {
    String attributeName = attributeNames.nextElement();
    session.removeAttribute(attributeName);
}
// session 对象本身还存在,只是是空的

为什么不推荐?

  • 不彻底:Session 对象本身未被销毁,仍然占用服务器资源。
  • 代码冗余invalidate() 一行代码就能搞定,而这种方式需要写循环。
  • 可能遗漏:Session 中存储了非标准的属性,可能会被遗漏。

Spring / Spring MVC

在 Spring MVC 中,你通常不会直接操作 HttpSession 对象,而是通过注入 HttpSession 或使用 Spring 提供的更高级的抽象。

直接注入 HttpSession 并调用 invalidate()

这是最直接的方式,与原生 Servlet API 几乎一样。

示例代码 (Controller 中):

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpSession;
@Controller
public class LogoutController {
    @GetMapping("/logout")
    public String logout(HttpSession session) {
        // 检查 session 是否存在 (Spring MVC 会自动管理,通常不为 null)
        if (session != null) {
            session.invalidate();
            System.out.println("Session invalidated in Spring MVC.");
        }
        return "redirect:/login"; // 重定向到登录页面
    }
}

使用 Spring Security (推荐)

如果你的项目使用了 Spring Security,它提供了更优雅、更安全的退出登录机制,Spring Security 会自动处理 Session 失效、Cookie 清除等所有事情。

示例代码 (Spring Security 配置):

你只需要在配置类中添加一个退出登录的 URL 映射即可。

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
            // ... 其他配置,如登录、角色等
            .logout()
                .logoutUrl("/logout") // 设置退出登录的URL
                .logoutSuccessUrl("/login?logout") // 退出成功后跳转的URL
                .invalidateHttpSession(true) // 使HTTP session失效 (默认为true)
                .deleteCookies("JSESSIONID"); // 删除与 session 相关的 cookie (默认会删除)
    }
}

访问方式: 用户只需访问 /logout 这个 URL,Spring Security 就会自动处理所有事情,包括:

  1. 使当前 Session 失效。
  2. 清除 JSESSIONID Cookie。
  3. 清除 Security 上下文中的认证信息。
  4. 重定向到 /login?logout 页面。

这是生产环境中最推荐的方式,因为它最安全、最全面。


Java EE (Jakarta EE) / Jakarta Servlet

从 Java 9 开始,Java EE 的包名从 javax.* 迁移到了 jakarta.*,如果你使用的是较新版本的 Jakarta EE (在 Jakarta EE 8 / 9+ 项目中),代码需要更换包名。

原生 Servlet API (Jakarta EE 版本):

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.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 {
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.invalidate();
        }
        response.sendRedirect(request.getContextPath() + "/login.html");
    }
}

主要变化:

  • javax.servlet.* -> jakarta.servlet.*
  • javax.servlet.http.* -> jakarta.servlet.http.*

总结与最佳实践

场景 推荐方法 优点
原生 Servlet / Jakarta Servlet session.invalidate() 标准做法,彻底、简单。
Spring MVC session.invalidate() 或注入 HttpSession 后调用 直接有效,与底层 API 一致。
使用 Spring Security 配置 .logout() 强烈推荐,一站式解决方案,自动处理 Session、Cookie、安全上下文,更安全、更全面。

核心要点:

  1. 首选 invalidate():在绝大多数情况下,调用 session.invalidate() 是清空 Session 的最佳方式。
  2. 框架优先:如果使用了 Spring Security 等安全框架,优先使用框架提供的退出功能,不要自己手动处理。
  3. 注意包名:在新项目中,注意使用 jakarta.* 包名,而不是已过时的 javax.*
分享:
扫描分享到社交APP
上一篇
下一篇