在使用 jersey restful 時 前端ajax post 數據到 服務器端,接收對象爲null,測試代碼javascript
web:前端
var ts = []; //模擬兩條數據 for (var i = 0; i < 2; i++) { ts.push({name:'name'+i,id:i}); } var testData = {aa:ts}; printLog('log',testData); $.rate.post({ url: hostUrl + '/xxx/xxx/xxxx/queryDepartmentsAll', data:testData, cache: false, objRest:false, success: function(data) { console.log(data); } });
post data:java
--- log --- {"aa":[{"name":"name0","id":0},{"name":"name1","id":1}]}
server:jquery
/** * 查詢全部科室 * @return * @throws Exception */ @POST @Path("/queryDepartmentsAll") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public String queryDepartmentsAllTest(@Form(prefix="aa")List<TestBean> beans) throws Exception { loggin.info(beans); return "test..."; }
TestBean:web
@XmlRootElement public class TestBean { @FormParam("name") private String name; @FormParam("id") private Integer id; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } }
有請 "debug " 出場.......ajax
ajax發出請求後 會通過 HttpServletInputMessage 處理,獲取表單帶的參數後端
調用getDecodedFormParameters,會把 url中的參數和表單參數合併,放入MultivaluedMapImpl 對象中數組
MultivaluedMapImpl點toString - --> {aa[1][id]=[1], aa[0][name]=[name0], aa[0][id]=[0], aa[1][name]=[name1]}服務器
往下走,到了ListFormInjectorrestful
form 注入器有兩種,List,Map
最終走到了PrefixedMultivaluedMap 類
對象注入的方式是經過「變量[0].屬性」 注入的,而前段傳進的值是
解決辦法:
把花括號改爲「 .」 就能夠注入了
修改後:
aa[0].id=0 aa[0].name=name0 aa[1].id=1 aa[1].name=name1
後端接收到了
====================================================================
jquery ajax data 若是對象中包涵數組,是使用 jQuery.param 函數格式化,因此致使 傳輸的數據格式不正確
jQuery.param = function( a, traditional ) { var prefix, s = [], add = function( key, value ) { // If value is a function, invoke it and return its value value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); }; // Set traditional to true for jQuery <= 1.3.2 behavior. if ( traditional === undefined ) { traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; } // If an array was passed in, assume that it is an array of form elements. if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { // Serialize the form elements jQuery.each( a, function() { add( this.name, this.value ); }); } else { // If traditional, encode the "old" way (the way 1.3.2 or older // did it), otherwise encode params recursively. for ( prefix in a ) { buildParams( prefix, a[ prefix ], traditional, add ); } } // Return the resulting serialization return s.join( "&" ).replace( r20, "+" ); };
能夠在請求前把data類型先處理,demo js
var datas = {}; for (var a in settings.data) { if ($.isArray(settings.data[a])) { var isObject = $.isPlainObject(settings.data[a][0]); //若是數組裏是對象 if (isObject) { for (var i = 0, ds = settings.data[a], len = ds.length; i < len; ++i) { for (var b in ds[i]) { datas[a + '[' + i + '].' + b] = ds[i][b]; } } } } else {// datas[a] = settings.data[a]; } }