利用post向後臺傳遞數組或者list參數

在項目上用到了批量刪除與批量更改狀態,前臺使用了EasyUI的DataGrid,用到了批量更改數據狀態功能。java

在前臺能夠獲取每條數據的ID,可是如何經過數組方式傳遞給後臺?jquery

目前有兩種方式可行:ajax

方式一:json

前臺代碼:api

// 方式一  
var _list = {};  
  
for (var i = 0; i < checkedRow.length; i++) {  
    _list["selectedIDs[" + i + "]"] = checkedRow[i].ID;  
}  
  
$.ajax({  
    url: '@Url.Action("SetCallBackStatus")',   
    //data: { "selectedIDs": _list },  
    data: _list,  
    dataType: "json",  
    type: "POST",  
    //traditional: true,  
    success: function (responseJSON) {  
        // your logic  
        alert('Ok');  
    }  
});

注意:數組

一、_list 是一個對象瀏覽器

二、_list中的屬性須要結合後臺參數名稱,例如」selectedIDs「,組合成相似:selectedIDs[0],selectedIDs[1]...等Request.Paramsapp

這裏是最重要的,不然後臺認不出來。這種方式也能夠傳遞自定義類的數組。組合方式就是selectedIDs[0].FirstName,selectedIDs[0].LastName,selectedIDs[1].FirstName,selectedIDs[1].LastName...框架

三、ajax的data參數直接指定爲_listpost

後臺代碼:

public ActionResult SetCallBackStatus(List<int> selectedIDs){  
       string result = "ok";  
       string errMsg = "";  
       return this.JsonFormat(new { result = result, errMsg = errMsg });  
}

 

方式二:

前臺代碼:

var _list = [];  
  
for (var i = 0; i < checkedRow.length; i++) {  
    _list[i] = checkedRow[i].ID;  
}  
  
$.ajax({  
    url: '@Url.Action("SetCallBackStatus")',  
    data: { "selectedIDs": _list },  
    //data: _list,  
    dataType: "json",  
    type: "POST",  
    traditional: true,  //使用該屬性放置深度序列化
    success: function (responseJSON) {  
        // your logic  
        alert('Ok');  
    }  
}); 

或者使用post
var url = '@Url.Action("SetCallBackStatus")';
var data = { "selectedIDs": _list };
//$.param(data,true)不會深度解析參數,返回一個字符串,字符串這種格式:"x=1&y=2&xx=3&xx=4",和GET方式在url後拼接請求參數是同樣的
$.post(url ,$.param(data,true),function(data){
		var obj=eval('('+data+')');
		console.info('success');
});

注意:

一、_list 是一個數組。

二、ajax參數中data爲{「selectedIDs」:_list}//傳遞的參數selectedIDs爲一個數組

三、這種方式比較重要的 traditional:true,或者將 _list參數轉換一下$.param(_list,true)。這裏其實就是將_list做爲傳統的方式傳遞給後臺。JQUERY默認是作了轉換的,自動在參數後面追加了」[]「。

如:

$.param(object,trad)
參數說明
object:必需。規定要序列化的數組或對象。
trad:可選。布爾值,指定是否使用參數序列化的傳統樣式
 
有時候提交參數中有數組,設置這個可選項就顯得十分必要了。
 
var obj = {
    title: "test",
    arr:[1,2,3]
};
     
$.param(obj,true)
--->>title=test&arr=1&arr=2&arr=3
 
$.param(obj)
--->>title=test&arr%5B%5D=1&arr%5B%5D=2&arr%5B%5D=3

後臺代碼:

同方式一

下面以實際中的例子來講明:

data是一個對象,裏面有一個object對象,object的屬性typeMaskValues爲一個數組,有三個元素在數組中

發送請求方式:

