1. 程式人生 > >@ModelAttribute的用法,與@RequestBody的區別

@ModelAttribute的用法,與@RequestBody的區別

value Coding 的區別 控制臺輸出 傳遞 attribute 地址 except 返回值

@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指定;

@ModelAttribute的用法,與@RequestBody的區別