淺談@RequestBody和@RequestParam可以同時使用
@RequestBody和@RequestParam可以同時使用嗎
@RequestParam和@RequestBody這兩個注解是可以同時使用的。
網(wǎng)上有很多博客說@RequestParam 和@RequestBody不能同時使用,這是錯誤的。
根據(jù)HTTP協(xié)議,并沒有說post請求不能帶URL參數(shù),經(jīng)驗證往一個帶有參數(shù)的URL發(fā)送post請求也是可以成功的。只不過,我們?nèi)粘i_發(fā)使用GET請求搭配@RequestParam,使用POST請求搭配@RequestBody就滿足了需求,基本不怎么同時使用二者而已。
自己個人實際驗證結(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請求,返回正常

body中參數(shù)如下

從結(jié)果來看,post請求URL帶參數(shù)是沒有問題的,所以@RequestParam和@RequestBody是可以同時使用的【經(jīng)測試,分別使用Postman 和 httpClient框架編程發(fā)送http請求,后端@RequestParam和@RequestBody都可以正常接收請求參數(shù),所以個人認(rèn)為可能一些前端框架不支持或者沒必要這么做,但是不能說@RequestParam和@RequestBody 不能同時使用】。
值得注意的地方
1、postman的GET請求是不支持請求body的;
2、
@GetMapping(value = "/dxc")
public String print(PramInfo info) {
return info.getId() + ": :" + info.getStr();
}這種請求方式,不加@RequestParam注解,也能直接取出URL后面的參數(shù),即參數(shù)可以與定義的類互相自動轉(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());如果請求中的body沒有ParamInfo對象對應(yīng)的json串,即當(dāng)body為空(連json串的{}都沒有)時,會報請求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ù)的(請求體中的數(shù)據(jù));
@RequestParam作用
將請求參數(shù)綁定到你控制器的方法參數(shù)上
GET方式無請求體,所以使用@RequestBody接收數(shù)據(jù)時,前端不能使用GET方式提交數(shù)據(jù),而是用POST方式進(jìn)行提交。在后端的同一個接收方法里,@RequestBody與@RequestParam()可以同時使用,@RequestBody最多只能有一個,而@RequestParam()可以有多個。
@RequestBody:
- 注:一個請求,只有一個RequestBody;一個請求,可以有多個RequestParam。
- 注:當(dāng)同時使用@RequestParam()和@RequestBody時,@RequestParam()指定的參數(shù)可以是普通元素、數(shù)組、集合、對象等等(即:當(dāng),@RequestBody 與@RequestParam()可以同時使用時,原SpringMVC接收參數(shù)的機制不變,只不過RequestBody 接收的是請求體里面的數(shù)據(jù);而RequestParam接收的是key-value里面的參數(shù),所以它會被切面進(jìn)行處理從而可以用普通元素、數(shù)組、集合、對象等接收)。
- 即:如果參數(shù)時放在請求體中,傳入后臺的話,那么后臺要用@RequestBody才能接收到;如果不是放在請求體中的話,那么后臺接收前臺傳過來的參數(shù)時,要用@RequestParam來接收,或者形參前什么也不寫也能接收。
- 注:如果參數(shù)前寫了@RequestParam(xxx),那么前端必須有對應(yīng)的xxx名字才行(不管其是否有值,當(dāng)然可以通過設(shè)置該注解的required屬性來調(diào)節(jié)是否必須傳),如果沒有xxx名的話,那么請求會出錯,報400。
- 注:如果參數(shù)前不寫@RequestParam(xxx)的話,那么就前端可以有可以沒有對應(yīng)的xxx名字才行,如果有xxx名的話,那么就會自動匹配;沒有的話,請求也能正確發(fā)送。
- 注:這里與feign消費服務(wù)時不同;feign消費服務(wù)時,如果參數(shù)前什么也不寫,那么會被默認(rèn)是@RequestBody的。
如果后端參數(shù)是一個對象
且該參數(shù)前是以@RequestBody修飾的,那么前端傳遞json參數(shù)時,必須滿足以下要求:
- 后端@RequestBody注解對應(yīng)的類在將HTTP的輸入流(含請求體)裝配到目標(biāo)類(即:@RequestBody后面的類)時,會根據(jù)json字符串中的key來匹配對應(yīng)實體類的屬性,如果匹配一致且json中的該key對應(yīng)的值符合(或可轉(zhuǎn)換為),這一條我會在下面詳細(xì)分析,其他的都可簡單略過,但是本文末的核心邏輯代碼以及幾個結(jié)論一定要看! 實體類的對應(yīng)屬性的類型要求時,會調(diào)用實體類的setter方法將值賦給該屬性。
- json字符串中,如果value為"“的話,后端對應(yīng)屬性如果是String類型的,那么接受到的就是”",如果是后端屬性的類型是Integer、Double等類型,那么接收到的就是null。
- json字符串中,如果value為null的話,后端對應(yīng)收到的就是null。
- 如果某個參數(shù)沒有value的話,在傳json字符串給后端時,要么干脆就不把該字段寫到j(luò)son字符串中;要么寫value時, 必須有值,null 或""都行
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
MyBatis-Plus速成指南之簡化你的數(shù)據(jù)庫操作流程(最新推薦)
MyBatis-Plus?是一個?MyBatis?的增強工具,在?MyBatis?的基礎(chǔ)上只做增強不做改變,為簡化開發(fā)、提高效率而生,這篇文章主要介紹了MyBatis-Plus速成指南:簡化你的數(shù)據(jù)庫操作流程,需要的朋友可以參考下2025-02-02
springboot自帶的緩存@EnableCaching用法
這篇文章主要介紹了springboot自帶的緩存@EnableCaching用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08
SpringBoot執(zhí)行定時任務(wù)@Scheduled的方法
這篇文章主要介紹了SpringBoot執(zhí)行定時任務(wù)@Scheduled的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07
JAVA面試題 簡談你對synchronized關(guān)鍵字的理解
這篇文章主要介紹了JAVA面試題 請談?wù)勀銓ychronized關(guān)鍵字的理解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-07-07

