一:?jiǎn)栴}demo展示
在開發(fā)新需求隔嫡,調(diào)試代碼的時(shí)候發(fā)現(xiàn)一個(gè)問題管削,就是HttpServletRequest 獲取不到ajax post請(qǐng)求的json參數(shù)杂彭!下面是偽代碼是整個(gè)請(qǐng)求的邏輯岩喷!
1.前臺(tái)JS請(qǐng)求代碼(偽代碼)
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) {
// 錯(cuò)誤的處理邏輯
}
});
}
2.后臺(tái)代碼(偽代碼)
@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;
}
二:?jiǎn)栴}分析
正常的post請(qǐng)求(不包括ajax請(qǐng)求)在http頭中的content-type為application/x-www-form-urlencoded,這時(shí)在java后臺(tái)可以通過request.getParameter(name)的形式獲取.但是通過原生ajax請(qǐng)求時(shí),在java后臺(tái)通過request.getParameter(name)的形式卻無法獲取到傳入的參數(shù).
原因是原生ajax請(qǐng)求時(shí),在http頭中的content-type為text/plain;charset=UTF-8.當(dāng)請(qǐng)求到達(dá)tomcat服務(wù)器時(shí),服務(wù)器只對(duì)application/x-www-form-urlencoded形式的http,post請(qǐng)求進(jìn)行讀取body體中的參數(shù),并放到request的parameter中,對(duì)于原生ajax請(qǐng)求則直接忽略,不會(huì)讀取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后臺(tái)通過request.getParameter(name)的形式是不能獲取到傳入的參數(shù)的礼旅!
三:解決方案
1.[前臺(tái)解決方案]修改Ajax post請(qǐng)求的contentType和data
修改前:
contentType : "application/json",
data : JSON.stringify(reqData),
修改后:
contentType : "application/x-www-form-urlencoded",
data : reqData, //不需要使用JSON.stringify()
后臺(tái)代碼不變膳叨!
2.[后臺(tái)解決方案]使用@RequestBody
前臺(tái)js代碼不變!
后臺(tái)代碼修改:
新增一個(gè)類:
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;
}
后臺(tái)通過request.getParameter(name)方式就可以獲取到參數(shù).
上面兩種方式選擇適合自己系統(tǒng)的方案即可痘系!
四:@RequestBody簡(jiǎn)單介紹
@RequestBody : @RequestBody是指方法參數(shù)應(yīng)該被綁定到HTTP請(qǐng)求Body上
<font color='red'>申明:在SpringMVC環(huán)境中,@RequestBody接收的是一個(gè)Json對(duì)象的字符串菲嘴,而不是一個(gè)Json對(duì)象。</font>
所以
第一:@RequestBody需要接的參數(shù)是一個(gè)String化的json汰翠,前臺(tái)js代碼可以直接使用JSON.stringify(json)這個(gè)方法來轉(zhuǎn)化龄坪;
第二:從@RequestBody名稱上來看,也就是說要讀取的數(shù)據(jù)在請(qǐng)求體(body)里复唤,所以要發(fā)post請(qǐng)求健田;
第三:@RequestBody接收的是一個(gè)String的Json,那么要設(shè)置請(qǐng)求contentType佛纫,contentType:"application/json妓局,明確的告訴服務(wù)器發(fā)送的內(nèi)容是json。
五:參考資料
jquery通過ajax-json訪問java后臺(tái)傳遞參數(shù),通過request.getParameter獲取不到參數(shù)的說明
如果帥氣(美麗)雳旅、睿智(聰穎)跟磨,和我一樣簡(jiǎn)單善良的你看到本篇博文中存在問題间聊,請(qǐng)指出攒盈,我虛心接受你讓我成長(zhǎng)的批評(píng),謝謝閱讀哎榴!
祝你今天開心愉快型豁!
歡迎訪問我的csdn博客,我們一同成長(zhǎng)尚蝌!
不管做什么迎变,只要堅(jiān)持下去就會(huì)看到不一樣!在路上飘言,不卑不亢!