浅谈 SpringMVC 数据绑定

浅谈 SpringMVC 数据绑定 – Senton – 博客频道 – CSDN.NET.

查看spring源码可以看出spring支持转换的数据类型:
org.springframework.beans.PropertyEditorRegistrySupport:

  1. /** 
  2.  * Actually register the default editors for this registry instance. 
  3.  */  
  4. private void createDefaultEditors() {  
  5.     this.defaultEditors = new HashMap<Class, PropertyEditor>(64);  
  6.   
  7.     // Simple editors, without parameterization capabilities.  
  8.     // The JDK does not contain a default editor for any of these target types.  
  9.     this.defaultEditors.put(Charset.classnew CharsetEditor());  
  10.     this.defaultEditors.put(Class.classnew ClassEditor());  
  11.     this.defaultEditors.put(Class[].classnew ClassArrayEditor());  
  12.     this.defaultEditors.put(Currency.classnew CurrencyEditor());  
  13.     this.defaultEditors.put(File.classnew FileEditor());  
  14.     this.defaultEditors.put(InputStream.classnew InputStreamEditor());  
  15.     this.defaultEditors.put(InputSource.classnew InputSourceEditor());  
  16.     this.defaultEditors.put(Locale.classnew LocaleEditor());  
  17.     this.defaultEditors.put(Pattern.classnew PatternEditor());  
  18.     this.defaultEditors.put(Properties.classnew PropertiesEditor());  
  19.     this.defaultEditors.put(Resource[].classnew ResourceArrayPropertyEditor());  
  20.     this.defaultEditors.put(TimeZone.classnew TimeZoneEditor());  
  21.     this.defaultEditors.put(URI.classnew URIEditor());  
  22.     this.defaultEditors.put(URL.classnew URLEditor());  
  23.     this.defaultEditors.put(UUID.classnew UUIDEditor());  
  24.   
  25.     // Default instances of collection editors.  
  26.     // Can be overridden by registering custom instances of those as custom editors.  
  27.     this.defaultEditors.put(Collection.classnew CustomCollectionEditor(Collection.class));  
  28.     this.defaultEditors.put(Set.classnew CustomCollectionEditor(Set.class));  
  29.     this.defaultEditors.put(SortedSet.classnew CustomCollectionEditor(SortedSet.class));  
  30.     this.defaultEditors.put(List.classnew CustomCollectionEditor(List.class));  
  31.     this.defaultEditors.put(SortedMap.classnew CustomMapEditor(SortedMap.class));  
  32.   
  33.     // Default editors for primitive arrays.  
  34.     this.defaultEditors.put(byte[].classnew ByteArrayPropertyEditor());  
  35.     this.defaultEditors.put(char[].classnew CharArrayPropertyEditor());  
  36.   
  37.     // The JDK does not contain a default editor for char!  
  38.     this.defaultEditors.put(char.classnew CharacterEditor(false));  
  39.     this.defaultEditors.put(Character.classnew CharacterEditor(true));  
  40.   
  41.     // Spring’s CustomBooleanEditor accepts more flag values than the JDK’s default editor.  
  42.     this.defaultEditors.put(boolean.classnew CustomBooleanEditor(false));  
  43.     this.defaultEditors.put(Boolean.classnew CustomBooleanEditor(true));  
  44.   
  45.     // The JDK does not contain default editors for number wrapper types!  
  46.     // Override JDK primitive number editors with our own CustomNumberEditor.  
  47.     this.defaultEditors.put(byte.classnew CustomNumberEditor(Byte.classfalse));  
  48.     this.defaultEditors.put(Byte.classnew CustomNumberEditor(Byte.classtrue));  
  49.     this.defaultEditors.put(short.classnew CustomNumberEditor(Short.classfalse));  
  50.     this.defaultEditors.put(Short.classnew CustomNumberEditor(Short.classtrue));  
  51.     this.defaultEditors.put(int.classnew CustomNumberEditor(Integer.classfalse));  
  52.     this.defaultEditors.put(Integer.classnew CustomNumberEditor(Integer.classtrue));  
  53.     this.defaultEditors.put(long.classnew CustomNumberEditor(Long.classfalse));  
  54.     this.defaultEditors.put(Long.classnew CustomNumberEditor(Long.classtrue));  
  55.     this.defaultEditors.put(float.classnew CustomNumberEditor(Float.classfalse));  
  56.     this.defaultEditors.put(Float.classnew CustomNumberEditor(Float.classtrue));  
  57.     this.defaultEditors.put(double.classnew CustomNumberEditor(Double.classfalse));  
  58.     this.defaultEditors.put(Double.classnew CustomNumberEditor(Double.classtrue));  
  59.     this.defaultEditors.put(BigDecimal.classnew CustomNumberEditor(BigDecimal.classtrue));  
  60.     this.defaultEditors.put(BigInteger.classnew CustomNumberEditor(BigInteger.classtrue));  
  61.   
  62.     // Only register config value editors if explicitly requested.  
  63.     if (this.configValueEditorsActive) {  
  64.         StringArrayPropertyEditor sae = new StringArrayPropertyEditor();  
  65.         this.defaultEditors.put(String[].class, sae);  
  66.         this.defaultEditors.put(short[].class, sae);  
  67.         this.defaultEditors.put(int[].class, sae);  
  68.         this.defaultEditors.put(long[].class, sae);  
  69.     }  
  70. }  

