杰瑞科技汇

java中获取session值

由于 Java Web 开发有多种框架(如原生 Servlet、Spring、Spring MVC、Spring Boot),获取 Session 的方式也略有不同,下面我将分情况详细说明。

java中获取session值-图1
(图片来源网络,侵删)

核心概念:什么是 Session?

  • Session 是服务器端的一种技术,用于跟踪用户的整个会话。
  • 当用户第一次访问服务器时,服务器会为该用户创建一个唯一的 Session ID,并将其发送给客户端(通常通过 Cookie 存储)。
  • 在后续的请求中,客户端会自动携带这个 Session ID,服务器通过 ID 找到对应的 Session 对象,从而可以读取或写入用户的数据。
  • Session 对象像一个“购物车”,可以存储任何 Java 对象(如 User 对象、权限信息、购物车列表等)。

在原生 Servlet 中获取 Session 值

这是最基础的方式,理解了它,在其他框架中就能触类旁通。

步骤:

  1. doGetdoPost 方法中,通过 HttpServletRequest 对象获取 HttpSession
  2. 使用 session.getAttribute(String name) 方法来根据键名获取存储的值,这个值是 Object 类型,需要强制类型转换。

示例代码:

设置 Session 值 (LoginServlet.java)

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("/login")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 模拟登录成功
        String username = request.getParameter("username");
        // 1. 获取Session对象(如果不存在,会自动创建一个新的)
        HttpSession session = request.getSession();
        // 2. 向Session中存储数据
        session.setAttribute("username", username); // 存储String
        session.setAttribute("userRole", "admin");   // 存储String
        // 3. 也可以存储自定义对象
        // User user = new User(username, "admin@example.com");
        // session.setAttribute("user", user);
        response.getWriter().println("Login successful! Session has been set.");
    }
}

获取 Session 值 (ProfileServlet.java)

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("/profile")
public class ProfileServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 获取Session对象(如果会话不存在,返回null,而不会创建新会话)
        HttpSession session = request.getSession(false);
        response.setContentType("text/html;charset=UTF-8");
        if (session != null && session.getAttribute("username") != null) {
            // 2. 从Session中获取数据,注意类型转换
            String username = (String) session.getAttribute("username");
            String userRole = (String) session.getAttribute("userRole");
            // 3. 获取自定义对象
            // User user = (User) session.getAttribute("user");
            response.getWriter().println("<h1>Welcome, " + username + "!</h1>");
            response.getWriter().println("<p>Your role is: " + userRole + "</p>");
        } else {
            response.getWriter().println("You are not logged in. Please <a href='login.html'>login</a> first.");
        }
    }
}

关键点:

java中获取session值-图2
(图片来源网络,侵删)
  • request.getSession(): 获取当前会话,如果不存在,则创建一个新的
  • request.getSession(false): 获取当前会话,如果不存在,则返回 null,不会创建新会话,常用于检查用户是否已登录。

在 Spring MVC 中获取 Session 值

Spring MVC 提供了更简洁、更强大的方式来处理 Session。

通过 HttpSession 参数注入(推荐)

可以直接在 Controller 方法的参数列表中添加 HttpSession 参数,Spring 会自动注入。

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
@Controller
public class SessionController {
    @PostMapping("/login")
    @ResponseBody // 直接返回字符串,不跳转页面
    public String login(@RequestParam String username, HttpSession session) {
        // 直接使用session对象
        session.setAttribute("username", username);
        session.setAttribute("userRole", "user");
        return "Login successful for user: " + username;
    }
    @GetMapping("/profile")
    @ResponseBody
    public String profile(HttpSession session) {
        // 从session中获取值
        String username = (String) session.getAttribute("username");
        if (username != null) {
            return "Welcome, " + username + "!";
        } else {
            return "Please login first.";
        }
    }
}

使用 @SessionAttributes 注解(用于模型数据共享)

这个注解用于将 Model 中的数据自动同步到 Session 中,当你希望某个数据不仅能在当前请求中访问,还能在后续请求中访问时使用它。

使用场景: 比如在表单分步提交时,将中间数据存入 Session。

java中获取session值-图3
(图片来源网络,侵删)
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.SessionAttributes;
// 1. 声明这个Controller中的哪些模型属性需要存入Session
// 这里的 "user" 是一个key,对应模型中的 user 对象
@SessionAttributes("user")
@Controller
public class UserProfileController {
    // 2. 将数据添加到Model中
    @GetMapping("/step1")
    public String step1(Model model) {
        model.addAttribute("user", new User()); // 假设User是一个POJO
        return "step1"; // 返回一个视图名,step1.jsp
    }
    // 3. 在后续方法中,可以直接从Model中获取,它会自动从Session中读取
    @GetMapping("/step2")
    public String step2(@ModelAttribute("user") User user) {
        // user 对象已经从Session中自动注入到这里了
        // 你可以修改它,修改后的内容也会被写回Session
        user.setEmail("updated@example.com");
        return "step2";
    }
}

