SpringMVC中使用Ajax POST請求發現一個小問題排查過程

作一個積極的人java

編碼、改bug、提高本身jquery

我有一個樂園,面向編程,春暖花開!ajax

SpringMVC中使用Ajax POST請求以json格式傳遞參數服務端經過request.getParameter("name")沒法獲取參數值問題分析編程

1、問題demo展現

在開發新需求,調試代碼的時候發現一個問題,就是HttpServletRequest 獲取不到ajax post請求的json參數!下面是僞代碼是整個請求的邏輯!json

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) {
        //業務異常處理邏輯
    }catch (Exception e) {
        //非業務異常處理邏輯

    }
    return response;
}
複製代碼

2、問題分析

正常的post請求(不包括ajax請求)在http頭中的content-type爲application/x-www-form-urlencoded,這時在java後臺能夠經過request.getParameter(name)的形式獲取.可是經過原生ajax請求時,在java後臺經過request.getParameter(name)的形式卻沒法獲取到傳入的參數.tomcat

緣由是原生ajax請求時,在http頭中的content-type爲text/plain;charset=UTF-8.當請求到達tomcat服務器時,服務器只對application/x-www-form-urlencoded形式的http,post請求進行讀取body體中的參數,並放到request的parameter中,對於原生ajax請求則直接忽略,不會讀取body體中的參數,才致使request.getParameter(name)讀取不到參數.服務器

根據上面的分析結合本身的當前系統,發現系統封裝的ajax默認content-type爲application/json,那麼這種方式在java後臺經過request.getParameter(name)的形式是不能獲取到傳入的參數的!app

3、解決方案

1.[前臺解決方案]修改Ajax post請求的contentType和data

修改前:async

contentType : "application/json",
    data : JSON.stringify(reqData),
		
複製代碼

修改後:post

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) {
        //業務異常處理邏輯
    }catch (Exception e) {
        //非業務異常處理邏輯

    }
    return response;
}
複製代碼

後臺經過request.getParameter(name)方式就能夠獲取到參數.

上面兩種方式選擇適合本身系統的方案便可!

4、@RequestBody簡單介紹

@RequestBody : @RequestBody是指方法參數應該被綁定到HTTP請求Body上

申明:在SpringMVC環境中,@RequestBody接收的是一個Json對象的字符串,而不是一個Json對象。 因此 第一:@RequestBody須要接的參數是一個String化的json,前臺js代碼能夠直接使用JSON.stringify(json)這個方法來轉化;

第二:從@RequestBody名稱上來看,也就是說要讀取的數據在請求體(body)裏,因此要發post請求;

第三:@RequestBody接收的是一個String的Json,那麼要設置請求contentType,contentType:"application/json,明確的告訴服務器發送的內容是json。

五:參考資料

jquery經過ajax-json訪問java後臺傳遞參數,經過request.getParameter獲取不到參數的說明

@RequestBody應用


謝謝你的閱讀,若是您以爲這篇博文對你有幫助,請點贊或者喜歡,讓更多的人看到!祝你天天開心愉快!



無論作什麼,只要堅持下去就會看到不同!在路上,不卑不亢!

願你我在人生的路上能都變成最好的本身,可以成爲一個獨擋一面的人

© 天天都在變得更好的阿飛雲

相關文章
相關標籤/搜索