下面挑选一些常用的数据类型,举例说明它们的绑定方式

1. 基本数据类型(以int为例,其他类似):
Controller代码:

  1. @RequestMapping(“test.do”)  
  2. public void test(int num) {  
  3.       
  4. }  

JSP表单代码:

  1. <form action=“test.do” method=“post”>  
  2.    <input name=“num” value=“10” type=“text”/>  
  3.    ……  
  4. </form>  

表单中input的name值和Controller的参数变量名保持一致,就能完成基本数据类型的数据绑定,如果不一致可以使用@RequestParam标注实现。值得一提的是,如果Controller方法参数中定义的是基本数据类型,但是从jsp提交过来的数据为null或者””的话,会出现数据转换的异常。也就是说,必须保证表单传递过来的数据不能为null或””,所以,在开发过程中,对可能为空的数据,最好将参数数据类型定义成包装类型,具体参见下面的第二条。

2. 包装类型(以Integer为例,其他类似):
Controller代码:

  1. @RequestMapping(“test.do”)  
  2. public void test(Integer num) {  
  3.       
  4. }  

JSP表单代码:

  1. <form action=“test.do” method=“post”>  
  2.    <input name=“num” value=“10” type=“text”/>  
  3.    ……  
  4. </form>  

和基本数据类型基本一样,不同之处在于,JSP表单传递过来的数据可以为null或””,以上面代码为例,如果jsp中num为””或者表单中无num这个input,那么,Controller方法参数中的num值则为null。

3. 自定义对象类型:
Model代码:

  1. public class User {  
  2.   
  3.     private String firstName;  
  4.   
  5.     private String lastName;  
  6.   
  7.     public String getFirstName() {  
  8.         return firstName;  
  9.     }  
  10.   
  11.     public void setFirstName(String firstName) {  
  12.         this.firstName = firstName;  
  13.     }  
  14.   
  15.     public String getLastName() {  
  16.         return lastName;  
  17.     }  
  18.   
  19.     public void setLastName(String lastName) {  
  20.         this.lastName = lastName;  
  21.     }  
  22.   
  23. }  

Controller代码:

  1. @RequestMapping(“test.do”)  
  2. public void test(User user) {  
  3.       
  4. }  

JSP表单代码:

  1. <form action=“test.do” method=“post”>  
  2.    <input name=“firstName” value=“张” type=“text”/>  
  3.    <input name=“lastName” value=“三” type=“text”/>  
  4.    ……  
  5. </form>  

非常简单,只需将对象的属性名和input的name值一一对应即可。

4. 自定义复合对象类型:
Model代码:

  1. public class ContactInfo {  
  2.   
  3.     private String tel;  
  4.   
  5.     private String address;  
  6.   
  7.     public String getTel() {  
  8.         return tel;  
  9.     }  
  10.   
  11.     public void setTel(String tel) {  
  12.         this.tel = tel;  
  13.     }  
  14.   
  15.     public String getAddress() {  
  16.         return address;  
  17.     }  
  18.   
  19.     public void setAddress(String address) {  
  20.         this.address = address;  
  21.     }  
  22.   
  23. }  
  24.   
  25. public class User {  
  26.   
  27.     private String firstName;  
  28.   
  29.     private String lastName;  
  30.   
  31.     private ContactInfo contactInfo;  
  32.   
  33.     public String getFirstName() {  
  34.         return firstName;  
  35.     }  
  36.   
  37.     public void setFirstName(String firstName) {  
  38.         this.firstName = firstName;  
  39.     }  
  40.   
  41.     public String getLastName() {  
  42.         return lastName;  
  43.     }  
  44.   
  45.     public void setLastName(String lastName) {  
  46.         this.lastName = lastName;  
  47.     }  
  48.   
  49.     public ContactInfo getContactInfo() {  
  50.         return contactInfo;  
  51.     }  
  52.   
  53.     public void setContactInfo(ContactInfo contactInfo) {  
  54.         this.contactInfo = contactInfo;  
  55.     }  
  56.   
  57. }  

