Java中POST、GET、@RequestBody和@RequestParam區(qū)別詳析
@RequestParam
注解@RequestParam接收的參數是來自HTTP請求體或請求url的QueryString中。
RequestParam可以接受簡單類型的屬性,也可以接受對象類型。
@RequestParam有三個配置參數:
required表示是否必須,默認為true,必須。defaultValue可設置請求參數的默認值。value為接收url的參數名(相當于key值)。
@RequestParam用來處理 Content-Type 為 application/x-www-form-urlencoded 編碼的內容,Content-Type默認為該屬性。@RequestParam也可用于其它類型的請求,例如:POST、DELETE等請求。
所以在postman中,要選擇body的類型為 x-www-form-urlencoded,這樣在headers中就自動變?yōu)榱?Content-Type : application/x-www-form-urlencoded 編碼格式。如下圖所示:

但是這樣不支持批量插入數據啊,如果改用 json 字符串來傳值的話,類型設置為 application/json,點擊發(fā)送的話,會報錯,后臺接收不到值,為 null。
但可以入參后再轉換,參考如下:
@PostMapping("/ali-receive")
public void aliReceive(@RequestParam("message") String message) {
ReceiveLog receiveLog = JSON.parseObject(message, ReceiveLog.class);
}解決Spring/SpringBoot @RequestParam注解無法讀取application/json格式數據:http://www.dhdzp.com/article/265478.htm
@RequestParam 接受JSON的字符串:
@RequestParam
1.用來處理Content-Type: 為 application/x-www-form-urlencoded編碼的內容。(Http協議中,如果不指定Content-Type,則默認傳遞的參數就是application/x-www-form-urlencoded類型)
@RequestParam可以接受簡單類型的屬性,也可以接受對象類型。
2.用來處理 multipart/form-data (表單上傳的)
如何使用@RequestParam 接受JSON的字符串
- 前端代碼
const message = {
"data": {
"userInfo": "2804951212",
"offerId": offerId,
"action": "distribution",
"categoryNav": categoryNav
},
"gmtBorn": time,
"msgId": time,
"type": "PRODUCT_COLLECTION",
"userInfo": "chrome"
};
$.ajax({
contentType :'application/x-www-form-urlencoded',
type:'post',
url: baseUrl+'/ali-receive',
data:"message="+JSON.stringify(message)
});
后端代碼
? ?@PostMapping("/ali-receive")
? ? public void aliReceive(@RequestParam("message") String message) {
? ? ? ? ? ? ? ? ReceiveLog receiveLog = JSON.parseObject(message, ReceiveLog.class);
? ? }@RequestBody
一般用來處理 Content-Type: 為application/json
不推薦使用@RequestParam接收application/json,這時候就需要使用到@RequestBody。
@RequestBody
注解@RequestBody接收的參數是來自requestBody中,即請求體。一般用于處理非 Content-Type: application/x-www-form-urlencoded編碼格式的數據,比如:application/json、application/xml等類型的數據。
就application/json類型的數據而言,使用注解@RequestBody可以將body里面所有的json數據傳到后端,后端再進行解析。
GET請求中,因為沒有HttpEntity,所以@RequestBody并不適用。
POST請求中,通過HttpEntity傳遞的參數,必須要在請求頭中聲明數據的類型Content-Type,SpringMVC通過使用
HandlerAdapter 配置的HttpMessageConverters來解析HttpEntity中的數據,然后綁定到相應的bean上。
向表中批量插入數據
舉個批量插入數據的例子,Controller層的寫法如下圖所示:

由于@RequestBody可用來處理 Content-Type 為 application/json 編碼的內容,所以在postman中,選擇body的類型為row -> JSON(application/json),這樣在 Headers 中也會自動變?yōu)?Content-Type : application/json 編碼格式。body內的數據如下圖所示:

批量向表中插入兩條數據,這里的 saveBatchNovel()方法已經封裝了 JPA的 saveAll() 方法。body 里面的 json 語句的 key 值要與后端實體類的屬性一一對應。
注意:前端使用$.ajax的話,一定要指定 contentType: "application/json;charset=utf-8;",默認為 application/x-www-form-urlencoded。
后端解析json數據
上述示例是傳遞到實體類中的具體寫法,那么如果傳遞到非實體類中,body里面的json數據需要怎么解析呢?我們再來看下面這個例子:
在body中,我們還是輸入上面的json數據,根據分析,上面的json數據是一個List數組內嵌套著map對象,那么在后臺的接收形式可寫為 List<Map<String, String>>,具體代碼如下圖所示:

postman請求:

控制臺輸出:

得出結論,通過@RequestBody可以解析Body中json格式的數據。
POST請求時
@RequestBody --> JSON字符串部分
@RequestParam --> 請求參數部分
application/json格局圖

form-data、x-www-form-urlencoded格局圖

