先看一个没有使用@ModelAttribute的Controller方法.

  1. @RequestMapping("/save")
  2. public String save(User user) {
  3. user.setUsername("U love me");
  4. userService.save(user);
  5. return "result";
  6. }

其中User包含id和username两个私有属性,含有公共setter和getter方法.
执行此方法时会将key为"user"(注意:这里即使参数名称是user1,key一样还是"user"),value为user的对象加入到model.在jsp页面可以通过${user.id}和${user.name}得到值的,即上面方法和下面方法是相当的.

  1. @RequestMapping("/save")
  2. public String save(Model model,int id,String username) {
  3. User user=new User();
  4. //这里是通过反射从request里面拿值再set到user
  5. user.setId(id);
  6. user.setUsername(username);
  7. model.addAttribute("user",user);
  8. user.setUsername("U love me");
  9. userService.save(user);
  10. return "result";
  11. }

一.下面再来看看@ModelAttribute的基本用法.
1.在方法上使用@ModelAttribute

  1. @ModelAttribute("user1")
  2. public User addUser(User user) {
  3. return new User(520,"I love U");
  4. }

假设此方法是写在UserController内,那么执行UserController内带有@RequestMapping的方法之前,都会先执行此addUser方法.并且执行addUser过程中会添加两个对象到model,先将key为"user"的对象(由addUser方法的User user引起的),再添加key为"user1"的对象(由注解@ModelAttribute("user1")引起的).

2.在方法参数上使用@ModelAttribute.

  1. @RequestMapping("/save")
  2. public String save(@ModelAttribute User user) {
  3. user.setUsername("U love me");
  4. userService.save(user);
  5. return "result";
  6. }

此方法会先从model去获取key为"user"的对象,如果获取不到会通过反射实例化一个User对象,再从request里面拿值set到这个对象,然后把这个User对象添加到model(其中key为"user").
使用了@ModelAttribute可修改这个key,不一定是"user",此情况下,用与不用@ModelAttribute没有区别.

3.再来看看在方法和方法参数上结合使用@ModelAttribute,即上面两步的两个方法都添加UserController,如下:

  1. @ModelAttribute("user1")
  2. public User addUser(User user) {
  3. return new User(520,"I love U");
  4. }
  5. @RequestMapping("/save")
  6. public String save(@ModelAttribute User user) {
  7. user.setUsername("U love me");
  8. userService.save(user);
  9. return "result";
  10. }

假设要执行保存用户操作,根据一分析可知,先执行完会产生两个User类型的对象(一个key是"user",另一个key是"user1")添加到model,再执行save方法,此时会先从model去找key为"user"的对象,能找到再从request取值set到这个User对象.最后返回到jsp页面,model里也只有两个User类型对象.
再来个小小假设,将上面@ModelAttribute("user1")的user1改为user,其它不变.虽然执行了addUser方法,那么执行到save方法内,user对象的字段值还是来源于请求,最后返回到jsp页面,model里也只有一个User类型对象.

4.另类:

  1. @ModelAttribute
  2. @RequestMapping("/save")
  3. public String save(@ModelAttribute User user) {
  4. user.setUsername("U love me");
  5. userService.save(user);
  6. return "result";
  7. }

此种情况,会添加一个key为"user"的User对象到model,还会添加一个key为"string",value为"result"的对象到model,而视图名称则变为了"save"而不是"result".相信一般开发者都不会这样用.

二.下面再看看结合@SessionAttributes的用法.

1.先看看这段代码

  1. @Controller
  2. @RequestMapping("user")
  3. @SessionAttributes("test")
  4. public class UserController {
  5. @RequestMapping(value = "test1")
  6. public String test1(Map<String, Object> model, SessionStatus sessionStatus) {
  7. model.put("test","something");
  8. //sessionStatus.setComplete();
  9. return "user/list";
  10. }
  11. @RequestMapping(value = "test2")
  12. public String test2(Map<String,?>  model) {
  13. Object test = model.get("test");
  14. System.out.println(test);
  15. return "user/list";
  16. }
  17. }
 

在类级别上使用@SessionAttributes("test"),它的作用是在controller共享 model 属性,直到调用org.springframework.web.bind.support.SessionStatus#setComplete会清除此session值.否则长期保留(session过期,这个值也不再保留).因此先调用/user/test1,再调用/user/test2.在test2方法能得到test1方法put进去的值.当移除上面的注解,因为属性为test的session也被清除了,所以test2方法会得到是null.

2.再看结合@ModelAttribute的用法.

  1. @Controller
  2. @RequestMapping("user")
  3. @SessionAttributes("test")
  4. public class UserController {
  5. @RequestMapping(value = "test1")
  6. public String test1(HttpServletRequest request) {
  7. User user = new User("xiejx618");
  8. request.getSession().setAttribute("test",user);
  9. return "user/list";
  10. }
  11. @RequestMapping(value = "test2")
  12. public String test2(@ModelAttribute("test") User user,SessionStatus sessionStatus) {
  13. System.out.println(user.getUsername());
  14. sessionStatus.setComplete();
  15. return "user/list";
  16. }
  17. }

