Spring MVC 操作会话属性详解(@SessionAttributes 与 @SessionAttribute)

news2025/4/18 1:57:11

Spring MVC 操作会话属性详解(@SessionAttributes 与 @SessionAttribute)


1. 核心注解对比
注解作用范围功能
@SessionAttributes类级别声明控制器中需要持久化的模型属性(存入 HttpSession
@SessionAttribute方法参数/返回值显式绑定方法参数或返回值到 HttpSession已弃用,推荐使用 @SessionAttributes

2. @SessionAttributes 详解

作用:在控制器类上标注,声明哪些模型属性需要被保存到会话中,跨请求共享。


2.1 基本用法
@Controller
@SessionAttributes({ "user", "cart" }) // 保存名为 "user" 和 "cart" 的属性
public class UserController {
    // 方法中添加到 Model 的属性会被自动保存到会话
}

2.2 参数选项
属性作用
value指定要持久化的模型属性名称(字符串数组)
types指定要持久化的属性类型(Class 对象数组),满足类型即会被保存

示例:按类型保存所有 Cart 类型的属性:

@SessionAttributes(types = { Cart.class })

2.3 生命周期管理
  • 添加属性:通过 Model 接口添加到模型:

    @GetMapping("/login")
    public String login(@ModelAttribute User user, Model model) {
        model.addAttribute("user", user); // 自动持久化到会话
        return "redirect:/home";
    }
    
  • 移除属性:通过 SessionStatus 接口:

    @PostMapping("/logout")
    public String logout(SessionStatus status) {
        status.setComplete(); // 清除所有 @SessionAttributes 标记的属性
        return "redirect:/login";
    }
    

3. @SessionAttribute 详解

作用:直接从 HttpSession 获取属性作为方法参数(已弃用,建议改用 @SessionAttributes)。


3.1 基本用法
@GetMapping("/profile")
public String showProfile(
    @SessionAttribute("user") User user, // 直接从会话获取 "user" 属性
    Model model
) {
    model.addAttribute("user", user);
    return "profile";
}

3.2 注意事项
  • 已弃用:Spring 官方推荐通过 @SessionAttributes 管理会话属性,而非直接使用 @SessionAttribute
  • 替代方案:通过 @Autowired 注入 HttpSession 对象:
    @Autowired
    private HttpSession session;
    
    @GetMapping("/cart")
    public String getCart() {
        Cart cart = (Cart) session.getAttribute("cart");
        // ...
    }
    

4. 完整代码示例

4.1 使用 @SessionAttributes 的控制器
@Controller
@SessionAttributes("user") // 持久化 "user" 属性
public class UserController {

    @GetMapping("/login")
    public String loginPage() {
        return "login";
    }

    @PostMapping("/login")
    public String loginSubmit(
        @ModelAttribute User user,
        Model model
    ) {
        model.addAttribute("user", user); // 自动保存到会话
        return "redirect:/home";
    }

    @GetMapping("/home")
    public String home(
        @ModelAttribute("user") User user, // 从会话获取
        Model model
    ) {
        model.addAttribute("user", user); // 保持会话属性
        return "home";
    }

    @GetMapping("/logout")
    public String logout(SessionStatus status) {
        status.setComplete(); // 清除 "user" 属性
        return "redirect:/login";
    }
}

4.2 使用 HttpSession 直接操作
@Controller
public class CartController {

    @Autowired
    private HttpSession session;

    @GetMapping("/addToCart/{productId}")
    public String addToCart(@PathVariable String productId) {
        Cart cart = (Cart) session.getAttribute("cart");
        if (cart == null) {
            cart = new Cart();
            session.setAttribute("cart", cart); // 手动保存
        }
        cart.addProduct(productId);
        return "redirect:/cart";
    }
}

5. 对比表格:@SessionAttributes 与 @SessionAttribute
对比项@SessionAttributes@SessionAttribute
作用范围类级别(声明持久化规则)方法参数/返回值(直接绑定)
推荐程度推荐(符合 Spring MVC 设计模式)已弃用(建议改用 @SessionAttributes
生命周期管理自动管理(通过 ModelSessionStatus需手动操作会话(不推荐直接使用)
灵活性支持按名称或类型持久化仅支持按名称获取参数

6. 常见问题

Q1:如何清除单个 @SessionAttributes 属性?

A:通过 SessionStatussetComplete() 会清除所有标记的属性。若需清除单个属性,需直接操作 HttpSession

session.removeAttribute("user");
Q2:如何避免会话属性内存泄漏?

A:

  1. 在用户退出时显式清除属性(如调用 logout 方法)。
  2. 配置 HttpSession 的超时时间(web.xml 或 Spring Security)。
  3. 对敏感数据及时清理。
Q3:@SessionAttributes 是否支持类型匹配?

A:是的,通过 types 参数指定类型,例如:

@SessionAttributes(types = { Cart.class, User.class })
Q4:能否在 RESTful API 中使用会话属性?

A:可以,但需注意:

  • REST 通常要求无状态,会话属性可能破坏这一原则。
  • 若需跨请求共享数据,建议改用 Token 或数据库存储。

7. 总结
  • 推荐实践
    1. 使用 @SessionAttributes 声明需要持久化的模型属性,通过 Model 接口操作。
    2. 避免直接使用 @SessionAttribute(已弃用),改用 HttpSession@SessionAttributes
    3. 对会话属性的生命周期进行严格管理,避免内存泄漏。

通过合理使用会话属性,可以实现用户状态的跨请求保持(如登录状态、购物车),但需权衡会话存储的性能和安全性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2331139.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

案例-流量统计

1.建一个data目录,在data下建log.txt文件 输入手机号码 上行流量 下行流量 2.在com.example.flow下建四个Java类3.flowBean flowMapper flowReducer flowDriver

Codeforces Round 1011 (Div. 2)

Dashboard - Codeforces Round 1011 (Div. 2) - Codeforces Problem - B - Codeforces 题目大意: 给你一个数组,你可以用一段子序列中没有出现的最小非负整数,替换数组中的组序列,经过若干操作,让数组变为长度为1,值…

时序数据异常检测-综述

更新中 异常检测基本概念 广义的Out-of-Distribution(广义的OOD)来描述异常检测的相关问题。OOD包括五个相关的子领域,分别为Anomaly Detection(AD)、Novelty Detection(ND)、Open Set Recogntion(OSR)、Out-of-Distribution(OOD)和Outlier Detection(OD)。这5个…

多类型医疗自助终端智能化升级路径(代码版.下)

医疗人机交互层技术实施方案 一、多模态交互体系 1. 医疗语音识别引擎 # 基于Wav2Vec2的医疗ASR系统 from transformers import Wav2Vec2Processor, Wav2Vec2ForCTC import torchaudioclass MedicalASR:def __init__(self):self.processor = Wav2Vec2Processor.from_pretrai…

蓝桥杯专项复习——双指针

目录 双指针算法:双指针算法-CSDN博客 最长连续不重复子序列 P8783 [蓝桥杯 2022 省 B] 统计子矩阵 双指针优化思路:当存在重复枚举时,可以考虑是否能使用双指针进行优化 双指针算法:双指针算法-CSDN博客 最长连续不重复子序列…

BetaFlight参数配置解读

BetaFlight参数配置解读 📌相关篇《Betaflight固件编译和烧录说明》🥕各型号已编译好的配置文件资源(.config):https://github.com/betaflight/unified-targets/tree/master/configs/default🌿各型号配置头…

Java 容器源码分析

一、哈希表 1、引入 hash 表 在无序数组中按照内容查找,效率底下,时间复杂度是 O(n) 在有序数组中按照内容查找,可以使用折半查找,时间复杂度 O(log2n) 哈希表可以不进行比较,通过计算得到地…

【Java中级】11章、枚举 - java引用数据类型,枚举介绍、快速入门,了解枚举类的基本使用方式【1】

文章内容: 自定义实现枚举enum关键字实现枚举 ❤️内容涉及枚举的定义,快速入门,注意事项和小题巩固知识点 🌈 跟着B站一位老师学习的内部类内容,现写这篇文章为学习内部类的小伙伴提供思路支持,希望可以一…

Jmeter 插件【性能测试监控搭建】

1. 安装Plugins Manager 1.1 下载路径: Install :: JMeter-Plugins.org 1.2 放在lib/ext目录下 1.3 重启Jmeter,会在菜单-选项下多一个 Plugins Manager菜单,打开即可对插件进行安装、升级。 2. 客户端(Jmeter端) 2.1 安装plugins manager…

【ES系列】Elasticsearch从入门到精通保姆级教程 | 启篇

🔥 本系列将带你从零开始学习Elasticsearch,通过保姆级教程,手把手教你掌握这个强大的搜索与分析引擎。无论你是完全的新手,还是想系统学习ES的开发者,这个系列都能满足你的需求。 📚博主匠心之作,强推专栏: JAVA集合专栏 【夜话集】JVM知识专栏数据库sql理论与实战【…

Unity中Spine骨骼动画完全指南:从API详解到避坑实战

Unity中Spine骨骼动画完全指南:从API详解到避坑实战 一、为什么要选择Spine? Spine作为专业的2D骨骼动画工具,相比传统帧动画可节省90%资源量。在Unity中的典型应用场景包括: 角色换装系统(通过插槽替换部件)复杂连招系统(动画混合与过渡)动态表情系统(面部骨骼控制)…

C++Cherno 学习笔记day17 [66]-[70] 类型双关、联合体、虚析构函数、类型转换、条件与操作断点

b站Cherno的课[66]-[70] 一、C的类型双关二、C的union(联合体、共用体)三、C的虚析构函数四、C的类型转换五、条件与操作断点——VisualStudio小技巧 一、C的类型双关 作用:在C中绕过类型系统 C是强类型语言 有一个类型系统,不…

wordpress 利用 All-in-One WP Migration全站转移

导出导入站点 在插件中查询 All-in-One WP Migration备份并导出全站数据 导入 注意事项: 1.导入部分限制50MB 宝塔解决方案,其他类似,修改php.ini配置文件即可 2. 全站转移需要修改域名 3. 大文件版本,大于1G的可以参考我的…

【工具使用】在OpenBMC中使用GDB工具来定位coredump原因

在OpenBMC调试中,有时会产生coredump却不知道从哪里入手分析,GDB工具就可以提供帮助。 1 编译带GDB工具的镜像 OpenBMC镜像中默认没有加入GDB工具,因此首先需要编译一个带GDB工具的OpenBMC镜像用于调试。在recipes-phosphor/packagegroups/…

Linux系统(Ubuntu和树莓派)的远程操作练习

文章目录 一、实验一(一)实验准备(二)Ubuntu 下的远程操作(三)树莓派下的远程操作(四)思考 二、实验二1.talk程序2. C 编写 Linux 进程间通信(IPC)聊天程序 一…

高效创建工作流,可实现类似unreal engine的蓝图效果,内部使用多线程高效执行节点函数

文章目录 前言(Introduction)开发环境搭建(Development environment setup)运行(Run test)开发者(Developer)编译(Compile)报错 前言(Introductio…

Design Compiler:语法检查工具dcprocheck

相关阅读 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 dcprocheck是一个在Design Compiler存在于安装目录下的程序(其实它是一个指向snps_shell的符号链接,但snps_shell可以根据启动命令名判…

aws(学习笔记第三十八课) codepipeline-build-deploy-github-manual

文章目录 aws(学习笔记第三十八课) codepipeline-build-deploy-github-manual学习内容:1. 整体架构1.1 代码链接1.2 全体处理架构 2. 代码分析2.1 创建ImageRepo,并设定给FargateTaskDef2.2 创建CodeBuild project2.3 对CodeBuild project赋予权限&#…

深度学习|注意力机制

一、注意力提示 随意:跟随主观意识,也就是指有意识。 注意力机制:考虑“随意线索”,有一个注意力池化层,将会最终选择考虑到“随意线索”的那个值 二、注意力汇聚 这一部分也就是讲第一大点中“注意力汇聚”那个池化…

京东店铺托管7*16小时全时护航

内容概要 京东店铺托管服务的*716小时全时护航模式,相当于给商家配了个全年无休的"运营管家"。专业团队每天从早7点到晚11点实时盯着运营数据和商品排名,连半夜流量波动都能通过智能系统秒级预警。这种全天候服务可不是单纯拼人力——系统自动…