@ModelAttribute注解的使用

来源:互联网 发布:唯品会官网首页淘宝 编辑:程序博客网 时间:2024/05/20 21:21

先看一下,spring官方给的解释:

@ModelAttribute has two usage scenarios in controllers. When you place it on a method parameter, @ModelAttribute maps a model attribute to the specific, annotated method parameter (see the processSubmit() method below). This is how the controller gets a reference to the object holding the data entered in the form. 

You can also use @ModelAttribute at the method level to provide reference data for the model (see the populatePetTypes() method in the following example). For this usage the method signature can contain the same types as documented previously for the @RequestMapping annotation. 

Note 
@ModelAttribute annotated methods are executed before the chosen @RequestMapping annotated handler method. They effectively pre-populate the implicit model with specific attributes, often loaded from a database. Such an attribute can then already be accessed through @ModelAttribute annotated handler method parameters in the chosen handler method, potentially with binding and validation applied to it.

Spring3关于@ModelAttribute的文档 

模式一(作用于方法上)

@ModelAttribute(value="user")public Employee initUser(HttpServletRequest request){return getSesionUser(request);}
这种情况下,你调用任何一个它所在的类中的链接,即@requestMapping方法的时候都会首先执行这个方法,并且返回对象,对象的标签就是该注解的value,这边就是"user".这样你在jsp页面中就可以使用这个user对象。使用方法就是${user.usercode}

遇到的问题,一些其他的类继承这个类,所以在调用它们里面的链接的时候都会调用一次这个链接,可是有个类的调用是不需要登录的,所以获取不到session,这个时候就会报错,可是这个类的业务本身是不需要session的,所以在用这个属性的时候主要使用场景。

模式二(作用在方法属性上)

@RequestMapping(value="/{userCode}/newRegular")public String newRegular(@ModelAttribute(value="user")Model model,@PathVariable(value="userCode")int userCode){        Employee  ep = getSesionUser(request);        if(!employeeService.checkEmployee(userCode,ep.getCompanyObject())){            return error_new(model,"对不起,无此员工信息,请联系管理员");        } if (ep.checkPrivilege(Constants.CHANGES_ADD)) { processRequest(userCode, model, EmployeeChangeRecords.CHANGE_TYPE_REGULAR); return "/changes/newRegular"; } return errorNoPrivilege(model);}
在方法上面使用,则对应的jsp页面操作完后返回的参数自动匹配到命名user对象上面。参考的例子如下:

