@ModelAttribute注解详解
注解用途
@ModelAttribute
注解用于将方法的参数或方法的返回值绑定到指定的模型属性上,并返回给Web视图
注释方法
被@ModelAttribute注解注释的方法会在此Controller每个方法执行前被执行
(1)void返回值的方法
@ModelAttribute
注释void返回值的方法
@Controller
public class HelloWorldController {
@ModelAttribute // 方法参数绑定到数据模型上
public void populateModel(@RequestParam String abc, Model model) {
// 请求参数绑定到该方法的方法参数上
model.addAttribute("attributeName", abc);
} // 该方法将请求参数绑定到了数据模型上
@RequestMapping(value = "/helloWorld")
public String helloWorld() {
return "helloWorld";
}
}
控制器获得/helloWorld
请求后,被@ModelAttribute
注释的方法首先执行,将populateModel
方法获得的请求参数/helloWorld
绑定到model中名为attrituteName
的属性上(换句话说,就是将参数abc
设置为model的attributeName
属性的参数)
然后helloWorld
方法被调用,返回视图名helloWorld
,由@ModelAttribute
生产的数据模型
本例中model属性名称和model属性对象有model.addAttribute()实现,不过前提是要在方法中加入一个Model类型的参数
当URL或者post中不包含参数时,会报错,其实不需要这个方法,完全可以把请求的方法写成下面的样子,这样缺少此参数也不会出错:
@RequestMapping(value = "/helloWorld")
public String helloWorld(String abc) {
return "helloWorld";
}
(2)返回具体类的方法Ⅰ
@ModelAttribute
注释返回具体类的方法
@ModelAttribute
public Account addAccount(@RequestParam String number) {
return accountManager.findAccount(number);
}
本例中并没有指定model属性的名称,这种情况下,它由返回类型隐含表示,即返回Account类型,则model属性的名称为account。这个例子中model属性名称有返回对象类型隐含表示,model属性对象的值就是方法的返回值。它无须要特定的参数
(3)返回具体类的方法Ⅱ
@ModelAttribute("attributeName")
注释返回具体类的方法
@Controller
public class HelloWorldController {
@ModelAttribute("attributeName")
public String addAccount(@RequestParam String abc) {
return abc;
}
@RequestMapping(value = "/helloWorld")
public String helloWorld() {
return "helloWorld";
}
}
本例使用@ModelAttribute
注释,并使用注解指定的attributeName
属性来指定model属性的名称。model属性对象的值就是方法的返回值。它无须要特定的参数。
(4)同时注释一个方法
@ModelAttribute
和@RequestMapping
同时注释一个方法
@Controller
public class HelloWorldController {
@RequestMapping(value = "/helloWorld.do")
@ModelAttribute("attributeName")
public String helloWorld() {
return "hi";
}
}
虽然helloWorld
方法标注了String
返回类型,但是model属性的值,视图名称由RequestToViewNameTranslator
根据请求/helloWorld.do
转换为逻辑视图helloWorld
Model属性名称由@ModelAttribute("attributeName")
指定,相当于在request中封装了key=attributeName,value=hi
注释一个方法的参数
(1)从model中获取
@Controller
public class HelloWorldController {
@ModelAttribute("user")
public User addAccount() {
return new User("jz","123");
}
@RequestMapping(value = "/helloWorld")
public String helloWorld(@ModelAttribute("user") User user) {
user.setUserName("jizhou");
return "helloWorld";
}
}
本例中,@ModelAttribute("user") User user
注释方法参数,参数user的值来源于addAccount()
方法中的model属性。此时如果方法体没有标注@SessionAttributes("user")
,那么scope为request,如果标注了,那么scope为session
(2)从Form表单或URL参数中获取
? // 实际上,不做此注释也能拿到user对象)
@Controller
public class HelloWorldController {
@RequestMapping(value = "/helloWorld")
public String helloWorld(@ModelAttribute User user) {
return "helloWorld";
}
}
注意这时候这个User类一定要有无参数的构造函数。