Controller代码:

  1. @RequestMapping(“test.do”)  
  2. public void test(User user) {  
  3.     System.out.println(user.getFirstName());  
  4.     System.out.println(user.getLastName());  
  5.     System.out.println(user.getContactInfo().getTel());  
  6.     System.out.println(user.getContactInfo().getAddress());  
  7. }  

JSP表单代码:

  1. <form action=“test.do” method=“post”>  
  2.    <input name=“firstName” value=“张” /><br>  
  3.    <input name=“lastName” value=“三” /><br>  
  4.    <input name=“contactInfo.tel” value=“13809908909” /><br>  
  5.    <input name=“contactInfo.address” value=“北京海淀” /><br>  
  6.    <input type=“submit” value=“Save” />  
  7. </form>  

User对象中有ContactInfo属性,Controller中的代码和第3点说的一致,但是,在jsp代码中,需要使用“属性名(对象类型的属性).属性名”来命名input的name。

5. List绑定:
List需要绑定在对象上,而不能直接写在Controller方法的参数中。
Model代码:

  1. public class User {  
  2.   
  3.     private String firstName;  
  4.   
  5.     private String lastName;  
  6.   
  7.     public String getFirstName() {  
  8.         return firstName;  
  9.     }  
  10.   
  11.     public void setFirstName(String firstName) {  
  12.         this.firstName = firstName;  
  13.     }  
  14.   
  15.     public String getLastName() {  
  16.         return lastName;  
  17.     }  
  18.   
  19.     public void setLastName(String lastName) {  
  20.         this.lastName = lastName;  
  21.     }  
  22.   
  23. }  
  24.   
  25.        public class UserListForm {  
  26.   
  27.     private List<User> users;  
  28.   
  29.     public List<User> getUsers() {  
  30.         return users;  
  31.     }  
  32.   
  33.     public void setUsers(List<User> users) {  
  34.         this.users = users;  
  35.     }  
  36.   
  37. }  

Controller代码:

  1. @RequestMapping(“test.do”)  
  2. public void test(UserListForm userForm) {  
  3.     for (User user : userForm.getUsers()) {  
  4.         System.out.println(user.getFirstName() + ” – “ + user.getLastName());  
  5.     }  
  6. }  

JSP表单代码:

  1. <form action=“test.do” method=“post”>  
  2.    <table>  
  3.       <thead>  
  4.          <tr>  
  5.             <th>First Name</th>  
  6.             <th>Last Name</th>  
  7.          </tr>  
  8.       </thead>  
  9.       <tfoot>  
  10.          <tr>  
  11.             <td colspan=“2”><input type=“submit” value=“Save” /></td>  
  12.          </tr>  
  13.       </tfoot>  
  14.       <tbody>  
  15.          <tr>  
  16.             <td><input name=“users[0].firstName” value=“aaa” /></td>  
  17.             <td><input name=“users[0].lastName” value=“bbb” /></td>  
  18.          </tr>  
  19.          <tr>  
  20.             <td><input name=“users[1].firstName” value=“ccc” /></td>  
  21.             <td><input name=“users[1].lastName” value=“ddd” /></td>  
  22.          </tr>  
  23.          <tr>  
  24.             <td><input name=“users[2].firstName” value=“eee” /></td>  
  25.             <td><input name=“users[2].lastName” value=“fff” /></td>  
  26.          </tr>  
  27.       </tbody>  
  28.    </table>  
  29. </form>  

