angularjs-$http.post请求传递参数,后台Controller接受不到原因

现象回显

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

 

posted @ 2016-11-21 09:42  qtyy  阅读(5301)  评论(0编辑  收藏  举报