var data={"id":row.id};
	for (var key in row)
	{
		if (!$.isArray(row[key]) && !$.isFunction(row[key])
				&& (typeof row[key]) == "object")
		{
			continue;
		}
		data["object."+key]=row[key];
	}
	var param = JSON.stringify(data);
	var param2 = $.param(data);
	var param3 = $.param(data,true);
	debugger;
	$.post(url,data,function(data){
	});		
	
	$.post(url,param,function(data){
		console.info(111);
	});		
	$.post(url,param2,function(data){
		console.info(222);
	});		
	$.post(url,param3,function(data){
		console.info(222);
	});		
	$.ajax({  
	    url: url,  
	    data: data,  
	    dataType: "json",  
	    type: "POST",  
//	    traditional: true,  //使用該屬性放置深度序列化
	    success: function (responseJSON) {  
	        console.info(333);
	    }  
	});
	$.ajax({  
		url: url,  
		data: data,  
		dataType: "json",  
		type: "POST",  
	    traditional: true,  //使用該屬性放置深度序列化
		success: function (responseJSON) {  
			console.info(444);
		}  
	});

1. JSON.Stringify()處理後返回字符串:

var param = JSON.stringify(data);

由於data爲一個對象,因此在轉化爲JSON字符串的時候以"{}"包裹,裏面的數組格式爲:"xx":["1","2"]

JSON字符串開始:

JSON字符串裏面的數組:

2. $.param 處理後的格式爲字符串,該字符串的式樣爲get請求在後面拼接多個參數的方式同樣,

var param2 = $.param(data);

字符串開始:

裏面的數組:

3.$.param 處理後的格式爲字符串,該字符串的式樣爲get請求在後面拼接多個參數的方式同樣,

var param3 = $.param(data,true);

字符串開始:

裏面的數組:

POST方式向後臺傳遞參數:

1. $.post(url,data,function(data){});        

控制檯的參數傳遞:

2. $.post(url,param,function(data){})

3.$.post(url,param2,function(data){});    

4.$.post(url,param3,function(data){
        console.info(222);
    });    

5.$.ajax({  
        url: url,  
        data: data,  
        dataType: "json",  
        type: "POST",  
//        traditional: true,  //使用該屬性放置深度序列化
        success: function (responseJSON) {  
            console.info(333);
        }  
    });

6.$.ajax({  
        url: url,  
        data: data,  
        dataType: "json",  
        type: "POST",  
        traditional: true,  //使用該屬性放置深度序列化
        success: function (responseJSON) {  
            console.info(444);
        }  
    });

 

針對自定義的類,也能夠經過方式一jquery ajax傳遞給後臺

例如:

// 自定義Person類  
public class Person  
{  
    public string FirstName { get; set; }  
    public string LastName { get; set; }  
}
// 後臺Action  
public ActionResult SetCallBackStatus(List<Person> selectedIDs)  
{  
    string result = "ok";  
    string errMsg = "";  
  
    return this.JsonFormat(new { result = result, errMsg = errMsg });  
}

此時前臺js能夠這樣寫:

var _list = {};  
  
for (var i = 0; i < checkedRow.length; i++) {  
    _list["selectedIDs[" + i + "].FirstName"] = checkedRow[i].FirstName;  
    _list["selectedIDs[" + i + "].LastName"] = checkedRow[i].LastName;  
}  
  
$.ajax({  
    url: '@Url.Action("SetCallBackStatus")',  
    //data: { "selectedIDs": _list },  
    data: _list,  
    dataType: "json",  
    type: "POST",  
    //traditional: true,  
    success: function (responseJSON) {  
        // your logic  
        alert('Ok');  
    }  
});

 

jQuery ajax的traditional參數的做用