其实,这和第4点User对象中的contantInfo数据的绑定有点类似,但是这里的UserListForm对象里面的属性被定义成List,而不是普通自定义对象。所以,在JSP中需要指定List的下标。值得一提的是,Spring会创建一个以最大下标值为size的List对象,所以,如果JSP表单中有动态添加行、删除行的情况,就需要特别注意,譬如一个表格,用户在使用过程中经过多次删除行、增加行的操作之后,下标值就会与实际大小不一致,这时候,List中的对象,只有在jsp表单中对应有下标的那些才会有值,否则会为null,看个例子:
JSP表单代码:

  1. <form action=“test.do” method=“post”>  
  2.    <table>  
  3.       <thead>  
  4.          <tr>  
  5.             <th>First Name</th>  
  6.             <th>Last Name</th>  
  7.          </tr>  
  8.       </thead>  
  9.       <tfoot>  
  10.          <tr>  
  11.             <td colspan=“2”><input type=“submit” value=“Save” /></td>  
  12.          </tr>  
  13.       </tfoot>  
  14.       <tbody>  
  15.          <tr>  
  16.             <td><input name=“users[0].firstName” value=“aaa” /></td>  
  17.             <td><input name=“users[0].lastName” value=“bbb” /></td>  
  18.          </tr>  
  19.          <tr>  
  20.             <td><input name=“users[1].firstName” value=“ccc” /></td>  
  21.             <td><input name=“users[1].lastName” value=“ddd” /></td>  
  22.          </tr>  
  23.          <tr>  
  24.             <td><input name=“users[20].firstName” value=“eee” /></td>  
  25.             <td><input name=“users[20].lastName” value=“fff” /></td>  
  26.          </tr>  
  27.       </tbody>  
  28.    </table>  
  29. </form>  

这个时候,Controller中的userForm.getUsers()获取到List的size为21,而且这21个User对象都不会为null,但是,第2到第19的User对象中的firstName和lastName都为null。打印结果:

  1. aaa – bbb  
  2. ccc – ddd  
  3. null – null  
  4. null – null  
  5. null – null  
  6. null – null  
  7. null – null  
  8. null – null  
  9. null – null  
  10. null – null  
  11. null – null  
  12. null – null  
  13. null – null  
  14. null – null  
  15. null – null  
  16. null – null  
  17. null – null  
  18. null – null  
  19. null – null  
  20. null – null  
  21. eee – fff  

6. Set绑定:
Set和List类似,也需要绑定在对象上,而不能直接写在Controller方法的参数中。但是,绑定Set数据时,必须先在Set对象中add相应的数量的模型对象。
Model代码:

  1. public class User {  
  2.   
  3.     private String firstName;  
  4.   
  5.     private String lastName;  
  6.   
  7.     public String getFirstName() {  
  8.         return firstName;  
  9.     }  
  10.   
  11.     public void setFirstName(String firstName) {  
  12.         this.firstName = firstName;  
  13.     }  
  14.   
  15.     public String getLastName() {  
  16.         return lastName;  
  17.     }  
  18.   
  19.     public void setLastName(String lastName) {  
  20.         this.lastName = lastName;  
  21.     }  
  22.   
  23. }  
  24.   
  25. public class UserSetForm {  
  26.   
  27.     private Set<User> users = new HashSet<User>();  
  28.       
  29.     public UserSetForm(){  
  30.         users.add(new User());  
  31.         users.add(new User());  
  32.         users.add(new User());  
  33.     }  
  34.   
  35.     public Set<User> getUsers() {  
  36.         return users;  
  37.     }  
  38.   
  39.     public void setUsers(Set<User> users) {  
  40.         this.users = users;  
  41.     }  
  42.   
  43. }  

Controller代码:

  1. @RequestMapping(“test.do”)  
  2. public void test(UserSetForm userForm) {  
  3.     for (User user : userForm.getUsers()) {  
  4.         System.out.println(user.getFirstName() + ” – “ + user.getLastName());  
  5.     }  
  6. }  

JSP表单代码:

  1. <form action=“test.do” method=“post”>  
  2.    <table>  
  3.       <thead>  
  4.          <tr>  
  5.             <th>First Name</th>  
  6.             <th>Last Name</th>  
  7.          </tr>  
  8.       </thead>  
  9.       <tfoot>  
  10.          <tr>  
  11.             <td colspan=“2”><input type=“submit” value=“Save” /></td>  
  12.          </tr>  
  13.       </tfoot>  
  14.       <tbody>  
  15.          <tr>  
  16.             <td><input name=“users[0].firstName” value=“aaa” /></td>  
  17.             <td><input name=“users[0].lastName” value=“bbb” /></td>  
  18.          </tr>  
  19.          <tr>  
  20.             <td><input name=“users[1].firstName” value=“ccc” /></td>  
  21.             <td><input name=“users[1].lastName” value=“ddd” /></td>  
  22.          </tr>  
  23.          <tr>  
  24.             <td><input name=“users[2].firstName” value=“eee” /></td>  
  25.             <td><input name=“users[2].lastName” value=“fff” /></td>  
  26.          </tr>  
  27.       </tbody>  
  28.    </table>  
  29. </form>  