注意: @SessionAttributes 不会自动管理 Session 的生命周期,通常需要配合 @SessionAttribute 来获取,或者手动管理 Session 的创建和销毁。


在 Spring Boot 中获取 Session 值

Spring Boot 是对 Spring MVC 的封装,所以方式与 Spring MVC 基本相同,但通常更推荐使用更现代的会话管理方式。

传统 HttpSession 方式(完全兼容 Spring MVC)

与 Spring MVC 中的方式一完全一样,直接注入 HttpSession 即可。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
@RestController
public class SessionBootController {
    @GetMapping("/set-session")
    public String setSession(HttpSession session) {
        session.setAttribute("message", "Hello from Spring Boot Session!");
        return "Session 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.";
    }
}

使用 SessionManager(更现代的方式,推荐)

Spring Boot 2.4+ 引入了 SessionManager,它提供了一种更面向对象的方式来管理会话数据,可以避免直接操作 HttpSession,从而更容易进行测试和切换会话存储实现(如 Redis)。

你需要先创建一个配置类来暴露 SessionManager

import org.springframework.context.annotation.Bean;
import org.springframework.session.Session;
import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession;
import org.springframework.session.web.http.SessionRepositoryFilter;
import org.springframework.stereotype.Component;
@EnableSpringHttpSession // 启用 Spring Session
@Component
public class SessionConfig {
    // 这个Bean的声明是必要的,用于让Spring Boot知道如何管理Session
    @Bean
    public SessionRepositoryFilter<? extends Session> springSessionRepositoryFilter() {
        // Spring Boot会自动配置,这里只是为了让编译通过
        return null;
    }
}

然后在 Controller 中使用 SessionManager

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.session.Session;
import org.springframework.session.SessionRepository;
@RestController
public class ModernSessionController {
    // 注入 SessionRepository
    @Autowired
    private SessionRepository<? extends Session> sessionRepository;
    @GetMapping("/set-modern-session")
    public String setModernSession(String sessionId) {
        // 获取或创建一个会话
        Session session = sessionRepository.createSession();
        session.setAttribute("modernMessage", "This is a modern session approach!");
        sessionRepository.save(session);
        return "Modern session set for ID: " + session.getId();
    }
    @GetMapping("/get-modern-session")
    public String getModernSession(String sessionId) {
        Session session = sessionRepository.findById(sessionId);
        if (session != null) {
            String message = (String) session.getAttribute("modernMessage");
            return message != null ? message : "No modern message found.";
        }
        return "Session not found.";
    }
}

这种方式更灵活,但日常开发中,直接注入 HttpSession 仍然是最简单直接的方法。


移除 Session 值

除了获取和设置,移除 Session 值也很重要,尤其是在用户登出时。

  • 移除单个属性:

    session.removeAttribute("username");
  • 销毁整个会话(使 Session 失效):

    session.invalidate(); // 这会清空所有 Session 数据,并删除 Session ID

总结与最佳实践

场景 推荐方式 优点
原生 Servlet request.getSession()session.getAttribute() 基础,必须掌握,是所有框架的原理。
Spring MVC / Spring Boot Controller 方法中直接注入 HttpSession 简单、直观,是 Spring 生态中最常用的方式。
Spring Boot (高级) 使用 SessionRepository / SessionManager 更灵活,易于测试,适合分布式会话(如配合 Redis)。
Spring MVC (模型共享) 使用 @SessionAttributes 适用于需要在多个请求间共享 Model 数据的场景。

最佳实践建议:

  1. 最小化 Session 数据: Session 存储在服务器内存中,数据量大会增加服务器内存压力,影响性能。
  2. 存储简单数据: 最好只存储用户 ID、角色等标识性信息,而不是整个用户对象或大量数据,复杂对象可以从数据库中根据 ID 重新加载。
  3. 及时清理: 用户登出时,务必调用 session.invalidate() 来销毁会话,防止会话固定攻击和资源浪费。
  4. 考虑分布式 Session: 在微服务或集群环境中,应使用 Spring Session + Redis 等方案,将 Session 数据集中存储,实现会话共享。
分享:
扫描分享到社交APP
上一篇
下一篇