場景如下:
前端vue使用axios向後臺發了一個Content-type為application/json
的post請求,
後臺springmvc介面如下:
@RequestMapping("xxx")
public Result xxx(User user) {
Result result = Result.getSuccessResult();
return result;
}
發現接收不到user的資訊。
改為 request.getParamter 也一樣接收不到。
搜尋一番,從這篇部落格找到了答案
AJAX POST請求中引數以form data和request payload形式在servlet中的獲取方式
jquery在執行post請求時,會設定Content-Type為application/x-www-form-urlencoded,所以伺服器能夠正確解析,而使用原生ajax請求時,如果不顯示的設定Content-Type,那麼預設是text/plain,這時伺服器就不知道怎麼解析資料了,所以才只能通過獲取原始資料流的方式來進行解析請求資料。
HTTP POST表單請求提交時,使用的Content-Type是application/x-www-form-urlencoded,而使用原生AJAX的POST請求如果不指定請求頭RequestHeader,預設使用的Content-Type是text/plain;charset=UTF-8。
由於Tomcat對於Content-Type multipart/form-data(檔案上傳)和application/x-www-form-urlencoded(POST請求)做了“特殊處理”。
伺服器為什麼會對錶單提交和檔案上傳做特殊處理,是因為表單提交資料是名值對的方式,且Content-Type為application/x-www-form-urlencoded,而檔案上傳伺服器需要特殊處理,普通的post請求(Content-Type不是application/x-www-form-urlencoded)資料格式不固定,不一定是名值對的方式,所以伺服器無法知道具體的處理方式,所以只能通過獲取原始資料流的方式來進行解析。
總結為:原生ajax如果不指定Context-type
預設使用text/plain;charset=UTF-8
,jquery的ajax則是application/x-www-form-urlencoded
,而axios底層正是使用了原生的ajax,後端會對非Content-type不為application/x-www-form-urlencoded
的請求做特殊處理,由此導致後端request.getParameter()
無法接收。
解決方法:
1、不使用框架的情況下,使用原始的讀取流的方式:
private String getRequestPayload(HttpServletRequest req) {
StringBuildersb = new StringBuilder();
try(BufferedReaderreader = req.getReader();) {
char[]buff = new char[1024];
intlen;
while((len = reader.read(buff)) != -1) {
sb.append(buff,0, len);
}
}catch (IOException e) {
e.printStackTrace();
}
returnsb.toString();
}
2、使用spring框架:
加入@RequestBody
註解,如下:
@RequestMapping("xxx")
public Result xxx(@RequestBody User user) {
Result result = Result.getSuccessResult();
return result;
}