1. 程式人生 > >SpringMVC學習筆記:Ajax與Controller的引數互動

SpringMVC學習筆記:Ajax與Controller的引數互動

jQuery.ajax( options )中重要引數設定

  jQuery.ajax( options ) : 通過 HTTP 請求載入遠端資料。通過jQuery.ajax與SpringMVC的Controller互動時候,需要關注以下幾個引數(一個典型的ajax請求程式碼如下):

$.ajax({
      type: "POST",
      url: "$!{_index}/buAuth/save4",
      data:JSON.stringify(dataObj) ,
      contentType: "application/json; charset=utf-8"
, dataType: "json", success: function (response, ifo) {} });
  • contentType
    引數型別:String
    說明:(預設: “application/x-www-form-urlencoded”) 傳送資訊至伺服器時內容編碼型別。預設值適合大多數應用場合。告訴伺服器從瀏覽器提交過來的資料格式。
      例如:我們提交資料時假如使用了 JSON2.js 中方法 JSON.stringify(obj) 格式化為json字串後,再預設提交就會報錯。這個時候就需要指定提交的內容格式為:”application/json”。
  • data
    引數型別:Object,String
    說明:傳送到伺服器的資料。若data資料型別為JavaScript物件或陣列,Jquery在提交之前自動呼叫JQuery.param()方法把要傳送的資料編碼成為”application/x-www-form- urlencoded”格式的資料(即 name=value&name1=value1),此時引數為Object並且必須為 Key/Value 格式;如果為陣列,jQuery 將自動為不同值對應同一個名稱。如 {foo:[“bar1”, “bar2”]} 轉換為 ‘&foo=bar1&foo=bar2’;
      若data資料型別為String型別,則直接預設該資料已經按照”application/x-www-form-urlencoded”格式編碼完成,不再轉換。
  • dataType
    引數型別:String
    說明:預期伺服器返回的資料型別。設定HttpHeader中“Accept”域的內容,告訴伺服器瀏覽器可以想要返回的資料格式型別,同時JQuery也會根據該型別對返回的資料進行處理。如果不指定,jQuery 將自動根據 HTTP 包 MIME 資訊返回 responseXML 或 responseText,並作為回撥函式引數傳遞,可用值:
    “xml”: 返回 XML 文件,可用 jQuery 處理。
    “html”: 返回純文字 HTML 資訊;包含 script 元素。
    “script”: 返回純文字 JavaScript 程式碼。不會自動快取結果。
    “json”: 返回 JSON 資料 。JQuery將返回的字串格式資料自動轉化為Javascript物件,便於直接使用obj.property格式訪問。若沒有指定該選項,即使返回的是JSON格式的字串,JQuery也不會自動轉換。
    “jsonp”: JSONP 格式。使用 JSONP 形式呼叫函式時,如 “myurl?callback=?” jQuery 將自動替換 ? 為正確的函式名,以執行回撥函式。

Controller中接受引數

  1. 普通方式傳遞引數
@RequestMapping(value = "buAuth/save")
@ResponseBody
public String save(Integer id){
    System.out.println(id);
    return "SUCCESS";
}

  採用這種方式接受引數,其底層實現原理類似於request. getParameter()獲得引數,注意:如果位址列/buAuth/save上面沒有傳遞引數,當id為Integer的時候值為null,那麼當id為int型的時候會報錯.
  當採用位址列為/buAuth/save?id=10的訪問方式時候,引數附加在Url的後面,此時Controller中有三種接收方式
  1.String save (@RequestParam(value=”userid”)Integer id),這樣會把位址列引數名為userid的值賦給引數id,如果用位址列上的引數名為id,則接收不到
  2. String save (@RequestParam Integer id),這種情況下預設會把id作為引數名來進行接收賦值
  3.String save (Integer id),這種情況下也會預設把id作為引數名來進行接收賦值
注:如果引數前面加上@RequestParam註解,如果位址列上面沒有加上該註解的引數,例如:id,那麼會報404錯誤,找不到該路徑。
  當採用Ajax請求方式時候,需設定兩兩處(1)設定contentType的引數值為:application/x-www-form-urlencoded(該值即為預設值,也可以不設定);(2)請求引數data必須為JS物件。此時由上文Ajax引數說明可知jQuery自動呼叫JQuery.param()方法把要傳送的資料組織成類似於application/x-www-form-urlencoded(即name=value&name1=value1),然後在Controller中SpringMVC框架自動把對應的值注入到與之對應的引數中。採用Ajax的方式舉例如下:

