Spring MVC SessionAttributes ModelAttribute注…
2018-08-05 07:46:06来源:博客园 阅读 ()
说明
本文主要针对 @SessionAttributes注解 和 @ModelAttribute注解的基础用法进行解析。至于为什么会将这两个注解放在一起,是因为它们之间还是有点影响的。
@SessionAttributes
光看这个注解的名字大概也就知道这个注解是用于往 Session 域中存数据的吧!这个注解是 Spring2.5版本才有的。
属性
① value:
一个字符串数组,表示存放到 Session 域中的属性名
② names: (这个属性是 4.2版本才有的)
和 value 属性一样,他们之间是彼此的别名而已
③ type:
一个 Class 数组,根据指定的类型,将模型中对应类型的数据放到 Session 域中
属性对应源码
用法
注意:@SessionAttributes 注解只能用在类上面。
package com.test; import *; @Controller @SessionAttributes(value={"name", "age"}, types={String.class}) //value 换成 names 一样的效果 public class SessionAttribute { @RequestMapping("/testSessionAttribute1") public String testSessionAttribute1(Map<String, Object> map) { //name 属性被放入了 value 数组中,所以也就存入了 Session 域中 map.put("name", "张三"); //age 属性放入了 names 数组中,也一样存入了 Session 域中 map.put("age", 19); //由于 types 数组中有 String.class,所以,address 属性也会放入 Session 域中 map.put("address", "重庆市"); return "success"; } }
页面显示:
注意:value 属性不能和 names 属性一起使用,如果一起使用了会出现下面异常信息
org.springframework.core.annotation.AnnotationConfigurationException: In annotation [org.springframework.web.bind.annotation.SessionAttributes] declared on class com.test.SessionAttribute and synthesized from [@org.springframework.web.bind.annotation.SessionAttributes(names=[age], value=[name], types=[class java.lang.String])], attribute 'names' and its alias 'value' are present with values of [{age}] and [{name}], but only one is permitted.
@ModelAttribute
修饰方法
注意:有 @ModelAttribute 注解修饰的方法,会在 Controller 中的每个方法执行之前都执行一次。
① 修饰没有返回值的方法
上面这个方法被 @ModelAttribute 注解所修饰,且没有返回值。但是,在方法的入参处有一个 map 集合,且在方法内部向 mpa 中放入了一个键值对。
执行完了 isNotReturn() 方法后,就会接着来到 isNotReturnTest() 方法,该方法重定向到了 success.jsp 页面,那么,map 集合中存放的数据也会在 request 域中被带到页面上。
最后从 request 域中获取 tom,页面输出:
上面两个方法可合并为一个方法:
执行该方法就会向 map 中放入一个键值对,并且转发到 success.jsp 页面,且将数据通过 request 域带到页面。
② 修饰有返回值的方法
//修饰有返回值的方法 @ModelAttribute(value="argtest") public String havaArg(Map<String, Object> map, Model model) { /* * 下面这种情况,返回值会被默认放到隐藏的 Model 中,在 Model 中的 key默认为 返回值的首字母小写, * 可以通过 ModelAttribute 注解的 value 属性设置 * value 为返回的值 * model.addAttribute("string", "值"); */ //map.put("arg", "修饰有返回值的方法"); model.addAttribute("modelTest", "model 测试"); return "修饰有返回值的方法"; }
注释中已经说的很清楚了,上面方法中,返回了一个字符串,那么在 model 中就会以下面的方式将 这个字符串存入 model:
model.addAttribute("string", 修饰有返回值的方法");
由于默认以返回值的首字母小写作为 key,这样可定有一定局限性,所以我们可以再 @ModelAttribute 注解中加上 value 属性标明返回值在 model 中的 key,还是上面的例子来说,加上 value 属性值后就是
model.addAttribute("argtest", 修饰有返回值的方法");
修饰参数
//修饰参数,就是从 Model 中获取对应的属性值 @RequestMapping("/updateUserInfo") public String updateUserInfo(User user, @ModelAttribute("modelTest") String modelTest, @ModelAttribute(value="argtest") String argtest) { System.out.println("ModelAttribute修改参数:"+modelTest); System.out.println("ModelAttribute修改参数:"+argtest); return SUCCESS; }
上面方法输出内容如下:
这里输出的内容就是我们上面 做修饰有返回值方法时放入的值。那么, @ModelAttribute 注解修饰参数就代表从 Model 中获取对应属性名的值。
修饰被 @RequestMapping 注解修饰的方法
@RequestMapping("/test2") @ModelAttribute public String test2() { System.out.println("修饰有 RequestMapping修饰的方法");
//这里返回的 "success" 就不在代表视图了,而是 RequestMapping 注解的 value 属性值才代表视图 return SUCCESS; }
可见上面 test2() 方法上有两个注解,那么,这个方法就不会在每次访问 Controller 时都会执行了。因为不是每次执行 Controller 都会执行该方法,所以,返回的 "success"字符串也不会被放入 Model 中(就会是一个无效的操作)。同时,返回值 "success" 也不代表视图,此时对应的页面就是 RequestMapping 注解对应的值 "test2",所以,在访问 "/test2" 来到 test2() 方法后,返回回去的路径为 test2.jsp,由于没有该页面,出现 404。
上面内容讲解了 SessionAttributes 注解和 ModelAttribute 注解各自的基本用法,下面就来看看他俩放在一起使用可能会出现什么问题
SessionAttributes 注解和 ModelAttribute 注解一起使用
情况一
@Controller @SessionAttributes(value= {"name"}) public class Test { //执行该 方法后,会将 name属性放入 Model 中和 Session 中
//只要 ModelAttribute 属性值和 SessionAttributes 注解 value 属性其中一个属性值一致,那么,ModelAttribute 修饰方法返回值也会被放入 Session 中 @ModelAttribute("name") public String getName() { return "李四"; } }
情况二
import *; @Controller
@SessionAttributes(value= {"userInfo"}) public class Test {/* 这段代码什么意思: 页面上存在一个表单,当点击提交后,整个表单中的数据就会自动封装为一个 UserInfo 对象,并传递到 Handler 方法中,输出,最后跳转到 "success.jsp" 页面,同时将 UserInfo 对象 放到 Session 域中 */ @RequestMapping("/test2") public String test2(@ModelAttribute("userInfo") UserInfo userInfo) { System.out.println("修改方法:"+userInfo); return "success"; } }
但是,上面代码执行会出错的。会抛出下面异常信息:
org.springframework.web.HttpSessionRequiredException: Expected session attribute 'userInfo' //Session 中不存在 userInfo 属性
解决办法
一、将 目标方法 即代码中 test2() 方法 的 @ModelAttribute("userInfo") 中的 userInfo 改名,只要不和 SessionAttributes 注解中的名字一样就可以了。
二、目标方法 即代码中 test2() 方法 的 @ModelAttribute("userInfo") 去掉,添加一个对应的被 ModelAttribute 修饰的方法。
import *; @Controller @SessionAttributes(value= {"userInfo"}) public class Test { @ModelAttribute public void getUserInfo(UserInfo userInfo, Model model) { model.addAttribute("userInfo", userInfo); }
@RequestMapping("/test2") public String test2(UserInfo userInfo) { System.out.println("修改方法:"+userInfo); return "success"; } }
这里只做了一个简单的处理介绍,关于更详细的原因,我会在后面说明。还得下去多了解一下源码过程!
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Spring系列.ApplicationContext接口 2020-06-11
- springboot2配置JavaMelody与springMVC配置JavaMelody 2020-06-11
- 给你一份超详细 Spring Boot 知识清单 2020-06-11
- SpringBoot 2.3 整合最新版 ShardingJdbc + Druid + MyBatis 2020-06-11
- 掌握SpringBoot-2.3的容器探针:实战篇 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash