因爲沒搞清楚 @RequestBody 和 @ModelAttribute 的區別,我覺得 @ModelAttribute 是 Swagger 的一個註解,結果我明明使用對象接收參數的,結果對象裏面都是 null。html
後來把 @ModelAttribute 去掉,發現就能夠接收到 json 了。前端
既然遇到了這個問題,那麼仍是瞭解一下這兩個註解以及它們的不一樣之處吧。java
@RequestBody 註解經常使用來處理 content-type 不是默認的 application/x-www-form-urlcoded 編碼的內容,好比說:application/json 或者是 application/xml 等。通常狀況下來講經常使用其來處理 application/json 類型。ajax
如今有以下的 ajax 請求:json
$.ajax({ url:"/login", type:"POST", data:'{"userName":"admin","pwd","admin123"}', content-type:"application/json charset=utf-8", success:function(data){ alert("request success ! "); } });
此時做爲後臺開發,你能夠有兩種方式接收參數:session
將 json 字符串中的兩個變量分別賦予兩個字符串app
@RequestMapping("/login") public void login(@RequestBody String userName, @RequestBody String pwd){ System.out.println(userName + " :" + pwd); }
這種方法我卻是用的比較少,通常都是用第二種方法。函數
構造一個 User 類,這個 User 類有以下的字段post
String userName; String pwd;
而後接收方式以下:ui
@RequestMapping("/login") public void login(@RequestBody User user){ System.out.println(user.getUserName + " :" + user.getPwd); }
這樣也能夠接收參數,並且是最經常使用的。
在一些特殊狀況 @RequestBody 也能夠用來處理 content-type 類型爲 application/x-www-form-urlcoded 的內容,只不過這種方式不是很經常使用,在處理這類請求的時候,@RequestBody 會將處理結果放到一個 MultiValueMap<String, String> 中。
@RequestBody 用於 post 請求,不能用於 get 請求。(某些時候仍是能夠用於 GET 請求的,只不過 HTTP 協議不推薦這麼作,由於 GET 通常不在 請求體中帶上數據,這個和實現有關。)
在 Spring MVC 中,註解 @ModelAttribute 是一個很是經常使用的註解,其功能主要在兩方面:
通常開發中,第一種用法居多,第二種用法能夠節省 controller 層的一些代碼。
@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)加入到一個名爲 attributeName 的 model 屬性中,在它執行後 helloWorld 被調用,返回視圖名 helloWorld 和 model 已由 @ModelAttribute 方法生產好了。例子中 model 屬性名稱和 model 屬性對象由 model.addAttribute() 實現,不過前提是要在方法中加入一個 Model 類型的參數。
當 URL 或者 post 中不包含次參數時,會報錯,其實不須要這個方法,徹底能夠把請求的方法寫成,這樣缺乏此參數也不會出錯。
@RequestMapping(value = "/helloWorld") public String helloWorld(String abc) { return "helloWorld"; }
@ModelAttribute 註釋返回具體類的方法
@ModelAttribute public Account addAccount(@RequestParam String number) { return accountManager.findAccount(number); }
這種狀況,model 屬性的名稱沒有指定,它由返回類型隱含表示,如這個方法返回 Account 類型,那麼這個 model 屬性的名稱是 account。
這個例子中 model 屬性名稱有返回對象類型隱含表示,model 屬性對象就是方法的返回值。它無需要特定的參數。
@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屬性對象就是方法的返回值。它無需要特定的參數。
@ModelAttribute 和 @RequestMapping 同時註釋一個方法
@Controller public class HelloWorldController { @RequestMapping(value = "/helloWorld.do") @ModelAttribute("attributeName") public String helloWorld() { return "hi"; } }
這時這個方法的返回值並非表示一個視圖名稱,而是 model 屬性的值,視圖名稱由RequestToViewNameTranslator 根據請求 "/helloWorld.do" 轉換爲邏輯視圖 helloWorld。
Model 屬性名稱由 @ModelAttribute(value="") 指定,至關於在 request 中封裝了 key=attributeName,value=hi。
@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 屬性。此時若是方法體沒有標註 @SessionAttributes("user"),那麼scope 爲 request,若是標註了,那麼 scope 爲 session
從 Form 表單或 URL 參數中獲取(實際上,不用此註解也能拿到 user 對象)
@Controller public class HelloWorldController { @RequestMapping(value = "/helloWorld") public String helloWorld(@ModelAttribute User user) { return "helloWorld"; } }
注意這時候這個User類必定要有沒有參數的構造函數。
這他媽的,ModelAttribute 這麼麻煩。。。
GET 和 POST 請求傳的參數會自動轉換賦值到 @RequestParam 所註解的變量上。
用來處理 Content-Type 爲 application/x-www-form-urlencoded 編碼的內容。提交方式爲 get 或 post。
(HTTP 協議中,若是不指定 Content-Type,則默認傳遞的參數就是 application/x-www-form-urlencoded 類型)
RequestParam 實質是將 Request.getParameter() 中的 Key-Value 參數 Map 利用 Spring 的轉化機制ConversionService 配置,轉化成參數接收對象或字段。
能夠經過required=false或者true來要求@RequestParam配置的前端參數是否必定要傳。
若是用@RequestMapping註解的參數是int基本類型,可是required=false,這時若是不傳參數值會報錯,由於不傳值,會賦值爲null給int,這個不能夠 。
@RequestParam 和 @PathVariable 都可以完成相似的功能:由於本質上,它們都是用戶的輸入,只不過輸入的部分不一樣,一個在URL路徑部分,另外一個在參數部分。
使用這個註解前提是在 @RequestMapping 中必須指定模板。
https://www.cnblogs.com/qiankun-site/p/5774300.html
https://blog.csdn.net/zz210891470/article/details/59719251