基本和List绑定类似。
需要特别提醒的是,如果最大下标值大于Set的size,则会抛出org.springframework.beans.InvalidPropertyException异常。所以,在使用时有些不便。暂时没找到解决方法,如果有网友知道,请回帖共享你的做法。

5. Map绑定:
Map最为灵活,它也需要绑定在对象上,而不能直接写在Controller方法的参数中。
Model代码:

  1. public class User {  
  2.   
  3.     private String firstName;  
  4.   
  5.     private String lastName;  
  6.   
  7.     public String getFirstName() {  
  8.         return firstName;  
  9.     }  
  10.   
  11.     public void setFirstName(String firstName) {  
  12.         this.firstName = firstName;  
  13.     }  
  14.   
  15.     public String getLastName() {  
  16.         return lastName;  
  17.     }  
  18.   
  19.     public void setLastName(String lastName) {  
  20.         this.lastName = lastName;  
  21.     }  
  22.   
  23. }  
  24.   
  25. public class UserMapForm {  
  26.   
  27.     private Map<String, User> users;  
  28.   
  29.     public Map<String, User> getUsers() {  
  30.         return users;  
  31.     }  
  32.   
  33.     public void setUsers(Map<String, User> users) {  
  34.         this.users = users;  
  35.     }  
  36.   
  37. }  

Controller代码:

  1. @RequestMapping(“test.do”)  
  2. public void test(UserMapForm userForm) {  
  3.     for (Map.Entry<String, User> entry : userForm.getUsers().entrySet()) {  
  4.         System.out.println(entry.getKey() + “: “ + entry.getValue().getFirstName() + ” – “ +  
  5.                                  entry.getValue().getLastName());  
  6.     }  
  7. }  

JSP表单代码:

  1. <form action=“test.do” method=“post”>  
  2.    <table>  
  3.       <thead>  
  4.          <tr>  
  5.             <th>First Name</th>  
  6.             <th>Last Name</th>  
  7.          </tr>  
  8.       </thead>  
  9.       <tfoot>  
  10.          <tr>  
  11.             <td colspan=“2”><input type=“submit” value=“Save” /></td>  
  12.          </tr>  
  13.       </tfoot>  
  14.       <tbody>  
  15.          <tr>  
  16.             <td><input name=“users[‘x’].firstName” value=“aaa” /></td>  
  17.             <td><input name=“users[‘x’].lastName” value=“bbb” /></td>  
  18.          </tr>  
  19.          <tr>  
  20.             <td><input name=“users[‘y’].firstName” value=“ccc” /></td>  
  21.             <td><input name=“users[‘y’].lastName” value=“ddd” /></td>  
  22.          </tr>  
  23.          <tr>  
  24.             <td><input name=“users[‘z’].firstName” value=“eee” /></td>  
  25.             <td><input name=“users[‘z’].lastName” value=“fff” /></td>  
  26.          </tr>  
  27.       </tbody>  
  28.    </table>  
  29. </form>  

打印结果:

  1. x: aaa – bbb  
  2. y: ccc – ddd  
  3. z: eee – fff  

[@Controller]4 详解@ModelAttribute

[@Controller]4 详解@ModelAttribute – howareyouo的专栏 – 博客频道 – CSDN.NET.

A@ModelAttribute

Annotation that binds a method parameter or method return value to a named model attribute, exposed to a web view. Supported for RequestMapping annotated handler classes.

在被@RequestMapping注释的处理器类中,这个注释可以绑定一个方法参数或绑定一个方法的返回值到一个命名的模型属性,提供给一个视图。

Can be used to expose command objects to a web view, using specific attribute names, through annotating corresponding parameters of a RequestMapping annotated handler method).

可以用于把一个command对象提供给web视图,使用指定的属性名称,在被@RequestMapping注释的处理器方法中注释相关参数。

Can also be used to expose reference data to a web view through annotating accessor methods ina controller class which is based on RequestMapping annotated handler methods, with such accessor methods allowed to have any arguments that RequestMapping supports for handler methods, returning the model attribute value to expose.