$.ajax({
    type: "POST",
    url: "$!{_index}/buAuth/save",
    data: {buAuth:JSON.stringify(dataObj),menuIds:menu_ids},
    dataType: "json",
    success: function(data){ }
});
或
$.post("$!{_index}/buAuth/save",{buAuth:JSON.stringify(dataObj),menuIds:menu_ids},function(result){});
@RequestMapping(value = "buAuth/save")
@ResponseBody
public String save(String buAuth,String menuIds){
try {
    //需要呼叫函式把字串轉化為對應的Bean
        BuAuth buAuthBean = JSON.parseObject(buAuth, BuAuth.class);
        System.out.println(menuIds);
    }catch (Exception e){
        System.out.println(e.getMessage());
    }
    return "SUCCESS";
}

注:(1)可以採用這種方式傳遞多個物件,把每個物件在前端轉換為JSON字串對映到Controller對應的方法引數上,然後在函式體裡分別進行解析獲得到不同的物件,從而達到傳遞多個物件的效果。
  (2)當Controller的方法引數為實體類時,採用這種方式同樣能夠自動注入到引數的實體類中,此時的注入過程類似於struts2中的Model,舉例如下:

$.ajax({
    type: "POST",
    url: "$!{_index}/buAuth/save2",
    data: dataObj,//dataObj必須為js物件,例如:{menuType:"POP",busiScope:"12,11,89"}
    dataType: "json",
    success: function(data){}
});
@RequestMapping(value = "buAuth/save2")
@ResponseBody
public String save2(BuAuth buAuth){
    return "SUCCESS";
}
  1. @RequestBody註釋進行引數傳遞
@RequestMapping(value = "buAuth/save1")
@ResponseBody
public String save1(@RequestBody BuAuth buAuth){
    return "SUCCESS";
}

  採用@RequestBody標註的引數,SpringMVC框架底層能夠自動完成JSON字串轉對應的Bean並注入到方法引數中,主要是通過使用HandlerAdapter 配置的HttpMessageConverters來解析post data body,然後繫結到相應的bean上的。此時Ajax傳送的data值必須為Json字串,如果Controller中需要對映到自定義Bean物件上上,則必須設定Ajax的contentType為application/json(或application/xml)。這種方式完整舉例如下:

$.ajax({
    type: "POST",
    url: "$!{_index}/buAuth/save1",
    data:JSON.stringify(dataObj) ,//傳遞引數必須是Json字串
    contentType: "application/json; charset=utf-8",//必須宣告contentType為application/json,否則後臺使用@RequestBody標註的話無法解析引數
    dataType: "json",
    success: function (response, info) {}
});
@RequestMapping(value = "buAuth/save1")
@ResponseBody
public String save1(@RequestBody BuAuth buAuth){
    return "SUCCESS";
}

注:(1)此時前端直接用$.post()直接請求會有問題,ContentType預設是application/x-www-form-urlencoded。需要使用$.ajaxSetup()標示下ContentType為application/json(或application/xml)。

$.ajaxSetup({ContentType:" application/json"});
$.post("$!{_index}/buAuth/save",{buAuth:JSON.stringify(dataObj),menuIds:menu_ids},function(result){});

(2)可以使用@ResponseBody傳遞陣列,如下舉例(做為整理直接引用其他部落格例子)

var saveDataAry=[];
var data1={"userName":"test","address":"gz"};
var data2={"userName":"ququ","address":"gr"};
saveDataAry.push(data1);
saveDataAry.push(data2);
$.ajax({
    type:"POST",
    url:"user/saveUser",
    dataType:"json",
    contentType:"application/json",
    data:JSON.stringify(saveData),
    success:function(data){ }
});
@RequestMapping(value = "saveUser", method = {RequestMethod.POST }}) 
@ResponseBody  
public void saveUser(@RequestBody List<User> users) { 
    userService.batchSave(users); 
}

(3)Controller中的同一個方法只能使用@ResponseBody標記一個引數。也即是說無法直接通過該方法同時傳遞多個物件,不過可以間接通過設定一箇中間pojo物件(設定不同的屬性)來達到傳遞多個物件的效果。舉例如下:

var buAuthPage = {
    buAuth :   data,
    menuInfo : {code:"100"}
};
$.ajax({
    type: "POST",
    url: "$!{_index}/buAuth/save5",
    data: JSON.stringify(buAuthPage),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(data){
    }
});
public class BuAuthPage {
    BuAuth buAuth;
    MenuInfo menuInfo;

    public BuAuth getBuAuth() {
        return buAuth;
    }
    public void setBuAuth(BuAuth buAuth) {
        this.buAuth = buAuth;
    }
    public MenuInfo getMenuInfo() {
        return menuInfo;
    }
    public void setMenuInfo(MenuInfo menuInfo) {
        this.menuInfo = menuInfo;
    }
}
@RequestMapping(value = "buAuth/save5")
@ResponseBody
public String save5(@RequestBody BuAuthPage buAuthPage){
    return "SUCCESS";
}