淺談@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)測試,分別使用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ì)分析,其他的都可簡單略過,但是本文末的核心邏輯代碼以及幾個(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)文章
MyBatis-Plus速成指南之簡化你的數(shù)據(jù)庫操作流程(最新推薦)
MyBatis-Plus?是一個(gè)?MyBatis?的增強(qiáng)工具,在?MyBatis?的基礎(chǔ)上只做增強(qiáng)不做改變,為簡化開發(fā)、提高效率而生,這篇文章主要介紹了MyBatis-Plus速成指南:簡化你的數(shù)據(jù)庫操作流程,需要的朋友可以參考下2025-02-02
springboot自帶的緩存@EnableCaching用法
這篇文章主要介紹了springboot自帶的緩存@EnableCaching用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
SpringBoot執(zhí)行定時(shí)任務(wù)@Scheduled的方法
這篇文章主要介紹了SpringBoot執(zhí)行定時(shí)任務(wù)@Scheduled的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
Java利用位運(yùn)算實(shí)現(xiàn)乘法運(yùn)算詳解
這篇文章主要為大家詳細(xì)介紹了Java如何用位運(yùn)算實(shí)現(xiàn)乘法運(yùn)算,在實(shí)現(xiàn)乘法時(shí)要用位運(yùn)算實(shí)現(xiàn),并且不能出現(xiàn)加減乘除任何符號(hào),感興趣的可以了解一下2023-04-04
通過jstack分析解決進(jìn)程死鎖問題實(shí)例代碼
這篇文章主要介紹了通過jstack分析解決進(jìn)程死鎖問題實(shí)例代碼,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01
JAVA面試題 簡談你對(duì)synchronized關(guān)鍵字的理解
這篇文章主要介紹了JAVA面試題 請(qǐng)談?wù)勀銓?duì)Sychronized關(guān)鍵字的理解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07
實(shí)例解析Java設(shè)計(jì)模式編程中的適配器模式使用
本篇文章主要通過實(shí)例對(duì)適配器模式進(jìn)行了詳解,需要的朋友可以參考下2017-04-04

