无法将JSON作为请求主体发送到Spring Controller

时间:2016-02-20 09:42:16

标签: java json ajax spring spring-mvc

第1步: Ajax请求:

$.ajax({
  url: "url",
  type: "POST",
  dataType: 'json',
  data:{
    'id': '1',
    'type': 'BOOK_VIEWED',
    'access_token': response.response.access_token
  },
  crossDomain: true,
  success: function() { }
});

第2步。在执行Spring Controller方法之前从请求获取参数;这里有两个变种:

  • 变体1:如果我在标头中发送带content-type: json的ajax请求,则工作;否则它会:

    String token = request.getParameter(HEADER_SECURITY_TOKEN);
  • 变式2 :如果我在标题中设置content-type: json,则可以使用:

    StringBuilder sb = new StringBuilder();
    BufferedReader reader = request.getReader();
    String line;
    while ((line = reader.readLine()) != null)
        sb.append(line).append('\n');

第3步。应该执行Spring Controller bookOpened方法:

@RequestMapping(value = "/event",
                    method = RequestMethod.POST,
                        produces = MediaType.APPLICATION_JSON_VALUE)
public void bookOpened(@RequestBody PostEvent postEvent, HttpServletRequest request) {
    // ..
}

尝试运行时,不会执行bookOpened方法并抛出415(unsupported media type) Exception。如果方法签名更改为仅接受:HttpServletRequest request参数(不带@RequestBody参数),则它将起作用;但这不适合我。

主要问题:

  • 在第2步中,我想从请求中获取参数。
  • 在第3步中,我想要包含@RequestBody参数,而不仅仅是HttpServletRequest参数。

1 个答案:

答案 0 :(得分:0)

第3步

要强制您请求的邮件转换器进程,您必须指定它的内容类型。它必须是application/json。在data请求参数中,您必须发送String,而不是array。因此,您的请求可能如下所示:

var post = {};
post['id']=1;
post['type']='BOOK_VIEWED';
post['access_token']=response.response.access_token;

$.ajax({
       url: 'url',
       type: 'post',
       contentType : 'application/json',
       dataType:'json',
       data:JSON.stringify(post)
   })
   success: function() { ... }
})

此外,要将json消息转换器包含到项目中,您已声明了一些依赖项。如果您还没有这样做,请将此依赖项添加到pom

<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-core</artifactId>
   <version>2.4.1</version>
</dependency>
<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.4.1.1</version>
</dependency>

第2步

因为客户端只发送一次请求,所以您只需读取一次请求。因此,除非在request.getReader()实施中使用它,否则永远不要使用HttpMessageConverter。要从请求中获取值,您可以将其作为请求参数(查询)发送。在您的情况下,要向url添加参数,您需要手动编写url-string:

...

$.ajax({
       url: 'url?acces_token='+encodeURIComponent(response.response.access_token),
       type: 'post',
       contentType : 'application/json',
       dataType:'json',
       data:JSON.stringify(post)
   })
   success: function() { ... }
})

之后,您可以获得以您熟知的请求参数:

String token = URLDecoder.decode(request.getParameter('acces_token'), "utf-8");

不是,你在将它作为url参数传递之前有编码令牌,并在服务器端获得它时再次解码它。

希望,这会有所帮助。