通常的,可能有些人在一個參數有多個值的狀況下,可能以某個字符分隔的形式傳遞,好比頁面上有多個checkbox:
$.ajax{
      url:"xxxx",
      data:{
            p: "123,456,789"
      }
}
而後後臺獲取參數後再分隔,這種作法有很大弊端,試問若是某一個參數值中出現了分隔符所使用的字符,會出現什麼狀況呢?固然後臺獲取的參數將與實際狀況不符.
這時我想到了將上述代碼寫成這樣:
$.ajax{
      url:"xxxx",
      data:{
            p: ["123", "456", "789"]
      }
}
若是單純寫成這樣,在java後臺是沒法取到參數的,由於jQuery須要調用jQuery.param序列化參數,
jQuery.param( obj, traditional )
默認的話,traditional爲false,即jquery會深度序列化參數對象,以適應如PHP和Ruby on Rails框架,
但servelt api沒法處理,咱們能夠經過設置traditional 爲true阻止深度序列化,而後序列化結果以下:
p: ["123", "456", "789"]    =>    p=123&p=456&p=456
隨即,咱們就能夠在後臺經過request.getParameterValues()來獲取參數的值數組了,
因此,好比咱們前臺有多個checkbox,前臺的代碼能夠寫成:
var values = $("input[type=checkbox]").map(function(){
      return $(this).val();
}).get();
$.ajax{
      url:"xxxx",
      traditional: true,
      data:{
            p: values 
      }
}

關於頁面向後臺傳遞數組,自動添加[]的問題也使用攔截器:

@Service("requestParamInterceptor")
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@SuppressWarnings("serial")
public class RequestParamInterceptor implements Interceptor {
 private static final Log log = LogFactory.getLog(RequestParamInterceptor.class);
  private static Pattern SCRIPT_PATTERN = Pattern
      .compile("<script.*>.*<\\/script\\s*>");
    private static Pattern HTML_PATTERN = Pattern.compile("<[^>]+>");
 
   private String uriEncoding=null;

    
 public String intercept(ActionInvocation invocation) throws Exception {
	//經過核心調度器invocation來得到調度的Action上下文
  final ActionContext context = invocation.getInvocationContext();
  HttpServletRequest request = (HttpServletRequest) context.get(ServletActionContext.HTTP_REQUEST);
  HttpServletResponse response = (HttpServletResponse) context.get(ServletActionContext.HTTP_RESPONSE);
  response.setCharacterEncoding(request.getCharacterEncoding());//TOMCAT WEB.XML設置的編碼方式
  response.setHeader("Pragma", "no-cache");
  response.setHeader("Cache-Control", "no-cache");
  response.setHeader("Cache-Control", "no-store");
  response.setDateHeader("Expires", 0);
  
  if(uriEncoding == null)
	  getUriEncoding();
  String method = request.getMethod();  
  Boolean isGet=false;
  if ("get".equalsIgnoreCase(method) && request.getCharacterEncoding() != null && !request.getCharacterEncoding().equals(uriEncoding))
	  isGet=true;
  //獲取Action上下文的值棧
  ValueStack stack = context.getValueStack();
  
  Map<?, ?> paramMap = request.getParameterMap();
    int flag = 0;
    String lowStr = null;
    Set<?> keSet = paramMap.entrySet();
    for (Iterator<?> itr = keSet.iterator(); itr.hasNext();) {
    
     try
     {
    @SuppressWarnings("rawtypes")
	Map.Entry me = (Map.Entry) itr.next();
     Object ok = me.getKey();
     if(ok.equals("_"))
    	 continue;
     Object ov = me.getValue();
     String[] value = new String[1];
     if (ov instanceof String[]) {
      value = (String[]) ov;
     } else {
    	value[0]=ov.toString();
     }
     
    //處理後的請求參數加入值棧中  處理有些數組名後自動加了[]的狀況
    stack.setValue(((String)ok).replace("[]", ""), (String[])value);
     }
     catch(Exception e)
     {
    	 
     }

    }
 
  return invocation.invoke();
 }
 
 
 public void destroy() {
 }
 public void init() {
	 
	 
 }
 public void getUriEncoding()
 {
	 String encoding=null;
	 Map<String, String> map = TomcatServer.getConnectorUriEncoding();
     for(Map.Entry<String, String> entry : map.entrySet()) {
        // System.out.println(entry.getKey() + " --> " + entry.getValue());
    	 encoding=entry.getValue();
    	 break;
     }
     
     try {
    	 if(VerifyString.isEmpty(encoding))
    		 encoding=SystemTool.getTomcatConfig("URIEncoding");
	} catch (IOException e) {
	}
     //System.out.println(uriEncoding);
     if(VerifyString.isEmpty(encoding))
     	 uriEncoding="ISO-8859-1";
     else
    	 uriEncoding=encoding;
}
 
}

