現象回顯
js文件
app.controller('indexCtrl', function($scope, $state, $http) { $scope.login = function() { $http.post('authc/login', $scope.user). success(function(data) { $state.go('dashboard'); }). error(function(err) { $scope.authError = err; }); }; });
controller文件
@RequestMapping(value = "/login", method = RequestMethod.POST) public AccountPresenter login( @RequestParam(value = "account", required = true) String account, @RequestParam(value = "password", required = true) String password ) throws ApplicationRuntimeException { CxUserTable user = new CxUserTable(); try { user = loginService.login(account, password, false, false, 1); } catch (ApplicationRuntimeException e) { throw new ApplicationRuntimeException(e.getMessage()); } return user != null ? new AccountPresenter(user) : null; }
結果:
后台報錯
08:32:36 [http-bio-8080-exec-10] ERROR c.c.c.u.s.ControllerExceptionHanler - 系統異常!
警告: Handler execution resulted in exception: Required String parameter 'account' is not present
分析:
原因是后台沒有接收到account 參數。
jquery angularjs 請求頭信息對比:
默認情況下,jQuery傳輸數據使用Content-Type: x-www-form-urlencodedand和類似於"foo=bar&baz=moe"的序列,
然而AngularJS,傳輸數據使用Content-Type: application/json和{ "foo": "bar", "baz": "moe" }這樣的json序列。
AngularJS帶有一些默認的請求頭,Angular發出的所有請求上都會帶有這些默認的請求頭信息。默認請求頭包括以下兩個:
1.Accept:appliction/json,text/pain,/
2.X-Requested-With: XMLHttpRequest
請求頭信息分析:
A) GET、POST方式提時, 根據request header Content-Type的值來判斷:
application/x-www-form-urlencoded, 可選(即非必須,因為這種情況的數據@RequestParam, @ModelAttribute也可以處理,當然@RequestBody也能處理);
multipart/form-data, 不能處理(即使用@RequestBody不能處理這種格式的數據);
其他格式, 必須(其他格式包括application/json, application/xml等。這些格式的數據,必須使用@RequestBody來處理);
B) PUT方式提交時,根據request header Content-Type的值來判斷:
application/x-www-form-urlencoded, 必須;
multipart/form-data, 不能處理;
其他格式,必須;
說明:request的body部分的數據編碼格式由header部分的Content-Type指定;
AngularJS 轉換請求和響應
對於所有通過$http服務發出的請求和收到的響應來說,AngularJS都會進行一些基本的轉換,包括如下內容。
1.轉換請求
如果請求的配置對象屬性中包含JS對象,那么就把這個對象序列化成JSON格式。
2.轉換響應
如果檢測到了XSRF(Cross Site Request Forgery的縮寫,意為跨站請求偽造,這是跨站腳本攻擊的一種方式)前綴,則直接丟棄。如果檢測到了JSON響應,則使用JSON解析器對它進行反序列化。
如果你不需要其中的某些轉換,或者想自已進行轉換,可以在配置項里面傳入自已的函數。這些函數會獲取HTTP的request/response體以及協議頭信息,然后輸出序列化、修改之后的版本。可以使用transformLRequest和transformResponse作為key來配置這些轉換函數,而這兩個函數在模塊的config函數中是用$httpProvider服務來配置的。
我們什么時候需要使用這些東西呢?假設我們有一個服務,它更適合用jQuery的方式來操作。POST數據使用key1=val1&key2=val2(也就是字符串)形式來代替{key1:val1, key2:val2}JSON格式。我們可以在每個請求中來進行這種轉換,也可以添加一個獨立transformRequest調用,對於當前這個例子來說,我們打算添加一個通用的transformRequest,這樣所有發出的請求都會進行這種從JSON到字符串的轉換。下面就是實現方式:
module.config(function($httpProvider) { $httpProvider.defaults.transformRequest = function(data) { //使用jQuery的param方法把JSON數據轉換成字符串形式 return $.param(data); }; });
解決方法:
第一種(推薦):
所以下把Content-Type設置成x-www-form-urlencodedand之后,還需要轉換序列的格式,添加postCfg屬性。
(此方法前提要引入jquery文件)
$scope.login = function() { var postCfg = { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, transformRequest: function (data) { return $.param(data); } }; $http.post('authc/login', $scope.user, postCfg). success(function(data) { $state.go('dashboard'); }). error(function(err) { $scope.authError = err; }); };
第二種:
添加@ResponseBody 注解。通過body的形式解析json數據。
作用:
i) 該注解用於讀取Request請求的body部分數據,使用系統默認配置的HttpMessageConverter進行解析,然后把相應的數據綁定到要返回的對象上;
ii) 再把HttpMessageConverter返回的對象數據綁定到 controller中方法的參數上。
參考:
http://blog.csdn.net/yy374864125/article/details/41113643
http://www.cfei.net/archives/24102