一、首先说一下 @ModelAttribute @ModelAttribute 绑定请求参数到命令对象
@ModelAttribute一个具有如下三个作用:
①绑定请求参数到命令对象:放在功能处理方法的入参上时,用于将多个请求参数绑定到一个命令对象,从而简化绑
定流程,而且自动暴露为模型数据用于视图页面展示时使用;
②暴露表单引用对象为模型数据:放在处理器的一般方法(非功能处理方法)上时,是为表单准备要展示的表单引用
对象,如注册时需要选择的所在城市等,而且在执行功能处理方法(@RequestMapping 注解的方法)之前,自动添加
到模型对象中,用于视图页面展示时使用;
③暴露@RequestMapping 方法返回值为模型数据:放在功能处理方法的返回值上时,是暴露功能处理方法的返回值为
模型数据,用于视图页面展示时使用。
如下是从spring API上面摘录的点击查看官方API文档
1.1 方法外的注释
Using @ModelAttribute on a method
The @ModelAttribute annotation can be used on methods or on method arguments. This section explains its usage on methods while the next section explains its usage on method arguments.
An @ModelAttribute on a method indicates the purpose of that method is to add one or more model attributes. Such methods support the same argument types as @RequestMapping methods but cannot be mapped directly to requests. Instead @ModelAttribute methods in a controller are invoked before @RequestMapping methods, within the same controller. A couple of examples:
// Add one attribute
// The return value of the method is added to the model under the name "account"
// You can customize the name via @ModelAttribute("myAccount")
@ModelAttribute
public Account addAccount(@RequestParam String number) {
return accountManager.findAccount(number);
}
// Add multiple attributes
@ModelAttribute
public void populateModel(@RequestParam String number, Model model) {
model.addAttribute(accountManager.findAccount(number));
// add more ...
}
@ModelAttribute methods are used to populate the model with commonly needed attributes for example to fill a drop-down with states or with pet types, or to retrieve a command object like Account in order to use it to represent the data on an HTML form. The latter case is further discussed in the next section.
Note the two styles of @ModelAttribute methods. In the first, the method adds an attribute implicitly by returning it. In the second, the method accepts a Model and adds any number of model attributes to it. You can choose between the two styles depending on your needs.
A controller can have any number of @ModelAttribute methods. All such methods are invoked before @RequestMapping methods of the same controller.//所有 被 @ModelAttribute 标记的方法都将先执行
@ModelAttribute methods can also be defined in an @ControllerAdvice-annotated class and such methods apply to many controllers. See the the section called “Advising controllers with the @ControllerAdvice annotation” section for more details.
如果一个 model attribute 没有被显示申明出来。
What happens when a model attribute name is not explicitly specified? In such cases a default name is assigned to the model attribute based on its type. For example if the method returns an object of type Account, the default name used is "account". You can change that through the value of the @ModelAttribute annotation. If adding attributes directly to the Model, use the appropriate overloaded addAttribute(..) method - i.e., with or without an attribute name.
1.2 方法内的注释
Using @ModelAttribute on a method argument
An @ModelAttribute on a method argument indicates the argument should be retrieved from the model. If not present in the model, the argument should be instantiated first and then added to the model. Once present in the model, the argument’s fields should be populated from all request parameters that have matching names. This is known as data binding in Spring MVC, a very useful mechanism that saves you from having to parse each form field individually.
@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(@ModelAttribute Pet pet) { }
实例化pet 的三种方法:
1.2.1 It may already be in the model due to use of @SessionAttributes
see the section called “Using @SessionAttributes to store model attributes in the HTTP session between requests”.
1.2.2 It may already be in the model due to an @ModelAttribute method in the same controller — as explained in the previous section.
1.2.3 It may be retrieved based on a URI template variable and type converter (explained in more detail below).
1.2.4 It may be instantiated using its default constructor.
1.3 URI template variable
@RequestMapping(value="/accounts/{account}", method = RequestMethod.PUT)
public String save(@ModelAttribute("account") Account account) {
}
In this example the name of the model attribute (i.e. "account") matches the name of a URI template variable. If you register Converter<String, Account> that can turn the String account value into an Account instance, then the above example will work without the need for an @ModelAttribute method.