可以用于提供数据给一个web视图,通过注释处理器方法,这个方法允许有任何参数,返回的模型属性值被提供。

A.1@ ModelAttribute的属性

value

The name of the model attribute to bind to.

绑定的模型属性的名称。

The default model attribute name is inferred from the declared attribute type (i.e. the method parameter type or method return type), based on the non-qualified class name: e.g. “orderAddress” for class “mypackage.OrderAddress”, or “orderAddressList” for “List<mypackage.OrderAddress>”.

默认的模型属性名称自动判断声明的属性类型(如,方法参数类型或方法返回类型)。如这个值是orderAddress,就对于当前包. OrderAddress

 

B@ModelAttribute注释一个方法

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.

@ModelAttribute注释的方法表示这个方法的目的是增加一个或多个模型(model)属性。这个方法和被@RequestMapping注释的方法一样也支持@RequestParam参数,但是它不能直接被请求映射。实际上,控制器中的@ModelAttribute方法是在同一控制器中的@RequestMapping方法被调用之前调用的。

@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.

@ModelAttribute注释的方法用于填充model属性,例如,为下拉菜单填充内容,或检索一个command对象(如,Account),用它来表示一个HTML表单中的数据。

A controller can have any number of @ModelAttribute methods. All such methods are invoked before @RequestMapping methods of the same controller.

一个控制器可以有任意数量的@ModelAttribute方法。所有这些方法都在@RequestMapping方法被调用之前调用。

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.

有两种类型的@ModelAttribute方法。一种是:加入只一个属性,用方法的返回类型隐含表示。另一种是:方法接受一个Model类型的参数,这个model可以加入任意多个model属性。

B.1@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 后,populateModel方法在helloWorld方法之前先被调用,它把请求参数(/helloWorld?abc=text)加入到一个名为attributeNamemodel属性中,在它执行后helloWorld被调用,返回视图名helloWorldmodel已由@ModelAttribute方法生产好了。

这个例子中model属性名称和model属性对象有model.addAttribute()实现,不过前提是要在方法中加入一个Model类型的参数。

B.2@ModelAttribute注释返回具体类的方法

举例说明

@ModelAttribute

    public Account addAccount(@RequestParam String number) {

       return accountManager.findAccount(number);

    }

这种情况,model属性的名称没有指定,它由返回类型隐含表示,如这个方法返回Account类型,那么这个model属性的名称是account

这个例子中model属性名称有返回对象类型隐含表示,model属性对象就是方法的返回值。它无须要特定的参数。

B.3@ModelAttribute(value=””)注释返回具体类的方法

举例说明

@Controller

public class HelloWorldController {

    @ModelAttribute(“attributeName”)

    public String addAccount(@RequestParam String abc) {

       return abc;

    }

    @RequestMapping(value = “/helloWorld”)

    public String helloWorld() {

       return “helloWorld”;

    }

}

这个例子中使用@ModelAttribute注释的value属性,来指定model属性的名称。model属性对象就是方法的返回值。它无须要特定的参数。

B.4@ModelAttribute@RequestMapping同时注释一个方法

举例说明

@Controller

public class HelloWorldController {

    @RequestMapping(value = “/helloWorld.do”)

    @ModelAttribute(“attributeName”)

    public String helloWorld() {

       return “hi”;

    }

}

这时这个方法的返回值并不是表示一个视图名称,而是model属性的值,视图名称由RequestToViewNameTranslator根据请求“/helloWorld.do”转换为helloWorldModel属性名称有@ModelAttribute(value=””)指定。

 

C@ModelAttribute注释一个方法的参数

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.

@ModelAttribute注释方法的一个参数表示应从模型model中取得。若在model中未找到,那么这个参数将先被实例化后加入到model中。若在model中找到,则请求参数名称和model属性字段若相匹配就会自动填充。这个机制对于表单提交数据绑定到对象属性上很有效。

B.1、从model中获取

It may already be in the model due to an @ModelAttribute method in the same controller

参数的值从当前控制器的@ModelAttribute方法提供的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属性。

B.2、从URI template变量中获取

 

B.3、从Form表单或URL参数中获取

举例说明

@Controller

public class HelloWorldController {

    @RequestMapping(value = “/helloWorld”)

    public String helloWorld(@ModelAttribute User user) {

       return “helloWorld”;

    }

}

注意这时候这个User类一定要有没有参数的构造函数。