@ModelAttribute的用法大概有兩種:一種是直接標記在方法上,一種是標記在方法的參數中,兩種標記的方法產生效果也各不相同
一.直接標記在方法上
1 @Controller 2 @RequestMapping(value="model") 3 public class ModelAttributeTest { 4 5 @ModelAttribute 6 public void init() 7 { 8 System.out.println("最先執行的方法"); 9 } 10 11 @ModelAttribute 12 public void init02() 13 { 14 System.out.println("最先執行的方法02"); 15 } 16 17 @RequestMapping(value="modelTest.do") 18 public String modelTest() 19 { 20 System.out.println("然后執行的方法"); 21 return "modelTest"; 22 } 23 24 @ModelAttribute 25 public void init03() 26 { 27 System.out.println("最先執行的方法03"); 28 } 29 }
部署后運行,點擊頁面測試按鈕,查看控制台輸出,這個時候你會發現,后台控制器並沒有直接進入modelTest.do的路徑,而是先執行了被@ModelAttribute標記的init方法。應該這么理解,當同一個controller中有任意一個方法被@ModelAttribute注解標記,頁面請求只要進入這個控制器,不管請求那個方法,均會先執行被@ModelAttribute標記的方法,所以我們可以用@ModelAttribute注解的方法做一些初始化操作。當同一個controller中有多個方法被@ModelAttribute注解標記,所有被@ModelAttribute標記的方法均會被執行,按先后順序執行,然后再進入請求的方法。
當@RequestMapping標記和@ModelAttribute同時標記在一個方法上
1 @Controller 2 @RequestMapping(value="model") 3 public class ModelAttributeTest { 4 5 @RequestMapping(value="modelTest.do") 6 @ModelAttribute(value="pojo") 7 public String modelTest() 8 { 9 System.out.println("進入modelTest方法"); 10 11 return "modelTest"; 12 } 13 14 }
點擊測試頁面發現進入控制器后返回,頁面報404,這是因為當兩個注解標記到同一個方法上時,邏輯視圖名並不是返回值,而是返回請求的路徑,根據model/modelTest.do生成邏輯視圖。在這里我們修改下代碼,把controller上的@RequestMapping標記去掉,並修改下頁面的請求路徑,讓生成的視圖路徑和訪問的頁面路徑相同。
1 @Controller 2 public class ModelAttributeTest { 3 4 @RequestMapping(value="modelTest.do") 5 @ModelAttribute(value="pojo") 6 public String modelTest() 7 { 8 System.out.println("進入modelTest方法"); 9 10 return "modelTest"; 11 } 12 13 }
1 <script type="text/javascript"> 2 $(function(){ 3 $("#modelTest").on("click",function(){ 4 5 window.location.href="<%=basePath%>modelTest.do"; 6 }) 7 }); 8 </script> 9 <body> 10 11 <input type="button" id="modelTest" value="測試"> 12 13 <input type="text" value="${pojo }"> 14 15 </body>
點擊測試頁面,會發現當兩個注解同時注解到一個方法上時,方法的返回值會變成model模型的返回值,key是標記的名
二.@ModelAttribute標記在參數前
1 @Controller 2 @RequestMapping(value="model") 3 public class ModelAttributeTest { 4 5 @RequestMapping(value="modelTest.do") 6 public String modelTest(@ModelAttribute("pojo") PojoTest pojo) 7 { 8 try { 9 pojo.setUserName(new String(pojo.getUserName().getBytes("iso-8859-1"),"utf-8")); 10 pojo.setSex(new String(pojo.getSex().getBytes("iso-8859-1"),"utf-8")); 11 } catch (UnsupportedEncodingException e) { 12 // TODO Auto-generated catch block 13 e.printStackTrace(); 14 } 15 System.out.println(pojo); 16 return "modelTest"; 17 } 18 19 }
點擊頁面測試,頁面文本框會顯示URL地址傳遞過來的參數,因為SpringMVC會自動匹匹配頁面傳遞過來的參數的name屬性和后台控制器中的方法中的參數名,如果參數名相同,會自動匹配,如果控制器中方法是封裝的bean,會自動匹配bean中的屬性,其實這種取值方式不需要用@ModelAttribute注解,只要滿足匹配要求,也能拿得到值
@RequestBody
作用:
i) 該注解用於讀取Request請求的body部分數據,使用系統默認配置的HttpMessageConverter進行解析,然后把相應的數據綁定到要返回的對象上;
ii) 再把HttpMessageConverter返回的對象數據綁定到 controller中方法的參數上。
使用時機:
A) GET、POST方式提時, 根據request header Content-Type的值來判斷:
- application/x-www-form-urlencoded, 可選(即非必須,因為這種情況的數據@RequestParam, @ModelAttribute也可以處理,當然@RequestBody也能處理);
- multipart/form-data, 不能處理(即使用@RequestBody不能處理這種格式的數據);
- 其他格式, 必須(其他格式包括application/json, application/xml等。這些格式的數據,必須使用@RequestBody來處理);
B) PUT方式提交時, 根據request header Content-Type的值來判斷:
- application/x-www-form-urlencoded, 必須;
- multipart/form-data, 不能處理;
- 其他格式, 必須;
說明:request的body部分的數據編碼格式由header部分的Content-Type指定;