@SessionAttributes用于在同Controller的多次请求间临时共享指定模型属性,需声明、添加、清理三步操作,适用于分步表单等场景,不跨Controller生效且要求对象可序列化。

@SessionAttributes 是 Spring MVC 提供的用于在多个请求之间**临时共享模型属性**的注解,它不是用来操作 HttpSession 的底层 API,而是对“模型属性”做会话级缓存的声明式支持。它的核心作用是:让某些 当前控制器内使用的 Model 属性 在后续同控制器的请求中自动从 session 恢复,避免重复绑定或查询。
什么时候该用 @SessionAttributes?
适用于同一 Controller 内、连续几步操作(如表单分步提交、向导流程)中需要暂存中间数据的场景。例如:
- 用户填写注册表单第一页(姓名、邮箱),跳转到第二页(密码、确认密码),需要保留前页输入;
- 购物车添加商品后,进入结算页,仍需访问购物车对象;
- 编辑实体时先查出对象放入 model,后续 POST 请求更新时希望直接绑定到同一个对象实例。
注意:它只对当前 Controller 有效,且仅管理被明确声明的模型属性名,不会影响其他 Controller 或全局 session。
基本用法:声明 + 添加 + 清理
三步缺一不可:
-
声明:在 Controller 类上加
@SessionAttributes({"user", "cart"}),指定要托管的模型属性名(String 数组); -
添加:在 handler 方法中通过
model.addAttribute("user", user)放入对应 key 的对象 —— Spring 会自动同步进 session; -
清理:调用
sessionStatus.setComplete()(传入SessionStatus参数),Spring 会在本次请求结束后移除这些属性。
示例:
@Controller
@SessionAttributes("userInfo")
public class UserController {
@GetMapping("/step1")
public String showStep1(Model model) {
model.addAttribute("userInfo", new UserInfo()); // 自动存入 session
return "step1";
}
@PostMapping("/step2")
public String handleStep2(@ModelAttribute UserInfo userInfo,
BindingResult result,
SessionStatus status) {
if (result.hasErrors()) return "step1";
// 处理第二步逻辑...
status.setComplete(); // ✅ 清理 userInfo,后续请求不再从 session 恢复
return "success";
}
}
常见误区和注意事项
-
不是所有 Model 属性都会进 session:只有名字匹配
@SessionAttributes列表的才会被托管; -
不等于直接操作 HttpSession:你不能用
request.getSession().getAttribute("userInfo")取值 —— Spring 封装了存储位置(可能是 session,也可能是其他策略),应始终通过@ModelAttribute绑定或Model获取; -
类型必须可序列化:被托管的对象类需实现
Serializable,否则可能在集群或重启时出错; -
不要跨 Controller 共享:另一个 Controller 即使也写了
@SessionAttributes("userInfo"),也无法自动获取前一个 Controller 存的值 —— 它只负责自己范围内的恢复逻辑。
替代方案对比
如果需要更灵活的会话控制(比如跨 Controller、手动增删、设置超时),应直接使用 HttpSession:
-
session.setAttribute("key", obj)/session.getAttribute("key"); - 搭配
@Scope("session")的 Bean(适合整个 session 生命周期的组件); - 使用 Spring Session(支持 Redis、JDBC 等外置 session 存储)。
@SessionAttributes 是轻量、约定式、面向流程的会话建模工具,适合“本 Controller 内短生命周期”的模型延续 —— 用对场景,代码更干净;滥用或误解,反而增加调试成本。


















