淺談@RequestBody和@RequestParam可以同時(shí)使用
@RequestBody和@RequestParam可以同時(shí)使用嗎
@RequestParam和@RequestBody這兩個(gè)注解是可以同時(shí)使用的。
網(wǎng)上有很多博客說@RequestParam 和@RequestBody不能同時(shí)使用,這是錯(cuò)誤的。
根據(jù)HTTP協(xié)議,并沒有說post請(qǐng)求不能帶URL參數(shù),經(jīng)驗(yàn)證往一個(gè)帶有參數(shù)的URL發(fā)送post請(qǐng)求也是可以成功的。只不過,我們?nèi)粘i_發(fā)使用GET請(qǐng)求搭配@RequestParam,使用POST請(qǐng)求搭配@RequestBody就滿足了需求,基本不怎么同時(shí)使用二者而已。
自己個(gè)人實(shí)際驗(yàn)證結(jié)果
package com.example.model; import java.util.List; public class PramInfo { public int getId() { return id; } public void setId(int id) { this.id = id; } public String getStr() { return str; } public void setStr(String str) { this.str = str; } private int id; private String str; }
package com.example.demo; import com.example.model.PramInfo; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(value = "/test") public class TestContoller { @RequestMapping(value = "/dxc") public String print(PramInfo info) { return info.getId() + ": :" + info.getStr(); } @RequestMapping(value = "/getUserJson") public String getUserJson(@RequestParam(value = "id") int id, @RequestParam(value = "name2", required = false) String name2 , @RequestBody PramInfo pramInfo) { return (id + "--" + name2 + ";paramInfo:" + pramInfo.getStr() + ";pramInfo.id:" + pramInfo.getId()); } }
在postman發(fā)送如下post請(qǐng)求,返回正常
body中參數(shù)如下
從結(jié)果來看,post請(qǐng)求URL帶參數(shù)是沒有問題的,所以@RequestParam和@RequestBody是可以同時(shí)使用的【經(jīng)測(cè)試,分別使用Postman 和 httpClient框架編程發(fā)送http請(qǐng)求,后端@RequestParam和@RequestBody都可以正常接收請(qǐng)求參數(shù),所以個(gè)人認(rèn)為可能一些前端框架不支持或者沒必要這么做,但是不能說@RequestParam和@RequestBody 不能同時(shí)使用】。
值得注意的地方
1、postman的GET請(qǐng)求是不支持請(qǐng)求body的;
2、
@GetMapping(value = "/dxc") public String print(PramInfo info) { return info.getId() + ": :" + info.getStr(); }
這種請(qǐng)求方式,不加@RequestParam注解,也能直接取出URL后面的參數(shù),即參數(shù)可以與定義的類互相自動(dòng)轉(zhuǎn)化。
3、
@PostMapping(value = "/getUserJson") public String getUserJson(@RequestParam(value = "id") int id, @RequestParam(value = "name2", required = false) String name2 , @RequestBody PramInfo pramInfo) { return (id + "--" + name2 + ";paramInfo:" + pramInfo.getStr() + ";pramInfo.id:" + pramInfo.getId());
如果請(qǐng)求中的body沒有ParamInfo對(duì)象對(duì)應(yīng)的json串,即當(dāng)body為空(連json串的{}都沒有)時(shí),會(huì)報(bào)請(qǐng)求body空異常:
2018-05-12 23:45:27.494 WARN 6768 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public java.lang.String com.example.demo.TestContoller.getUserJson(int,java.lang.String,com.example.model.PramInfo)
-05-12 23:45:27.494 WARN 6768 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public java.lang.String com.example.demo.TestContoller.getUserJson(int,java.lang.String,com.example.model.PramInfo)
@RequestBody和@RequestParam注解使用說明
@RequestBody作用
主要用來接收前端傳遞給后端的json字符串中的數(shù)據(jù)的(請(qǐng)求體中的數(shù)據(jù));
@RequestParam作用
將請(qǐng)求參數(shù)綁定到你控制器的方法參數(shù)上
GET方式無請(qǐng)求體,所以使用@RequestBody接收數(shù)據(jù)時(shí),前端不能使用GET方式提交數(shù)據(jù),而是用POST方式進(jìn)行提交。在后端的同一個(gè)接收方法里,@RequestBody與@RequestParam()可以同時(shí)使用,@RequestBody最多只能有一個(gè),而@RequestParam()可以有多個(gè)。
@RequestBody:
- 注:一個(gè)請(qǐng)求,只有一個(gè)RequestBody;一個(gè)請(qǐng)求,可以有多個(gè)RequestParam。
- 注:當(dāng)同時(shí)使用@RequestParam()和@RequestBody時(shí),@RequestParam()指定的參數(shù)可以是普通元素、數(shù)組、集合、對(duì)象等等(即:當(dāng),@RequestBody 與@RequestParam()可以同時(shí)使用時(shí),原SpringMVC接收參數(shù)的機(jī)制不變,只不過RequestBody 接收的是請(qǐng)求體里面的數(shù)據(jù);而RequestParam接收的是key-value里面的參數(shù),所以它會(huì)被切面進(jìn)行處理從而可以用普通元素、數(shù)組、集合、對(duì)象等接收)。
- 即:如果參數(shù)時(shí)放在請(qǐng)求體中,傳入后臺(tái)的話,那么后臺(tái)要用@RequestBody才能接收到;如果不是放在請(qǐng)求體中的話,那么后臺(tái)接收前臺(tái)傳過來的參數(shù)時(shí),要用@RequestParam來接收,或者形參前什么也不寫也能接收。
- 注:如果參數(shù)前寫了@RequestParam(xxx),那么前端必須有對(duì)應(yīng)的xxx名字才行(不管其是否有值,當(dāng)然可以通過設(shè)置該注解的required屬性來調(diào)節(jié)是否必須傳),如果沒有xxx名的話,那么請(qǐng)求會(huì)出錯(cuò),報(bào)400。
- 注:如果參數(shù)前不寫@RequestParam(xxx)的話,那么就前端可以有可以沒有對(duì)應(yīng)的xxx名字才行,如果有xxx名的話,那么就會(huì)自動(dòng)匹配;沒有的話,請(qǐng)求也能正確發(fā)送。
- 注:這里與feign消費(fèi)服務(wù)時(shí)不同;feign消費(fèi)服務(wù)時(shí),如果參數(shù)前什么也不寫,那么會(huì)被默認(rèn)是@RequestBody的。
如果后端參數(shù)是一個(gè)對(duì)象
且該參數(shù)前是以@RequestBody修飾的,那么前端傳遞json參數(shù)時(shí),必須滿足以下要求:
- 后端@RequestBody注解對(duì)應(yīng)的類在將HTTP的輸入流(含請(qǐng)求體)裝配到目標(biāo)類(即:@RequestBody后面的類)時(shí),會(huì)根據(jù)json字符串中的key來匹配對(duì)應(yīng)實(shí)體類的屬性,如果匹配一致且json中的該key對(duì)應(yīng)的值符合(或可轉(zhuǎn)換為),這一條我會(huì)在下面詳細(xì)分析,其他的都可簡(jiǎn)單略過,但是本文末的核心邏輯代碼以及幾個(gè)結(jié)論一定要看! 實(shí)體類的對(duì)應(yīng)屬性的類型要求時(shí),會(huì)調(diào)用實(shí)體類的setter方法將值賦給該屬性。
- json字符串中,如果value為"“的話,后端對(duì)應(yīng)屬性如果是String類型的,那么接受到的就是”",如果是后端屬性的類型是Integer、Double等類型,那么接收到的就是null。
- json字符串中,如果value為null的話,后端對(duì)應(yīng)收到的就是null。
- 如果某個(gè)參數(shù)沒有value的話,在傳json字符串給后端時(shí),要么干脆就不把該字段寫到j(luò)son字符串中;要么寫value時(shí), 必須有值,null 或""都行
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
java實(shí)現(xiàn)上傳網(wǎng)絡(luò)圖片到微信臨時(shí)素材
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)上傳網(wǎng)絡(luò)圖片到微信臨時(shí)素材,網(wǎng)絡(luò)圖片上傳到微信服務(wù)器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07Json轉(zhuǎn)list二層解析轉(zhuǎn)換代碼實(shí)例
這篇文章主要介紹了Json轉(zhuǎn)list二層解析轉(zhuǎn)換代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12intellij IDEA配置springboot的圖文教程
Spring Boot是由Pivotal團(tuán)隊(duì)提供的全新框架,其設(shè)計(jì)目的是用來簡(jiǎn)化新Spring應(yīng)用的初始搭建以及開發(fā)過程。接下來通過本文給大家介紹intellij IDEA配置springboot的圖文教程,感興趣的朋友一起看看吧2018-03-03spring和quartz整合,并簡(jiǎn)單調(diào)用(實(shí)例講解)
下面小編就為大家?guī)硪黄猻pring和quartz整合,并簡(jiǎn)單調(diào)用(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07詳解springboot通過Async注解實(shí)現(xiàn)異步任務(wù)及回調(diào)的方法
這篇文章主要介紹了springboot通過Async注解實(shí)現(xiàn)異步任務(wù)及回調(diào),文中通過一個(gè)簡(jiǎn)單示例來直觀的理解什么是同步調(diào)用,在單元測(cè)試用例中,注入?SyncTask?對(duì)象,并在測(cè)試用例中執(zhí)行?doTaskOne(),doTaskTwo(),doTaskThree()?三個(gè)方法,具體實(shí)現(xiàn)方式跟隨小編一起看看吧2022-05-05JAVA操作MongoDB數(shù)據(jù)庫實(shí)例教程
MongoDB是一個(gè)文檔型數(shù)據(jù)庫,是NOSQL家族中最重要的成員之一,下面這篇文章主要給大家介紹了關(guān)于JAVA操作MongoDB數(shù)據(jù)庫的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05解讀controller層,service層,mapper層,entity層的作用與聯(lián)系
這篇文章主要介紹了關(guān)于controller層,service層,mapper層,entity層的作用與聯(lián)系,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11