Spring MVC SessionAttributes ModelAttribute注解

时间:2022-03-10 19:52:38

说明

  本文主要针对 @SessionAttributes注解 和 @ModelAttribute注解的基础用法进行解析。至于为什么会将这两个注解放在一起,是因为它们之间还是有点影响的。

@SessionAttributes

  光看这个注解的名字大概也就知道这个注解是用于往 Session 域中存数据的吧!这个注解是 Spring2.5版本才有的。

 属性

    ① value:

      一个字符串数组,表示存放到 Session 域中的属性名

    ② names: (这个属性是 4.2版本才有的)

      和 value 属性一样,他们之间是彼此的别名而已

    ③ type:

      一个 Class 数组,根据指定的类型,将模型中对应类型的数据放到 Session 域中

 属性对应源码

    Spring MVC SessionAttributes ModelAttribute注解

 用法

    注意:@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";
}
}

    页面显示:

     Spring MVC SessionAttributes ModelAttribute注解

    注意: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 中的每个方法执行之前都执行一次。

    ① 修饰没有返回值的方法

      Spring MVC SessionAttributes ModelAttribute注解

    上面这个方法被 @ModelAttribute 注解所修饰,且没有返回值。但是,在方法的入参处有一个 map 集合,且在方法内部向 mpa 中放入了一个键值对。

      Spring MVC SessionAttributes ModelAttribute注解

    执行完了 isNotReturn() 方法后,就会接着来到 isNotReturnTest() 方法,该方法重定向到了 success.jsp 页面,那么,map 集合中存放的数据也会在 request 域中被带到页面上。

    最后从 request 域中获取 tom,页面输出:

       aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPgAAAAyCAIAAAD+wIGOAAACIElEQVR4nO2Y0Y6FIAwF/f+fdh82uTEgtS2Iypl5MlpLpXOru9sOIMD2dAEAM0B0kADRQQJEBwkQHSRAdJAA0UECRAcJEB0kQHSQANFBAkQHCRAdJPiG6NsWqNMZHMqZ5rhKz4pzql2Yb2xftM2e+CJmq4iV2FjimOr/IJcZ0Tv5xvbZba4dbRHK2VOtvaL9G2vFpOuBfRnRE0mMu0ZZ5Rc9FAMJvrF9/VIeBbI/UQYq5ZQV0ScQ/pa9G/93iOGuEVw81HCfcvUPLKz/EZZknui1baF7xwbfJ7qRrZUc0ScQ+COvdek0uHVLskr398l29p+N+vbCJ3vipjHKuDxOiD62X4uRmeitHhgHPZy6WwQUfSo62spZXx3b7KLytOghCx/v1ztZQXQjPmR5aBVnJdFpXcT8MiB6J28XvTX5WsHFq9lOe6vopwUYJ4v3UutH4lnXPuPsV+g18n5WEL1QZD806dJ1z8k92HVj9csB75n6l6vbZzz9Wm/GzxM9MSESE7eWrDVEQ/lz4+10o3IOIXonrseo29x61f56WZsUdcVwzlPkacH1Jf/g7BS9Pr5J9P2hfr2clz6JvcV1P/wa2eMt+uuyKyw0KgLuEx1qXrd9TgPssJwWY2W6zIboM2H7QAJEBwkQHSRAdJAA0UECRAcJEB0kQHSQANFBAkQHCRAdJEB0kADRQQJEBwkQHSRAdJAA0UECRAcJEB0kQHSQ4A/Ej6b7Yj3+OgAAAABJRU5ErkJggg==" alt="" />

    上面两个方法可合并为一个方法:

      aaarticlea/png;base64,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" alt="" />

    执行该方法就会向 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;
}

    上面方法输出内容如下:

    aaarticlea/png;base64,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" alt="" />

    这里输出的内容就是我们上面 做修饰有返回值方法时放入的值。那么, @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";
}
}

  这里只做了一个简单的处理介绍,关于更详细的原因,我会在后面说明。还得下去多了解一下源码过程!