@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>

通过实例可以得出一下结论:

  1. 不论是利用@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 使用的更多相关文章

  1. SpringMVC @SessionAttributes注解

    @SessionAttributes 注解只能作用到类上 @SessionAttributes(value={"user"},types={String.class}) @Sess ...

  2. SpringMVC SessionAttributes 简述

    使用SpringMVC时,我们会发现网络上有关SessionAttributes注解的内容非常少,更多的人甚至推荐你继续用HttpServletRequest中的session管理方法来控制Sessi ...

  3. SpringMVC @SessionAttributes 使用详解以及源码分析

    @sessionattributes @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Docum ...

  4. SpringMVC中的常用注解

    RequestParam 作用: 用于  将请求参数区数据  映射到  功能处理方法的参数上. 属性: value  请求参数中的名称 required   请求参数中是否必须提供此参数. 默认值: ...

  5. SpringMVC实例及注解(二)

    @RequestMapping()除了修饰方法,还可以修饰类1.类定义处:提供初步的请求映射信息.相对于WEB应用的根目录2.方法处:提供进一步的细分映射信息.相对于类定义处的URL.若类定义处未标注 ...

  6. Spring MVC 学习笔记(二)

    6. 视图和视图解析器  ❤  Spring MVC如何解析视图                                  • 请求处理方法执行完成后,最终返回一个ModelAndView对象 ...

  7. Spring MVC 学习笔记(一)

    • 1.SpringMVC概述 • 2.SpringMVC的HelloWorld • 3.使用@RequestMapping映射请求 • 4.映射请求参数&请求头 • 5.处理模型数据 • 6 ...

  8. 在SpringMVC中使用@SessionAttributes和@ModelAttribute将数据存储在session域中

    今天在我的springMVC项目--图书管理系统中,希望在登录时将登录的Users存在session中,开始是准备在controller中使用Servlet API中的对象,可是一直无法引用,不知道为 ...

  9. SpringMVC(十六) 处理模型数据之SessionAttributes

    @SessionAttributes原理 默认情况下Spring MVC将模型中的数据存储到request域中.当一个请求结束后,数据就失效了.如果要跨页面使用.那么需要使用到session.而@Se ...

随机推荐

  1. MySQL 基础十一 事件

    1.查看事件 2.创建事件 3.执行事件,并查看执行结果是否正确 一 查看事件 -- 1.查看所有事件(显示执行频率(按年.月.日).创建日期.最后执行事件等)SELECT * FROM mysql. ...

  2. ESP32 environment ubuntu

    ubuntu官方用的是16.04版本的,阿里源下载地址:http://mirrors.aliyun.com/ubuntu-releases/16.04/     用官方版本的好处就是省的搞一堆各种错误 ...

  3. C# 程序默认使用管理员权限(转载)

    1.从A程序启动B程序,当B程序需要管理员权限的时候代码如下 A程序里面启动B程序的代码如下 ProcessStartInfo startInfo = new ProcessStartInfo(); ...

  4. POJ3714 Raid 分治/K-D Tree

    VJ传送门 简要题意:给出两个大小均为\(N\)的点集\(A,B\),试在\(A\)中选择一个点,在\(B\)中选择一个点,使得它们在所有可能的选择方案中欧几里得距离最小,求出这个距离 下面给出的两种 ...

  5. 千兆以太网TCP协议的FPGA实现

    转自https://blog.csdn.net/zhipao6108/article/details/82386355 千兆以太网TCP协议的FPGA实现 Lzx 2017/4/20 写在前面,这应该 ...

  6. 基于uFUN开发板和扩展板的联网校准时钟

    项目概述 上周在uFUN试用群里看到管理员说试用活动快结束了,要抓紧完成评测总结,看大家的评测总结也都写了,我也不能落后啊!正好最近做的扩展板到手了,于是赶紧进行调试,做了一个不用校准的时钟,时钟这种 ...

  7. openhtmltopdf 支持自定义字体、粗体

    一.支持自定义字体 private static void renderPDF(String html, OutputStream outputStream) throws Exception { t ...

  8. 基于HTML5 WebGL实现 json工控风机叶轮旋转

    突然有个想法,如果能把一些用到不同的知识点放到同一个界面上,并且放到一个盒子里,这样我如果要看什么东西就可以很直接显示出来,而且这个盒子一定要能打开.我用HT实现了我的想法,代码一百多行,这么少的代码 ...

  9. StoryLine3变量存储与跳转后台时的使用

    前言 公司项目原因,接触到storyline3(后面简称SL)课件制作工具,类似ppt,但是又多了互动.交互,且页面元素可添加触发器,触发器中可执行js代码. 1.官方教程 在SL中,会有“了解详情. ...

  10. linux-安装-源码安装

    编译安装 tengine