在sturts2的xml中配置攔截器:

<interceptors>
	<interceptor name="illegalCharacter" class="requestParamInterceptor" />
	<interceptor name="authority" class="authorityInterceptor"></interceptor>
	<interceptor-stack name="hwhmdStack">
		<interceptor-ref name="illegalCharacter"></interceptor-ref>
		<interceptor-ref name="authority">
			<param name="indexAction">login</param>
			<param name="appCode">cost</param>
		</interceptor-ref>
		<interceptor-ref name="defaultStack" />
	</interceptor-stack>
</interceptors>
<default-interceptor-ref name="hwhmdStack" />

又例如:

java的Action:

private List<PersonnelObject> personnelObjects;
    
public List<PersonnelObject> getPersonnelObjects() {
	return personnelObjects;
}
public void setPersonnelObjects(List<PersonnelObject> personnelObjects) {
	this.personnelObjects = personnelObjects;
}

前臺:

錯誤寫法1.

//下面這麼寫後臺沒法獲取personnelObjects的值
var data = {};
var personnelList = new Array();
for(var i = 0;i<checkRows.length;i++){
	personnelList.push(checkRows[i]);
}
data["personnelObjects"] = personnelList;
$.post(funUrl,data,function(data){});

google請求參數:

錯誤寫法2:

//這麼寫會發現後臺personnelObjects也是爲null,接受不到值
var data = {};
for(var i = 0;i<checkRows.length;i++){
	personnelList.push(checkRows[i]);
	data["personnelObjects["+i+"]"] = checkRows[i];
}
$.post(funUrl,data,function(data){})

google請求參數爲:

可是若是這麼寫:

//這麼寫會發現後臺personnelObjects有值,集合中的每一個對象的ID有值
var data = {};
for(var i = 0;i<checkRows.length;i++){
	personnelList.push(checkRows[i]);
	data["personnelObjects["+i+"].id"] = i;//只傳遞數組中的每一個對象的ID值
}
$.post(funUrl,data,function(data){})

疑問:傳遞完整的每一個對象,後臺接受不到值;若是傳遞的是每一個對象的某個屬性,則會獲取到對應的值

進一步測試

//這麼寫會發現後臺personnelObjects有值,集合中的每一個對象的ID有值
var data = {};
for(var i = 0;i<checkRows.length;i++){
	personnelList.push(checkRows[i]);
	//data["personnelObjects["+i+"].id"] = i;//只傳遞數組中的每一個對象的ID值
    for (var key in checkRows[i]){
		if (!$.isArray(checkRows[i][key]) && !$.isFunction(checkRows[i][key])
						&& (typeof checkRows[i][key]) == "object")
		{
			continue;
		}
			data["personnelObjects["+i+"]."+key]=checkRows[i][key];
	}
}
$.post(funUrl,data,function(data){})

google瀏覽器的請求參數:

發現這種寫法,後臺也可以正常的獲取.

好像向後臺傳遞參數的時候,若是屬性在符號".id"能夠正常解析,可是[id]不可以解析.

接下來測試$.param:

var aa = $.param(data);//這個就是正常的jquery的參數序列化
var bb = $.param(data,true);

aa的參數序列化格式爲:

bb的參數格式爲:

可見:

$.param(data,true)的淺度序列化並無解析出object對象,因此在傳遞參數的時候並無可以真正的給後臺傳值.

$.param(data)就可以正確的解析出來

總結:

普通參數和基本類型數組可使用$.param(data,true);

若是要傳遞非基本類型數組,那麼就要循環數組中的每一個對象,利用"."來賦值參數屬性

相關文章
相關標籤/搜索