一:問題demo展示
在開發(fā)新需求,調(diào)試代碼的時候發(fā)現(xiàn)一個問題,就是HttpServletRequest 獲取不到ajax post請求的json參數(shù)!下面是偽代碼是整個請求的邏輯!
1.前臺JS請求代碼(偽代碼)
var _phoneId = "123456789";
var closeUrl=contextPath+"/close";
ajax(closeUrl,{"phoneId":_phoneId},"post",false,callbackForSessionClose,null,'json');
function ajax(url,reqData,type,async,successBack,errorBack,statusText,dataType){
$.ajax({
type : type,
url : url,
dataType : dataType,
async : async,
timeout : "60000",
contentType : "application/json",
data : JSON.stringify(reqData),
success : function(data) {
// 成功的處理邏輯
},
error : function(data) {
// 錯誤的處理邏輯
}
});
}
2.后臺代碼(偽代碼)
@RequestMapping(value="/close",method=RequestMethod.POST)
@ResponseBody
public String closeSession(HttpServletRequest request){
String response;
try{
String phoneId = request.getParameter("phoneId");
if(phoneId == "123456789"){
response = "success";
}else{
response = "error";
}
}catch (ServiceException e) {
//業(yè)務(wù)異常處理邏輯
}catch (Exception e) {
//非業(yè)務(wù)異常處理邏輯
}
return response;
}
二:問題分析
正常的post請求(不包括ajax請求)在http頭中的content-type為application/x-www-form-urlencoded,這時在java后臺可以通過request.getParameter(name)的形式獲取.但是通過原生ajax請求時,在java后臺通過request.getParameter(name)的形式卻無法獲取到傳入的參數(shù).
原因是原生ajax請求時,在http頭中的content-type為text/plain;charset=UTF-8.當(dāng)請求到達tomcat服務(wù)器時,服務(wù)器只對application/x-www-form-urlencoded形式的http,post請求進行讀取body體中的參數(shù),并放到request的parameter中,對于原生ajax請求則直接忽略,不會讀取body體中的參數(shù),才導(dǎo)致request.getParameter(name)讀取不到參數(shù).
根據(jù)上面的分析結(jié)合自己的當(dāng)前系統(tǒng),發(fā)現(xiàn)系統(tǒng)封裝的ajax默認(rèn)content-type為application/json,那么這種方式在java后臺通過request.getParameter(name)的形式是不能獲取到傳入的參數(shù)的!
三:解決方案
1.[前臺解決方案]修改Ajax post請求的contentType和data
修改前:
contentType : "application/json",
data : JSON.stringify(reqData),
修改后:
contentType : "application/x-www-form-urlencoded",
data : reqData, //不需要使用JSON.stringify()
后臺代碼不變!
2.[后臺解決方案]使用@RequestBody
前臺js代碼不變!
后臺代碼修改:
新增一個類:
public class CloseRequestVO implements Serializable{
private String phoneId;
//省略get set方法
//....
}
@RequestMapping(value="/close",method=RequestMethod.POST)
@ResponseBody
public String closeSession(@RequestBody CloseRequestVO requestVO){
String response;
try{
String phoneId = requestVO.getPhoneId();
if(phoneId == "123456789"){
response = "success";
}else{
response = "error";
}
}catch (ServiceException e) {
//業(yè)務(wù)異常處理邏輯
}catch (Exception e) {
//非業(yè)務(wù)異常處理邏輯
}
return response;
}
后臺通過request.getParameter(name)方式就可以獲取到參數(shù).
上面兩種方式選擇適合自己系統(tǒng)的方案即可!
四:@RequestBody簡單介紹
@RequestBody : @RequestBody是指方法參數(shù)應(yīng)該被綁定到HTTP請求Body上
<font color='red'>申明:在SpringMVC環(huán)境中,@RequestBody接收的是一個Json對象的字符串,而不是一個Json對象。</font>
所以
第一:@RequestBody需要接的參數(shù)是一個String化的json,前臺js代碼可以直接使用JSON.stringify(json)這個方法來轉(zhuǎn)化;
第二:從@RequestBody名稱上來看,也就是說要讀取的數(shù)據(jù)在請求體(body)里,所以要發(fā)post請求;
第三:@RequestBody接收的是一個String的Json,那么要設(shè)置請求contentType,contentType:"application/json,明確的告訴服務(wù)器發(fā)送的內(nèi)容是json。
五:參考資料
jquery通過ajax-json訪問java后臺傳遞參數(shù),通過request.getParameter獲取不到參數(shù)的說明
如果帥氣(美麗)、睿智(聰穎),和我一樣簡單善良的你看到本篇博文中存在問題,請指出,我虛心接受你讓我成長的批評,謝謝閱讀!
祝你今天開心愉快!
歡迎訪問我的csdn博客,我們一同成長!
不管做什么,只要堅持下去就會看到不一樣!在路上,不卑不亢!