SpringMVC常用注解之@ModelAttribute
@ModelAttribute
@ModelAttribute最主要的作用是将数据添加到模型对象中,用于视图页面展示时使用。@ModelAttribute等价于 model.addAttribute("attributeName", abc); 但是根据@ModelAttribute注释的位置不同,和其他注解组合使用,致使含义有所不同。
@ModelAttribute和@RequestMapping分开修饰方法时,@ModelAttribute会优先于@RequestMapping执行,也就是会在Controller中每个方法执行前被执行,所以当一个Controller中有映射到多个Url时,需要谨慎使用;但是@ModelAttribute和@RequestMapping同事修饰一个方法时和他们单独修改方法时所代表的的意思是不同的,这一点要特别注意。
属性介绍:
- value:类型是为String,代表绑定的属性名称
使用方式:
- 方法返回值为void,@ModelAttribute注解没有指定任何属性,这样的话需要将Model或者map传入方法中,如下:key为user1,value为User对象,可以用 ${requestScope.user1.userName} 取出
@ModelAttribute
//@ModelAttribute 没有指定值,且被修饰的方法返回值为void,则需要借助map或者model将数据模型放入request域
public void getUser(Map<String, Object> map) {
System.out.println("ModelAttribute1..");
map.put("user1", new User("kelin","123aaa"));
}
2.方法返回值为普通的pojo,@ModelAttribute注解没有指定任何属性,这样的话,request域中存入的对象名字默认为类型首字母小写,如下:key为user(类型首字母小写),value为User对象,可以用 ${requestScope.user.userName} 取出
注意:当@ModelAttrbute修改方法时,这里是将返回数据user1对象放到model模型中而不是将方法上的参数userName和age放到model模型中返回给页面中使用
@ModelAttribute //@ModelAttribute 没有指定值,且被修饰方法有pojo类型的返回值,则request域中 key为返回值类型第一个字母小写的字符串,value为返回值 public User getUser(@RequestParam("userName") String userName,@RequestParam("age") int age) {
User user1=new User();
user.setUserName(userName);
user.setAge(age);
return user1;
}
3.方法返回值为普通的pojo,@ModelAttribute注解指定了value属性,这样的话,request域中就放入了一个对象,如下:key为user2,value为User对象,可以用 ${requestScope.user2.userName} 取出
@ModelAttribute("user2")
//@ModelAttribute 的值就是request域中的key,被该注解修饰的方法的返回值为对应的value
public User getUser() {
System.out.println("ModelAttribute3..");
return new User("kelin","123aaa");
}
4.@ModelAttribute 修饰方法参数(最常用),参数直接封装到对象中,比如常用的 pageNo,pageSize..,
注意:这里@ModelAttribute修饰的是方法上的参数,这里是直接将user参数放到了model模型中返回到页面中使用,而return的字符窜“modelAttribute”其实就是视图文件名
/*
* @ModelAttribute用于修饰入参,前台传过来的值自动赋予入参对于的属性
*/
@RequestMapping("/testModelAttribute5")
public String testModelAttribute(@ModelAttribute User user) {
return "modelAttribute";
}
5.两个注解同时修饰方法,看注释解释,有点不一样,返回的东西不是视图,而是request域中的值,返回的视图变成了 @RequestMapping中指定的value
/*
* @ModelAttribute 和 @RequestMapping 同时修饰一个方法
*
* @ModelAttribute 中value为 request域中的key,被修饰的方法返回值为request域中的value
* @RequestMapping 中value为 返回的视图名,此例中相当于定向到xxx/testModelAttribute4.jsp
*/
@ModelAttribute(value="user")
@RequestMapping(value="/testModelAttribute4")
public User testModelAttribute() {
return new User("kelin","123aaa");
}
6.@ModelAttribute注释一个方法的返回值,
大家可以看到返回值类型是对象类型,而且通过 @ModelAttribute("user2") 注解,此时会添加返回值到模型数据( 名字为user2 ) 中供视图展示使用@ModelAttribute 注解的返回值会覆盖 @RequestMapping 注解方法中的 @ModelAttribute 注解的同名命令对象
@Controller
public class HelloWorldController {
@RequestMapping(value = "/helloWorld")
public @ModelAttribute("user2") User helloWorld(@ModelAttribute User user) {
return new User();
}
}
以上都是针对一个controller类中只有一个被@ModelAttribute修改的方法,如果一个controller中除了有@ModelAttribute修饰的方法还有被@RequestMapping修饰的方法有事如何工作的?
我们知道在一个controller中当我们调用任何一个被@RequestMapping修饰的方法时都会先执行被@ModelAttribute修饰的方法
1.
@Controller
public class ModelAttributeController{
@ModelAttribute("loginname")
public String userModelfirst(@ResquestParam("loginname") String loginname){
//返回的参数赋值给value变量
return loginname;
}
@RequestMapping(vaule="/loginfirst")
public String loginfirst(){
//返回到结果界面
return "resultfirst";
}
}
这里注解@ModelAttribute注解默认vaule值为“loginname”,指定model的属性名称,属性的值就是@ModelAttribute注解的方法的返回值。他把请求参数loginname的值通过@ResquestParam赋值给变量loginname,然后再设置一个名为loginname的属性到Model中,属性值就是userModelfirst方法的返回值。
因为@ModelAttribute优先于@RequestMapping执行,所以当访问URL“/loginfirst”时会先执行@ModelAttribute注解的方法,在resultfirst.jsp中用EL表达式得到${resquestScope.loginname}获取。
上面的这种写法和下面这种写法是等价的
@Controller
public class ModelAttributeController{
@ModelAttribute
public void userModelsecond(@ResquestParam("loginname") String loginname,Model model){
model.addAttribute("loginname",loginname);
}
@RequestMapping(vaule="/loginsecond")
public String loginsecond(){
//返回到结果界面
return "resultsecond";
}
}
2.
@Controller
@RequestMapping("/modelAttributeController") public class ModelAttributeController{ @ModelAttribute("user") public String userModelfourth(@ResquestParam("loginname") String loginname){ User user1 = new User(); user1.setLoginame(loginname); return user1; } @RequestMapping(vaule="/loginfourth") public String loginfourth( @ModelAttribute("user") User user){ //返回到结果界面 user.setUsername("test"); return "resultfourth"; } }
当我们请求localhost:8080/modelAttributeController/loginfourth?loginname=lisi时,会先执行userModelfourth方法,同时会把lisi赋值给此方法的loginname参数,然后生成一个user对象,并且在model中会有一个key为user,value为user1的数据,然后才会执行loginfourth方法,同时将model中key为user的数据复制给loginfourth方法中user参数,然后在resultfourth.jsp的页面上可以通过${resquestScope.user.username}来获取相应的数据。