springmvc的@ModelAttribute註解

來源:http://blog.csdn.net/xiejx618/article/details/43638537###;

參考資料:spring-framework-reference的Using @ModelAttribute on a method和Using @ModelAttribute on a method argument


先看一個沒有使用@ModelAttribute的Controller方法.

  1. @RequestMapping("/save")  
  2. public String save(User user) {  
  3.     user.setUsername("U love me");  
  4.     userService.save(user);  
  5.     return "result";  
  6. }  
其中User包含id和username兩個私有屬性,含有公共setter和getter方法.
執行此方法時會將key爲"user"(注意:這裏即使參數名稱是user1,key一樣還是"user"),value爲user的對象加入到model.在jsp頁面可以通過${user.id}和${user.name}得到值的,即上面方法和下面方法是相當的.
  1. @RequestMapping("/save")  
  2. public String save(Model model,int id,String username) {  
  3.     User user=new User();  
  4.     //這裏是通過反射從request裏面拿值再set到user  
  5.     user.setId(id);  
  6.     user.setUsername(username);  
  7.     model.addAttribute("user",user);  
  8.       
  9.     user.setUsername("U love me");  
  10.     userService.save(user);  
  11.     return "result";  
  12. }  
一.下面再來看看@ModelAttribute的基本用法.
1.在方法上使用@ModelAttribute
  1. @ModelAttribute("user1")  
  2. public User addUser(User user) {  
  3.     return new User(520,"I love U");  
  4. }  
假設此方法是寫在UserController內,那麼執行UserController內帶有@RequestMapping的方法之前,都會先執行此addUser方法.並且執行addUser過程中會添加兩個對象到model,先將key爲"user"的對象(由addUser方法的User user引起的),再添加key爲"user1"的對象(由註解@ModelAttribute("user1")引起的).

2.在方法參數上使用@ModelAttribute.

  1. @RequestMapping("/save")  
  2. public String save(@ModelAttribute User user) {  
  3.     user.setUsername("U love me");  
  4.     userService.save(user);  
  5.     return "result";  
  6. }  
此方法會先從model去獲取key爲"user"的對象,如果獲取不到會通過反射實例化一個User對象,再從request裏面拿值set到這個對象,然後把這個User對象添加到model(其中key爲"user").
使用了@ModelAttribute可修改這個key,不一定是"user",此情況下,用與不用@ModelAttribute沒有區別.


3.再來看看在方法和方法參數上結合使用@ModelAttribute,即上面兩步的兩個方法都添加UserController,如下:
  1. @ModelAttribute("user1")  
  2. public User addUser(User user) {  
  3.     return new User(520,"I love U");  
  4. }  
  5. @RequestMapping("/save")  
  6. public String save(@ModelAttribute User user) {  
  7.     user.setUsername("U love me");  
  8.     userService.save(user);  
  9.     return "result";  
  10. }  
假設要執行保存用戶操作,根據一分析可知,先執行完會產生兩個User類型的對象(一個key是"user",另一個key是"user1")添加到model,再執行save方法,此時會先從model去找key爲"user"的對象,能找到再從request取值set到這個User對象.最後返回到jsp頁面,model裏也只有兩個User類型對象.
再來個小小假設,將上面@ModelAttribute("user1")的user1改爲user,其它不變.雖然執行了addUser方法,那麼執行到save方法內,user對象的字段值還是來源於請求,最後返回到jsp頁面,model裏也只有一個User類型對象.


4.另類:
  1. @ModelAttribute  
  2. @RequestMapping("/save")  
  3. public String save(@ModelAttribute User user) {  
  4.     user.setUsername("U love me");  
  5.     userService.save(user);  
  6.     return "result";  
  7. }  
此種情況,會添加一個key爲"user"的User對象到model,還會添加一個key爲"string",value爲"result"的對象到model,而視圖名稱則變爲了"save"而不是"result".相信一般開發者都不會這樣用.

二.下面再看看結合@SessionAttributes的用法.

1.先看看這段代碼

  1. @Controller  
  2. @RequestMapping("user")  
  3. @SessionAttributes("test")  
  4. public class UserController {  
  5.     @RequestMapping(value = "test1")  
  6.     public String test1(Map<String, Object> model, SessionStatus sessionStatus) {  
  7.         model.put("test","something");  
  8.         //sessionStatus.setComplete();  
  9.         return "user/list";  
  10.     }  
  11.   
  12.     @RequestMapping(value = "test2")  
  13.     public String test2(Map<String,?>  model) {  
  14.         Object test = model.get("test");  
  15.         System.out.println(test);  
  16.         return "user/list";  
  17.     }  
  18. }  
在類級別上使用@SessionAttributes("test"),它的作用是在controller共享 model 屬性,直到調用org.springframework.web.bind.support.SessionStatus#setComplete會清除此session值.否則長期保留(session過期,這個值也不再保留).因此先調用/user/test1,再調用/user/test2.在test2方法能得到test1方法put進去的值.當移除上面的註解,因爲屬性爲test的session也被清除了,所以test2方法會得到是null.

2.再看結合@ModelAttribute的用法.

  1. @Controller  
  2. @RequestMapping("user")  
  3. @SessionAttributes("test")  
  4. public class UserController {  
  5.     @RequestMapping(value = "test1")  
  6.     public String test1(HttpServletRequest request) {  
  7.         User user = new User("xiejx618");  
  8.         request.getSession().setAttribute("test",user);  
  9.         return "user/list";  
  10.     }  
  11.     @RequestMapping(value = "test2")  
  12.     public String test2(@ModelAttribute("test") User user,SessionStatus sessionStatus) {  
  13.         System.out.println(user.getUsername());  
  14.         sessionStatus.setComplete();  
  15.         return "user/list";  
  16.     }  
  17. }  
一樣先調用/user/test1,再調用/user/test2.在test2方法能得到test1方法set進去的值.使用了@SessionAttributes,如果在controller的方法參數上有@ModelAttribute,那麼此方法會確保屬性test的session會存在,否則會拋org.springframework.web.HttpSessionRequiredException異常,即上面代碼先不調/user/test1,直接調/user/test2就會拋此異常


我個人很少這樣用,用原始的寫法就清晰很多了,但要看明白別人寫的代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章