Java代码  收藏代码
  1. package org.liukai.tutorial.controller;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import javax.annotation.Resource;  
  7.   
  8. import org.apache.log4j.Logger;  
  9. import org.liukai.tutorial.domain.Person;  
  10. import org.liukai.tutorial.service.PersonService;  
  11. import org.springframework.stereotype.Controller;  
  12. import org.springframework.ui.Model;  
  13. import org.springframework.web.bind.annotation.ModelAttribute;  
  14. import org.springframework.web.bind.annotation.PathVariable;  
  15. import org.springframework.web.bind.annotation.RequestMapping;  
  16. import org.springframework.web.bind.annotation.RequestMethod;  
  17.   
  18. @Controller  
  19. @RequestMapping("/main")  
  20. public class MainController {  
  21.   
  22.     protected static Logger logger = Logger.getLogger("controller");  
  23.   
  24.     @Resource(name = "personService")  
  25.     private PersonService personService;  
  26.   
  27.     /** 
  28.      * 获得所有Person,并使他们成为一个model. 
  29.      */  
  30.     @ModelAttribute("persons")  
  31.     public List<Person> getAllPersons() {  
  32.         logger.debug("Retrieving all persons and adding it to ModelAttribute");  
  33.         // Delegate to PersonService  
  34.         return personService.getAll();  
  35.     }  
  36.   
  37.     /** 
  38.      * 获得所有的货币类型,并使他们成为一个model. 
  39.      */  
  40.     @ModelAttribute("currencies")  
  41.     public List<String> getAllCurrencies() {  
  42.         logger.debug("Retrieving all currencies and adding it to ModelAttribute");  
  43.   
  44.         // Prepare data  
  45.         List<String> currencies = new ArrayList<String>();  
  46.         currencies.add("Dollar");  
  47.         currencies.add("Yen");  
  48.         currencies.add("Pound");  
  49.         currencies.add("Euro");  
  50.         currencies.add("Dinar");  
  51.   
  52.         return currencies;  
  53.     }  
  54.   
  55.     /** 
  56.      * 处理和检索一个包含Perosn 的JSP Page 
  57.      */  
  58.     @RequestMapping(method = RequestMethod.GET)  
  59.     public String getAllPage(Model model) {  
  60.   
  61.         logger.debug("Received request to show all persons page");  
  62.   
  63.         // personsage.jsp会引用一个名叫persons的model attribute  
  64.         // 我们不需要手动添加这个model  
  65.         // 前面他已经自动的通过@ModelAttribute("persons")进行了添加.  
  66.   
  67.         // 他会解析 /WEB-INF/jsp/personspage.jsp  
  68.         return "personspage";  
  69.     }  
  70.   
  71.     /** 
  72.      * 检索修改页面 
  73.      */  
  74.     @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)  
  75.     public String getEdit(@PathVariable Integer id, Model model) {  
  76.         /* 
  77.          * @PathVariable表示指定@RequestMapping的URL模板中{}里的值  
  78.          * 相当于以前我们URL后面传的参数如XX?id=XXXX . 
  79.          * 但是现在我们可以用 XX/id/XX来代替.  
  80.          * 这个就是REST风格的URL,我们可以实现非常复杂的URL模板 
  81.          */  
  82.   
  83.         logger.debug("Received request to show edit page");  
  84.   
  85.         /* 
  86.          * 根据ID检索出对应的Person,然后把检索出来的Person放入一个叫 
  87.          * "personAttribute"的model中. 
  88.          * 这样editpage.jsp就会接收一个 名为personAttribute的参数. 
  89.          * 相当于request.setAttribute("XX",XX) 
  90.          */  
  91.         model.addAttribute("personAttribute", personService.get(id));  
  92.   
  93.         // This will resolve to /WEB-INF/jsp/editpage.jsp  
  94.         return "editpage";  
  95.     }  
  96.   
  97.     /** 
  98.      * 保存修改结果 
  99.      */  
  100.     @RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)  
  101.     public String saveEdit(@ModelAttribute("personAttribute") Person person,  
  102.             @PathVariable Integer id, Model model) {  
  103.         logger.debug("Received request to update person");  
  104.   
  105.         // 我们从页面接收到了一个名为"personAttribute"的model并命名为person  
  106.         // 同样我们也获得了指定的id.  
  107.         person.setId(id);  
  108.   
  109.         // 更新person  
  110.         personService.edit(person);  
  111.   
  112.         // 在更新后我们重新显示所有Person 的页面  
  113.         model.addAttribute("persons", personService.getAll());  
  114.   
  115.         // This will resolve to /WEB-INF/jsp/personspage.jsp  
  116.         return "personspage";  
  117.     }  
  118.   
  119. }  


这个controller里定义了两个method级别的@ModelAttribute方法:getAllPersons和getAllCurrencies 
我们已经了解了他们的用法和意义. 
然后在saveEdit方法中,有个一个参数是用@ModelAttribute注解的. 

Java代码  收藏代码
  1. @RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)  
  2.     public String saveEdit(@ModelAttribute("personAttribute") Person person,   
  3.       @PathVariable Integer id, Model model) {  
  4. ...  
  5. }  

表示从JSP 页面返回的一个叫"personAttribute"的值.并自动的转化为Person对象. 
这样和以前我们用的request.getParameters("personAttribute")效果一样. 
但是一个是操作参数对象.一个是处理请求.两者的实现思想不同. 


在此controller中我们有3个映射: 
/main  - 检索所有的Person 

/main/edit/{id} - (GET)根据ID进行检索和edit 

/main/edit/{id} - (POST) 根据ID进行更新 