1、從content-type方面總結:
① form-data、x-www-form-urlencoded:不可以用@RequestBody;可以用@RequestParam。見postman的格局,這兩種方式的時候沒有json字符串部分。
② application/json:json字符串部分可以用@RequestBody;url中的?后面參數可以用@RequestParam。見postman的格局
2、從兩種注解方式總結:
@RequestBody
(@RequestBody Map map) (@RequestBody Object object) application/json時候可用 form-data、x-www-form-urlencoded時候不可用
@RequestParam
(@RequestParam Map map) application/json時候,json字符串部分不可用,url中的?后面添加參數即可用,form-data、x-www-form-urlencoded時候可用,但是要將Headers里的Content-Type刪掉
(@RequestParam String waterEleId,@RequestParam String enterpriseName) application/json時候,json字符串部分不可用,url中的?后面添加參數即可用 form-data、x-www-form-urlencoded時候可用,且參數可以沒有順序(即前端傳過來的參數或者url中的參數順序不必和后臺接口中的參數順序一致,只要字段名相同就可以),但是要將Headers里的Content-Type刪掉
(@RequestParam Object object) 不管application/json、form-data、x-www-form-urlencoded都不可用
既不是@RequestBody也不是@RequestParam,沒有指定參數哪種接收方式
(Map map) (Object object) application/json時候:json字符串部分不可用,url中的?后面添加參數不可用。 因為沒有指定,它也不知道到底是用json字符串部分還是?后面添加參數部分,所以干脆都不可以用 form-data、x-www-form-urlencoded時都不可用,見圖二 (HttpServletRequest request) application/json不可用 form-data、x-www-form-urlencoded時可用
GET請求
@RequestBody
RequestBody -- Map / Object GET請求中不可以使用@RequestBody
@RequestParam
(@RequestParam Map map) 在url中的?后面添加參數即可使用
(@RequestParam String waterEleId,@RequestParam String enterpriseName) 在url中的?后面添加參數即可使用
(@RequestParam Object object) GET請求中不可以使用
當使用GET請求時,通過postman添加?后面的參數,不用在url中自己一個一個拼,點擊Params,在下面key-value中輸入就自動拼接到url中

舉栗子
上傳文件,包含了圖中圈出來的兩部分

如果這樣,沒有@RequestParam,那么url?后的參數就拿不到
@RequestMapping(value = "/leadingIn", method = RequestMethod.POST)
public ResponseObj<Boolean> leadingIn(Map formData,
HttpServletRequest request,
Map<String, InputStream> files) {
}如果control中這樣接收,本來想formData只接收url?后的參數,結果將{ "retCode": null, "data": true }這部分內容也拿到了,真實意外之喜。字符串這部分內容還可以從request中取到,見下面完整方法。
@RequestMapping(value = "/leadingIn", method = RequestMethod.POST)
public ResponseObj<Boolean> leadingIn(@RequestParam Map formData,
HttpServletRequest request,
Map<String, InputStream> files) {
}完整方法
/**
* 導入
*/
@RequestMapping(value = "/leadingIn", method = RequestMethod.POST)
public ResponseObj<Boolean> leadingIn(@RequestParam Map formData,
HttpServletRequest request,
Map<String, InputStream> files) {
//測試
try {
MultipartHttpServletRequest mulRequest = (MultipartHttpServletRequest) request;
Set<Map.Entry<String, MultipartFile>> set = mulRequest.getFileMap().entrySet();
Map<String, InputStream> listFile = new LinkedHashMap<>();
System.out.println("個數" + set.size());
for (Map.Entry<String, MultipartFile> each : set) {
String fileName = each.getKey();
MultipartFile file = each.getValue();
//這里需要上傳FTP
try {
listFile.put(fileName, file.getInputStream());
} catch (Exception ex) {
return new ResponseObj<>(false, null);
}
}
String formjson = mulRequest.getParameter("content");
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// boolean result = iInstallWorkOrder.upLoadFile(listFile);
boolean result = true;
return new ResponseObj<>(result, null);
} catch (Exception ex) {
System.out.println(ex.toString());
return new ResponseObj<>(false, null);
}
}按F12看一下Network里對應請求:
使用@RequestParam:Content-Type為application/x-www-form-urlencoded,參數在FormData中

使用@RequestBody:Content-Type為application/json,參數在Request PayLoad中

總結
•在GET請求中,不能使用@RequestBody。
•在POST請求,可以使用@RequestBody和@RequestParam,但是如果使用@RequestBody,對于參數轉化的配置必須統(tǒng)一。
可以使用多個@RequestParam獲取數據,@RequestBody不可以 舉個例子,在SpringMVC配置了HttpMessageConverters處理棧中,指定json轉化的格式,如Date轉成‘yyyy-MM-dd’,則參數接收對象包含的字段如果是Date類型,就只能讓客戶端傳遞年月日的格式,不能傳時分秒。因為不同的接口,它的參數可能對時間參數有不同的格式要求,所以這樣做會讓客戶端調用同事對參數的格式有點困惑,所以說擴展性不高。 如果使用@RequestParam來接受參數,可以在接受參數的model中設置@DateFormat指定所需要接受時間參數的格式。 另外,使用@RequestBody接受的參數是不會被Servlet轉化統(tǒng)一放在request對象的Param參數集中,@RequestParam是可以的。
另外,還有一種應用場景,接口規(guī)范為resultful風格時,舉個例子:如果要獲取某個id下此條問題答案的查詢次數的話,則后臺就需要動態(tài)獲取參數,其注解為@PathVariable,并且requestMapping中的value應為value="/{id}/queryNum",截圖如下:

到此這篇關于Java中POST、GET、@RequestBody和@RequestParam區(qū)別詳析的文章就介紹到這了,更多相關POST GET @RequestBody和@RequestParam區(qū)別內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
參考:
@RequestParam @RequestBody @PathVariable 等參數綁定注解詳解
https://blog.csdn.net/walkerjong/article/details/7946109
https://my.oschina.net/u/3372000/blog/906217
https://www.jianshu.com/p/4981911d5e15
https://cloud.tencent.com/developer/article/1414464
相關文章
Java中BeanUtils.copyProperties基本用法與小坑
本文主要介紹了Java中BeanUtils.copyProperties基本用法與小坑,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-04-04
Prometheus監(jiān)控Springboot程序的實現方法
這篇文章主要介紹了Prometheus監(jiān)控Springboot程序的實現方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03

