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

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 {@Autowiredprivate 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.mzph.cn/news/900677.shtml

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

相关文章

Python字典实战: 三大管理系统开发指南(班级+会议+购物车)(附源码)

目录 摘要 一、班级管理系统(含成绩模块) 1. 功能概述 2. 完整代码与解析 3. 代码解析与亮点 二、会议管理系统 1. 功能概述 2. 完整代码 3. 代码解析与亮点 三、购物车管理系统 1. 功能概述 2. 完整代码 3. 代码解析与亮点 四、总结与扩…

北京自在科技:让万物接入苹果Find My网络的″钥匙匠″

在AirTag掀起全球防丢热潮的今天,越来越多的第三方产品开始接入苹果Find My网络——从充电宝到电动车,从行李箱到保温杯,用户只需打开iPhone的「查找」App,就能实时定位这些物品。 北京自在科技有限责任公司早在苹果推出Find My开…

Vue进行前端开发流程

一、创建vue项目 创建vue项目&#xff1a;先进入要操作的目录下&#xff0c;注意本项目是用vue2开发的。 vue create vue项目名 二、项目开发 1.创建项目结构 2.开发功能模块 主入口App.vue <template><div class"boss-app"><Header /><m…

网络带宽测速工具选择指南iperf3 nttcp tcpburn jperf使用详解

简介 本文主要介绍内网&#xff08;局域网&#xff09;与外网&#xff08;互联网&#xff09;的网络带宽测速工具下载地址、选择指南、参数对比、基本使用。 测速工具快速选择指南 测速工具下载地址 iperf 官网下载链接&#xff1a;iperf.fr/iperf-download.php该链接提供了不…

微软的 Copilot 现在可以浏览网页并为您执行操作

在庆祝其 50 岁生日之际&#xff0c;微软正在向其人工智能驱动的 Copilot 聊天机器人传授一些新技巧。 从 BASIC 到 AI&#xff0c;改变世界的公司&#xff1a;微软 微软表示&#xff0c;Copilot 现在可以在“大多数网站”上采取行动&#xff0c;使其能够预订门票、预订餐厅等…

Docker学习--网络相关命令

docker network 命令的作用&#xff1a; 用于管理 Docker 网络。这些命令可以创建、列出、删除和检查网络&#xff0c;帮助用户在 Docker 容器之间建立通信。 常用命令&#xff1a; ①列出所有网络&#xff1a; docker network ls。 输出&#xff1a; NETWORK ID NA…

【Vue3知识】组件间通信的方式

组件间通信的方式 概述**1. 父子组件通信****父组件向子组件传递数据&#xff08;Props&#xff09;****子组件向父组件发送事件&#xff08;自定义事件&#xff09;** **2. 兄弟组件通信****通过父组件中转****使用全局状态管理&#xff08;如 Pinia 或 Vuex&#xff09;** **…

[蓝桥杯] 挖矿(CC++双语版)

题目链接 P10904 [蓝桥杯 2024 省 C] 挖矿 - 洛谷 题目理解 我们可以将这道题中矿洞的位置理解成为一个坐标轴&#xff0c;以题目样例绘出坐标轴&#xff1a; 样例&#xff1a; 输入的5为矿洞数量&#xff0c;4为可走的步数。第二行输入是5个矿洞的坐标。输出结果为在要求步数…

2025年Python的主要应用场景

李升伟 编译 Python在2025年仍是最受欢迎和强大的编程语言之一。其简洁易读的语法以及庞大的库生态系统&#xff0c;使其成为各行业开发者的首选。无论是构建复杂的数据管道&#xff0c;还是自动化重复性任务&#xff0c;Python都能提供广泛的应用场景&#xff0c;以实现快速、…

fastapi完全离线环境(无外网)的访问Swagger所做特殊处理

在互联网环境中&#xff0c;只要 启动FastAPI 服务运行在本地机器上&#xff0c;访问 http://localhost:8000/docs&#xff08;Swagger UI&#xff09;就可以访问到Swagger界面&#xff0c;但是在完全离线环境&#xff08;无外网&#xff09;下如何访问Swagger页面呢&#xff1…

Ubuntu 20.04 出现问号图标且无法联网 修复

在 Ubuntu 中遇到网络连接问题&#xff08;如出现问号图标且无法联网&#xff09;&#xff0c;可以通过以下命令尝试重启网络服务&#xff1a; 1. 推荐先修改DNS 编辑 -> 虚拟机网络编辑器-> VMnet8 ->NAT 设置 -> DNS 设置 -> 设置DNS 服务器 DNS填什么 取决…

哈希表(开散列)的实现

目录 引入 开散列的底层实现 哈希表的定义 哈希表的扩容 哈希表的插入 哈希表查找 哈希表的删除 引入 接上一篇&#xff0c;我们使用了闭散列的方法解决了哈希冲突&#xff0c;此篇文章将会使用开散列的方式解决哈希冲突&#xff0c;后面对unordered_set和unordered_map的…

机器学习(八):K-Means聚类原理与实战

声明&#xff1a;未经允许禁止转载与抄袭。 前言 k k k均值&#xff08; k k k-means&#xff09;聚类算法是一种经典的无监督聚类算法&#xff0c;本文将深入解析其理论原理&#xff0c;并在真是数据集上进行算法实践&#xff0c;话不多说&#xff0c;请看下文。 算法原理 …

判断矩阵A和矩阵B是否相似?

【例题1】 &#xff08;1&#xff09;方法1 &#xff08;2&#xff09;方法2 &#xff08;3&#xff09;方法3 好题\(^o^)/~ 【注意】当二次多项式有重根时&#xff0c;即判别式为零&#xff0c;此时二次多项式是完全平方。

【10】搭建k8s集群系列(二进制部署)之安装Dashboard和CoreDNS

一、部署Dashboard 1.1、创建kubernetes-dashboard.yaml文件 完整的yaml配置文件信息如下&#xff1a; # Copyright 2017 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in …

大数据技术与Scala

集合高级函数 过滤 通过条件筛选集合元素&#xff0c;返回新集合。 映射 对每个元素应用函数&#xff0c;生成新集集合 扁平化 将嵌套集合展平为单层集合。 扁平化映射 先映射后展平&#xff0c;常用于拆分字符串。 分组 按规则将元素分组为Map结构。 归约 …

数据驱动可视化实战:图表狐精准生成图表的完整数据范式

一、数据输入黄金法则 图表狐 - AI图表生成工具,在线数据可视化要求数据描述必须包含三个核心要素&#xff1a; [主体对象] [量化指标] [维度划分] 错误示例 ❌&#xff1a; "展示各部门销售额对比" 正确示例 ✅&#xff1a; "2023年Q1-Q4各部门销售额&a…

苍穹外卖(1)-部分环境配置(git、数据库)

首先配置git 创建好本地仓库之后 把项目弄到远程仓库里去 先进行提交 &#xff0c;后进行推送 &#xff0c;然后gitee创建一个仓库 把这个url复制好 推送后会出来一个 点击推送&#xff0c;会让你输入gitee账号密码&#xff0c;输入自己的账号密码&#xff0c;就可以连接远程仓…

Ubunut18.04 离线安装MySQL 5.7.35

一、环境准备 1.1 官方下载MySQL5.7.35 完整包 1.2 上传包 & 解压 上传包名称是&#xff1a;mysql-server_5.7.35-1ubuntu18.04_amd64.deb-bundle.tar # 切换到上传目录 cd /home/MySQL # 解压&#xff1a; tar -xvf mysql-server_5.7.35-1ubuntu18.04_amd64.deb-bundle…

Linux(CentOS10) gcc编译

本例子摘自《鸟哥的linux私房菜-基础学习第四版》 21.3 用make进行宏编译 书中的代码在本机器(版本见下&#xff09;编译出错&#xff0c;改正代码后发布此文章&#xff1a; #kernel version: rootlocalhost:~/testmake# uname -a Linux localhost 6.12.0-65.el10.x86_64 #1…