杰瑞科技汇

Java如何获取session中的值?

核心概念

要明白几个关键点:

Java如何获取session中的值?-图1
(图片来源网络,侵删)
  1. Session 是什么? Session(会话)是一种在服务器端存储用户特定数据的机制,当用户访问网站时,服务器会为其创建一个唯一的 Session ID,并将其发送给浏览器(通常通过 Cookie),之后,浏览器每次请求都会带上这个 ID,服务器就能识别出是哪个用户,并从服务器内存或数据库中找到对应的 Session 数据。

  2. Session 中存什么? Session 通常用来存储一些小量、敏感且需要跨多个请求保持的数据,

    • 用户登录信息(用户对象、用户ID)
    • 用户权限信息
    • 临时验证码
  3. 获取值的通用步骤:

    1. 获取 Session 对象:从当前请求中获取 HttpSession 实例。
    2. 根据键获取值:使用 session.getAttribute("key") 方法,传入之前存入数据时使用的键。
    3. 类型转换getAttribute() 返回的是 Object 类型,你需要将其强制转换为你当初存入时的数据类型。

原生 Servlet (Java EE / Jakarta EE)

这是最基础、最原始的方式,理解它有助于理解其他框架的底层原理。

Java如何获取session中的值?-图2
(图片来源网络,侵删)

获取 Session

// HttpServletRequest 对象通常由容器(如 Tomcat)传入
HttpSession session = request.getSession();
  • request.getSession():如果当前请求没有关联的 Session,它会创建一个新的 Session 并返回,如果已有,则返回现有的 Session。
  • request.getSession(false):如果当前请求没有关联的 Session,它不会创建新的,而是返回 null

存入和获取值

假设我们有一个 LoginServlet 来处理登录,并将用户信息存入 Session。

存入值 (例如在登录成功后):

// LoginServlet.java
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String username = request.getParameter("username");
    // 模拟从数据库获取用户信息
    User user = new User(username, "user@example.com");
    // 1. 获取 Session
    HttpSession session = request.getSession();
    // 2. 向 Session 中存入值 (key-value 对)
    session.setAttribute("loggedInUser", user);
    session.setAttribute("userRole", "admin");
    response.getWriter().println("Login successful! User info stored in session.");
}

获取值 (例如在另一个 ProfileServlet 中):

// ProfileServlet.java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 1. 获取 Session
    HttpSession session = request.getSession();
    // 2. 根据键获取值,并进行类型转换
    User loggedInUser = (User) session.getAttribute("loggedInUser");
    String userRole = (String) session.getAttribute("userRole");
    if (loggedInUser != null) {
        response.getWriter().println("Welcome, " + loggedInUser.getUsername() + "!");
        response.getWriter().println("Your role is: " + userRole);
    } else {
        response.getWriter().println("You are not logged in.");
    }
}

移除 Session 中的值

// 移除单个属性
session.removeAttribute("userRole");
// 销毁整个 Session (包括所有属性)
session.invalidate();

Spring MVC

Spring MVC 对 Servlet API 进行了封装,使得操作更加便捷和优雅。

Java如何获取session中的值?-图3
(图片来源网络,侵删)

获取 Session

在 Spring MVC 中,你可以直接在 Controller 方法的参数列表中声明 HttpSession,Spring 会自动为你注入。

存入和获取值

存入值:

import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class LoginController {
    @PostMapping("/login")
    public String login(String username, HttpSession session) {
        // 直接使用注入的 HttpSession 对象
        User user = new User(username, "user@example.com");
        session.setAttribute("loggedInUser", user);
        session.setAttribute("userRole", "admin");
        System.out.println("User info stored in session.");
        return "redirect:/profile"; // 登录成功后跳转到个人主页
    }
}

获取值:

import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class ProfileController {
    @GetMapping("/profile")
    public String profile(HttpSession session) {
        // 直接使用注入的 HttpSession 对象
        User loggedInUser = (User) session.getAttribute("loggedInUser");
        String userRole = (String) session.getAttribute("userRole");
        if (loggedInUser != null) {
            System.out.println("Welcome, " + loggedInUser.getUsername());
            // 可以将数据存入 Model,传递给视图
            // model.addAttribute("user", loggedInUser);
            return "profile"; // 返回视图名,profile.jsp
        } else {
            return "redirect:/login"; // 未登录则跳转到登录页
        }
    }
}

Spring Boot 环境下的注意事项: 在 Spring Boot 中,javax.servlet.http.HttpSession 仍然是标准的,但如果你使用的是较新版本的 Spring Boot (3.x+),并且配置了 Servlet 容器(如 Tomcat),它依然可用。


Spring Boot (使用现代 Session 管理)

