SpringMVC @SessionAttributes 使用
@SessionAttributes 只能作用在类上,作用是将指定的Model中的键值对添加至session中,方便在下一次请求中使用。
简单示例
- 目标是通过 @SessionAttributes 注解将Model中attrName为 "user","age","name" 的值添加至 session 中
@Controller
@RequestMapping("/testSessionAttribute")
@SessionAttributes(value = {"user","age","name"})
public class TestSessionAttributeController { @ModelAttribute("user")
public User addUser(){
User user = new User();
user.setName("James");
user.setAge(29);
return user;
} @RequestMapping("/testHandler")
public String testHandler(Model model, String age, String name){
16 model.addAttribute("age",age);
17 model.addAttribute("name",name);
System.out.println(age);
System.out.println(name);
return "result";
}
}
对应的jsp代码如下:
<body>
${sessionScope.user.age}
${sessionScope.user.name}
<br/>
${sessionScope.age}
${sessionScope.name}
</body>
通过实例可以得出一下结论:
- 不论是利用@ModelAttribute添加至model的数据,还是手动添加至model的数据,均遵循 @SessionAttributes 的规则
清除@SessionAttributes向session中添加的值
如果需要清除通过@SessionAttribute添加至 session 中的数据,则需要在controller 的 handler method中添加 SessionStatus参数,在方法体中调用SessionStatus#setComplete。
需要注意的是,此时清除的只是该Controller通过@SessionAttribute添加至session的数据(当然,如果不同controller的@SessionAttribute拥有相同的值,则也会清除)
@Controller
@RequestMapping("/testSessionAttribute")
@SessionAttributes(value = {"user","age","name"})
public class TestSessionAttributeController { .......................... @RequestMapping("/removeSessionAttributes")
public String removeSessionAttributes(SessionStatus sessionStatus){
sessionStatus.setComplete();
return "result";
}
}
通过@ModelAttributes和@SessionAttributes共同添加至session中的数据,只会添加一次
在没用使用SessionStatus清除过之前,通过@ModelAttributes和@SessionAttributes共同添加至session中的数据并不会更新,如下例:
@Controller
@RequestMapping("/testSessionAttribute")
@SessionAttributes(value = {"user","age","name"})
public class TestSessionAttributeController { public static int age = 29;
@ModelAttribute("user")
public User addUser(){
User user = new User();
user.setName("James");
user.setAge(age++);
return user;
} @RequestMapping("/testHandler")
public String testHandler(Model model, String age, String name){
model.addAttribute("age",age);
model.addAttribute("name",name);
System.out.println(age);
System.out.println(name);
return "result";
} }
<body>
${sessionScope.user.age}
${sessionScope.user.name}
<br/>
${sessionScope.age}
${sessionScope.name}
</body>
第一次请求:http://localhost:8080/testSessionAttribute/testHandler.action?name=James&age=29
结果:
29 James
29 James
第二次请求:http://localhost:8080/testSessionAttribute/testHandler.action?name=James&age=30
29 James
30 James
原因是,在org.springframework.web.bind.annotation.support.HandlerMethodInvoker#invokeHandlerMethod中进行了如下操作:
public final Object invokeHandlerMethod(Method handlerMethod, Object handler,
NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception { Method handlerMethodToInvoke = BridgeMethodResolver.findBridgedMethod(handlerMethod);
try {
boolean debug = logger.isDebugEnabled();
for (String attrName : this.methodResolver.getActualSessionAttributeNames()) {
8 Object attrValue = this.sessionAttributeStore.retrieveAttribute(webRequest, attrName);
9 if (attrValue != null) {
10 implicitModel.addAttribute(attrName, attrValue);
11 }
}
for (Method attributeMethod : this.methodResolver.getModelAttributeMethods()) {
Method attributeMethodToInvoke = BridgeMethodResolver.findBridgedMethod(attributeMethod);
Object[] args = resolveHandlerArguments(attributeMethodToInvoke, handler, webRequest, implicitModel);
if (debug) {
logger.debug("Invoking model attribute method: " + attributeMethodToInvoke);
}
String attrName = AnnotationUtils.findAnnotation(attributeMethod, ModelAttribute.class).value();
20 if (!"".equals(attrName) && implicitModel.containsAttribute(attrName)) {
21 continue;
22 }
ReflectionUtils.makeAccessible(attributeMethodToInvoke);
Object attrValue = attributeMethodToInvoke.invoke(handler, args);
if ("".equals(attrName)) {
Class<?> resolvedType = GenericTypeResolver.resolveReturnType(attributeMethodToInvoke, handler.getClass());
attrName = Conventions.getVariableNameForReturnType(attributeMethodToInvoke, resolvedType, attrValue);
}
if (!implicitModel.containsAttribute(attrName)) {
implicitModel.addAttribute(attrName, attrValue);
}
}
Object[] args = resolveHandlerArguments(handlerMethodToInvoke, handler, webRequest, implicitModel);
if (debug) {
logger.debug("Invoking request handler method: " + handlerMethodToInvoke);
}
ReflectionUtils.makeAccessible(handlerMethodToInvoke);
return handlerMethodToInvoke.invoke(handler, args);
}
catch (IllegalStateException ex) {
// Internal assertion failed (e.g. invalid signature):
// throw exception with full handler method context...
throw new HandlerMethodInvocationException(handlerMethodToInvoke, ex);
}
catch (InvocationTargetException ex) {
// User-defined @ModelAttribute/@InitBinder/@RequestMapping method threw an exception...
ReflectionUtils.rethrowException(ex.getTargetException());
return null;
}
}
如8-11行所示,在执行被@ModelAttributes注解的方法前,会将上一次通过@SessionAttributes添加至session中的数据添加添加至model中;
第20-22行,在执行被@ModelAttributes注解的方法前,springMVC会判断model中是否已经包含了@ModelAttributes给出的attrName,如果包含,则被@ModelAttributes注解的方法则不再执行
SpringMVC @SessionAttributes 使用的更多相关文章
- SpringMVC @SessionAttributes注解
@SessionAttributes 注解只能作用到类上 @SessionAttributes(value={"user"},types={String.class}) @Sess ...
- SpringMVC SessionAttributes 简述
使用SpringMVC时,我们会发现网络上有关SessionAttributes注解的内容非常少,更多的人甚至推荐你继续用HttpServletRequest中的session管理方法来控制Sessi ...
- SpringMVC @SessionAttributes 使用详解以及源码分析
@sessionattributes @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Docum ...
- SpringMVC中的常用注解
RequestParam 作用: 用于 将请求参数区数据 映射到 功能处理方法的参数上. 属性: value 请求参数中的名称 required 请求参数中是否必须提供此参数. 默认值: ...
- SpringMVC实例及注解(二)
@RequestMapping()除了修饰方法,还可以修饰类1.类定义处:提供初步的请求映射信息.相对于WEB应用的根目录2.方法处:提供进一步的细分映射信息.相对于类定义处的URL.若类定义处未标注 ...
- Spring MVC 学习笔记(二)
6. 视图和视图解析器 ❤ Spring MVC如何解析视图 • 请求处理方法执行完成后,最终返回一个ModelAndView对象 ...
- Spring MVC 学习笔记(一)
• 1.SpringMVC概述 • 2.SpringMVC的HelloWorld • 3.使用@RequestMapping映射请求 • 4.映射请求参数&请求头 • 5.处理模型数据 • 6 ...
- 在SpringMVC中使用@SessionAttributes和@ModelAttribute将数据存储在session域中
今天在我的springMVC项目--图书管理系统中,希望在登录时将登录的Users存在session中,开始是准备在controller中使用Servlet API中的对象,可是一直无法引用,不知道为 ...
- SpringMVC(十六) 处理模型数据之SessionAttributes
@SessionAttributes原理 默认情况下Spring MVC将模型中的数据存储到request域中.当一个请求结束后,数据就失效了.如果要跨页面使用.那么需要使用到session.而@Se ...
随机推荐
- FreeRTOS任务函数
FreeRTOS的任务函数原型如下:void ATaskFunction(void *pvParameters); void ATaskFunction(*pvParameters){;; //函数可 ...
- linux中断源码分析 - 中断发生(三)
本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 回顾 上篇文章linux中断源码分析 - 初始化(二)已经描述了中断描述符表和中断描述符数组的初始化,由于在初始 ...
- curl发送json格式数据
php的curl方法详细的见官方手册. curl_setopt用法: http://www.php.net/manual/en/function.curl-setopt.php <?php $ ...
- MSComm控件与Win32 API操作串口有何区别?
MSComm控件与Win32 API操作串口有何区别? [问题点数:50分,结帖人shell_shell] 收藏帖子 回复 我是一个小兵,在战场上拼命! 结帖率 83.33% 我以前用MSCo ...
- linux应用编程之进程间同步
一.描述 在操作系统中,异步并发执行环境下的一组进程,因为相互制约关系,进而互相发送消息.互相合作.互相等待,使得各进程按一定的顺序和速度执行,称为进程间的同步.具有同步关系的一组并发进程,称为合作进 ...
- vue 动态加载组建
<component :is="comp1"></component> data () { return { comp1:'', } } require.e ...
- Luogu P1129 [ZJOI2007]矩阵游戏
题目意思还是比较直观的,而且这个建模的套路也很明显. 我们首先考虑从主对角线可以转移到哪些状态. 由于每一次操作都不会把同一行(列)的黑色方块分开.因此我们发现: 只要找出\(n\)个黑色棋子,让它们 ...
- PV原语操作详解
from http://www.blogjava.net/wxqxs/archive/2009/05/10/277320.html PV原语通过操作信号量来处理进程间的同步与互斥的问题.其核心就是一段 ...
- WD与循环 组合数学
WD与循环 LG传送门 为什么大家都是先算\(n\)个数的和等于\(m\)的情况再求前缀和? 既然已经想到了插板法,为什么不直接对\(n\)个数的和\(\le m\)的情况做呢? 基本套路没有变:考虑 ...
- [React]全自动数据表格组件——BodeGrid
表格是在后台管理系统中用的最频繁的组件之一,相关的功能有数据的新增和编辑.查询.排序.分页.自定义显示以及一些操作按钮.我们逐一深入进行探讨以及介绍我的设计思路: 新增和编辑 想想我们最开始写新增 ...