注:后两者的URL虽然一样, 
但一个是GET方法,一般用于检索. 
一个是POST方法,一般用于提交表单. 
如果大家有注意@RequestMapping中的method方法其实有四种. 
GET 
POST 
PUT 
DELETE 

每个方法对应一个逻辑操作.对于REST风格的编程是一个相当好的补充. 
关于这点感兴趣的同学可以看看springsource一篇官方BLOG:REST in Spring 3: @MVC 

让我们继续完成其他的JSP 

personspage.jsp
 
Jsp代码  收藏代码
  1. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  
  2. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  3.     pageEncoding="UTF-8"%>  
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  5. <html>  
  6. <head>  
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  8. <title>Insert title here</title>  
  9. </head>  
  10. <body>  
  11.   
  12. <h1>Persons</h1>  
  13.   
  14. <table>  
  15.     <tr>  
  16.         <td width="50">Id</td>  
  17.         <td width="150">First Name</td>  
  18.         <td width="150">Last Name</td>  
  19.         <td width="100">Money</td>  
  20.         <td width="50">Currency</td>  
  21.     </tr>  
  22.     <c:forEach items="${persons}" var="person">  
  23.         <tr>  
  24.             <td><c:out value="${person.id}" /></td>  
  25.             <td><c:out value="${person.firstName}" /></td>  
  26.             <td><c:out value="${person.lastName}" /></td>  
  27.             <td><c:out value="${person.money}" /></td>  
  28.             <td><c:out value="${person.currency}" /></td>  
  29.         </tr>  
  30.     </c:forEach>  
  31. </table>  
  32.   
  33. </body>  
  34. </html>  

这个主要是映射 /main. 


editpage.jsp 

Jsp代码  收藏代码
  1. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  
  2. <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>  
  3. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  4.     pageEncoding="UTF-8"%>  
  5. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  6. <html>  
  7. <head>  
  8. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  9. <title>Insert title here</title>  
  10. </head>  
  11. <body>  
  12.   
  13. <h1>Edit Person</h1>  
  14.   
  15. <c:url var="saveUrl" value="/main/edit/${personAttribute.id}" />  
  16.   
  17. <form:form modelAttribute="personAttribute" method="POST" action="${saveUrl}">  
  18.     <table>  
  19.         <tr>  
  20.             <td><form:label path="id">Id:</form:label></td>  
  21.             <td><form:input path="id" disabled="true"/></td>  
  22.         </tr>  
  23.       
  24.         <tr>  
  25.             <td><form:label path="firstName">First Name:</form:label></td>  
  26.             <td><form:input path="firstName"/></td>  
  27.         </tr>  
  28.   
  29.         <tr>  
  30.             <td><form:label path="lastName">Last Name</form:label></td>  
  31.             <td><form:input path="lastName"/></td>  
  32.         </tr>  
  33.           
  34.         <tr>  
  35.             <td><form:label path="money">Money</form:label></td>  
  36.             <td><form:input path="money"/></td>  
  37.         </tr>  
  38.           
  39.         <tr>  
  40.             <td><form:label path="currency">Currency:</form:label></td>  
  41.             <td><form:select path="currency"  items="${currencies}"/></td>  
  42.         </tr>  
  43.     </table>  
  44.       
  45.     <input type="submit" value="Save" />  
  46. </form:form>  
  47.   
  48. </body>  
  49. </html>  

此页面返回以下controller中的方法: 


Java代码  收藏代码
  1. @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)  
  2.     public String getEdit(@PathVariable Integer id, Model model) {  
  3. ...  
  4. }  


我们可以通过类似 
http://localhost:8080/spring-jsp/main/edit/1 
的链接进行编辑. 
下面是编辑页面 

 

当我们编辑完提交表格,执行了下面的方法 

Java代码  收藏代码
  1.   @RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)  
  2.     public String saveEdit(@ModelAttribute("personAttribute") Person person,   
  3.       @PathVariable Integer id, Model model) {  
  4. ...  
  5. }  



0 0