Spring Boot 推荐使用更高级的会话管理方式,特别是与 Spring Session 结合时,可以实现将 Session 数据存储在 Redis、数据库等外部存储中,实现集群共享。

虽然底层可能还是通过 HttpSession,但 Spring Boot 的自动配置让你几乎感觉不到它的存在。

基本用法与 Spring MVC 完全相同:

@RestController
public class SessionController {
    @GetMapping("/set-session")
    public String setSession(HttpSession session) {
        session.setAttribute("message", "Hello from Spring Boot Session!");
        return "Session value has been set.";
    }
    @GetMapping("/get-session")
    public String getSession(HttpSession session) {
        String message = (String) session.getAttribute("message");
        return message != null ? message : "No message found in session.";
    }
}

高级用法 (Spring Session + Redis): 要启用外部 Session 存储,你只需要添加依赖和配置。

  1. 添加依赖 (pom.xml):

    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
  2. 添加注解: 在你的主应用类上添加 @EnableRedisHttpSession

    import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
    @SpringBootApplication
    @EnableRedisHttpSession // 启用基于 Redis 的 Spring Session
    public class MyApplication {
        public static void main(String[] args) {
            SpringApplication.run(MyApplication.class, args);
        }
    }

完成以上配置后,你的 Spring Boot 应用就会自动将 Session 数据存入 Redis,而你的 Controller 代码完全不需要任何改动。


Java EE (JSP / JSTL)

在 JSP 页面中直接获取 Session 值非常方便,通常结合 JSTL (JSP Standard Tag Library) 使用。

存入值 (在 Servlet 中): 和原生 Servlet 一样,在 Servlet 中通过 session.setAttribute() 存入。

获取值 (在 JSP 页面中):

<%@ page import="com.example.User" %>
<%@ page import="javax.servlet.http.HttpSession" %>
<%@ page import="javax.servlet.jsp.jstl.core.LoopTagSupport" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
    // 1. 获取 Session
    HttpSession currentSession = pageContext.getSession();
    // 2. 获取属性并设置到 request 作用域,供 JSTL 使用
    User user = (User) currentSession.getAttribute("loggedInUser");
    request.setAttribute("user", user);
%>
<html>
<head>User Profile</title>
</head>
<body>
    <h1>Welcome to your Profile</h1>
    <!-- 使用 JSTL 的 c:if 判断是否存在 -->
    <c:if test="${not empty user}">
        <p>Username: <c:out value="${user.username}" /></p>
        <p>Email: <c:out value="${user.email}" /></p>
    </c:if>
    <!-- 使用 EL 表达式 (Expression Language) 也可以直接访问 Session 作用域的属性 -->
    <!-- ${sessionScope.loggedInUser.username} -->
    <!-- 但更推荐的做法是通过 Servlet 将数据转发到 request 作用域 -->
</body>
</html>
  • 是 EL 表达式,用于获取作用域(page, request, session, application)中的数据。
  • sessionScope 是 EL 的隐式对象,可以明确指定从 Session 作用域查找。
  • <c:out> 是 JSTL 的标签,用于安全地输出内容,可以防止 XSS 攻击。

总结与最佳实践

技术 获取 Session 对象方式 获取值示例 备注
原生 Servlet request.getSession() User user = (User) session.getAttribute("loggedInUser"); 基础,必须掌握。
Spring MVC 在 Controller 方法参数中声明 HttpSession session User user = (User) session.getAttribute("loggedInUser"); Spring 自动注入,代码更简洁。
Spring Boot 同 Spring MVC 同 Spring MVC 推荐结合 Spring Session 使用,实现集群 Session 共享。
JSP / JSTL pageContext.getSession() 或直接使用 EL ${sessionScope.loggedInUser.username} 主要用于视图层展示。

最佳实践建议:

  1. 避免在 Session 中存放大对象:Session 存储在服务器内存中,过大的对象会消耗大量内存,影响性能。
  2. 使用 POJO (普通 Java 对象):存入自定义的 Java 对象比存入零散的基本数据类型更易于管理和维护。
  3. 及时清理 Session:用户登出时,调用 session.invalidate() 销毁整个 Session,或 session.removeAttribute() 移除特定属性,释放服务器资源。
  4. 考虑序列化:如果你的应用需要集群部署(使用 Spring Session 等技术),存入 Session 的对象必须实现 java.io.Serializable 接口,以便可以被序列化后在节点间传输。
  5. 注意线程安全:Session 是用户私有的,单个用户的请求是串行的,所以一个用户的 Session 操作本身是线程安全的,但不要将 Session 对象本身共享给多个线程。
分享:
扫描分享到社交APP
上一篇
下一篇