一样先调用/user/test1,再调用/user/test2.在test2方法能得到test1方法set进去的值.使用了@SessionAttributes,如果在controller的方法参数上有@ModelAttribute,那么此方法会确保属性test的session会存在,否则会抛org.springframework.web.HttpSessionRequiredException异常,即上面代码先不调/user/test1,直接调/user/test2就会抛此异常

我个人很少这样用,用原始的写法就清晰很多了,但要看明白别人写的代码。

springmvc的ModelAttribute注解的更多相关文章

  1. SpringMVC的@ModelAttribute注解简单使用(用户修改信息)

    例如有一个User对象,我们要修改他的值,但是不能修改他的密码!通过表单提交数据之后,password为null,会把原对象的passwod覆盖掉.这时候可以用@ModelAttribute注解处理. ...

  2. SpringMvc中@ModelAttribute注解的使用

    一.绑定请求参数到指定对象 public String test1(@ModelAttribute("user") UserModel user) 只是此处多了一个注解@Model ...

  3. (七)springmvc之ModelAttribute注解

    一.没有使用@ModelAttribute的Controller方法. @RequestMapping("/save") public String save(User user) ...

  4. springmvc中ModelAttribute注解应用在参数中

    可以用@ModelAttribute来注解方法参数或方法.带@ModelAttribute创建的参数对象会被添加到Model对象中.注解在参数上时,可以从Form表单或URL参数中获取参数并绑定到mo ...

  5. SpringMVC @ModelAttribute注解

    /**     * 1. 有 @ModelAttribute 标记的方法, 会在每个目标方法执行之前被 SpringMVC 调用!      * 2. @ModelAttribute 注解也可以来修饰 ...

  6. 7、SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解

    从上一篇 SpringMVC源码分析(1) 中我们了解到在DispatcherServlet.doDispatch方法中会通过 mv = ha.handle(processedRequest, res ...

  7. SpringMVC(十七-二十) ModelAttribute 注解

    有点难理解. 修饰方法是表示在该控制器的所有目标方法执行前都执行该modelattribute注解的方法. 修饰参数是表示什么?修饰参数时@modelattributes(value="xx ...

  8. @ModelAttribute注解(SpringMVC)

    在方法定义上使用 @ModelAttribute 注解:Spring MVC 在调用目标处理方法前,会先逐个调用在方法级上标注了 @ModelAttribute 的方法. 在方法的入参前使用 @Mod ...

  9. springmvc在使用@ModelAttribute注解获取Request和Response会产生线程并发不安全问题(转)

    springmvc在获取Request和Response有很多方式:具体请看:https://www.cnblogs.com/wade-luffy/p/8867144.html 产生线程问题的代码如下 ...

随机推荐

  1. 你真的了解interface和内部类么

    java 访问控制符 private     : 只能被当前类访问 protected : 可以被同包的类和任何子类访问(包内,包外) default    : 可以被包内的任何内访问 public  ...

  2. SpringMVC【校验器、统一处理异常、RESTful、拦截器】

    前言 本博文主要讲解的知识点如下: 校验器 统一处理异常 RESTful 拦截器 Validation 在我们的Struts2中,我们是继承ActionSupport来实现校验的...它有两种方式来实 ...

  3. select函数的介绍和使用

    我们所使用的I/O模型一共有五种. 分别为阻塞I/O,非阻塞I/O,I/O复用,信号驱动I/O,异步I/O. 所谓I/O复用就是指管理多个I/O文件描述符,一般会使用(select,poll,epol ...

  4. docker学习系列(五):使用docker创建集成服务--lnmp

    在掌握了docker的基本命令之后,我也是想着去用docker做一点实际的配套环境,就拿自己最常用的lnmp环境来做测试.配套环境运行的顺序依次是mysql->php->nginx,至于为 ...

  5. 20165226 预备作业3 Linux安装及学习

    20165226 预备作业3 Linux安装及学习 Linux安装 一.下载安装VirtualBox 1.首先在官网下载,点开基于VirtualBox虚拟机安装Ubuntu图文教程 找到版本进行下载安 ...

  6. 手机端原生js实现下拉刷新数据

    HTML结构如下: <div class="outerScroller comment"> <div class='scroll comment'> < ...

  7. mac下利用Breakpad的dump文件进行调试

    一.前情回顾 最近把公司的一个视频处理程序更新了一个版本,准备提交测试的发现了崩溃的情况.这个程序采用Qt和ffmpeg技术栈开发,主要用于对视频进行渲染拼接处理,在Windows和mac两个平台同时 ...

  8. phpStorm安装方法

    1)下载 http://big2.h5gamen.com/soft/jetbrainscrack-2.6.2.zip 放到phpstorm安装目录下的lib文件夹 如放到f盘 F:\PhpStorm ...

  9. TPYBoard v102 DIY照相机(视频和制作流程)

    前段时间的帖子,利用TPYBoard v102做的DIY照相机,周末实物终于做出来了,加了两个按键模块和一个5110,做的有点糙啊----望大家勿怪,哈哈哈.拍出来图片还算清晰,串口摄像头模块用的30 ...

  10. DB2开发系列之三——SQL函数

    1.内置函数分类(SYSIBM模式内) 1)标量函数:返回一个标量值的函数: 2)聚合函数:也叫列函数,也返回一个标量值,这个值是一组输入值的计算结果:3)表函数:向引用它的 SQL 语句返回一个表: ...