Spring @MVC和带有x-www-form-urlencoded数据的@RequestBody注释?

时间:2013-05-08 19:56:38

标签: spring jquery spring-mvc

我试图找出为什么我不能从jQuery.ajax调用接收请求,然后Spring @Controller处理程序方法包含@RequestBody注释。请考虑以下事项:

HTML / JavaScript的

<form id="foo" action="/baz">
  <input name="bar">
</form>

<script>
  $(function() {
    var $fooForm = $('#foo');

    $fooForm.on('submit', function(evt) {
      evt.preventDefault();

      $.ajax({
        url: $fooForm.action,
        data: $fooForm.serialize(),
        dataType: 'json',
        type: 'POST',
        success: function(data) { console.log(data); }
      });
    });
  });
</script>

爪哇

@RequestMapping(
  value = "/baz",
  method = RequestMethod.POST,
  consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
  produces = MediatType.APPLICATION_JSON_VALUE
)
public @ResponseBody SearchResults[] jqueryPostHandler(
  @RequestBody FormDataObject formData)
{
  return this.searchService.find(formData);
}

以上将失败并显示@RequestBody注释并返回415错误(不会生成异常)。但是如果@RequestBody注释被删除(即参数签名只是FormDataObject formData),那么将调用该方法并将JSON返回给JavaScript。

为什么会这样? POST请求包括请求正文中的数据。注释过程不应该这样的请求吗?

我意识到我可以将JavaScript发送的内容类型更改为application/json,将consumes属性更改为MediaType.APPLICATION_JSON_VALUE,以使注释正常工作。但为什么它不适用于普通的表单请求?

注意:我使用的是Spring 3.1.4。

3 个答案:

答案 0 :(得分:7)

您是否尝试过登录'org.springframework.web'来查找返回状态代码的原因?在将其转换为415之前,应该引发异常并进行记录。

另外,如果发送表单数据,为什么不省略@RequestBody。然后,您将使用将Servlet请求参数应用于对象字段的数据绑定(即@ModelAttribute)。这比使用FormHttpMessageConverter更好。

答案 1 :(得分:6)

正如Spring Docs of @RequestBody所述,请求正文将由HttpMessageConverter转换为您的对象。

有4个默认的HttpMessageConverters:

要转换url编码的表单,即ajax.serialize()创建,它是FormHttpMessageConverter的工作。由于您有HttpMediaTypeNotSupportedException例外,我猜您没有配置FormHttpMessageConverter。检查你的spring配置文件,这是一个例子:

< bean class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >
   < property name= "messageConverters" >
         < list>
             < ref bean= "mappingJacksonHttpMessageConverter" />
             < ref bean= "stringHttpMessageConverter" /> 
             <!-- Do you have this converter ? -->
             < ref bean= "formHttpMessageConverter" />
         </ list>
    </ property>
</ bean>

答案 2 :(得分:-3)

问题在于,当我们使用 application / x-www-form-urlencoded 时,Spring并不将其理解为RequestBody。所以,如果我们想要使用它 我们必须删除 @RequestBody 注释。

然后尝试以下方法:

@RequestMapping(
        value = "/baz",
        method = RequestMethod.POST,
        consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
        produces = MediatType.APPLICATION_JSON_VALUE
)
public @ResponseBody SearchResults[] jqueryPostHandler(
        FormDataObject formData)
{
    return this.searchService.find(formData);
}

请注意,删除了注释 @RequestBody

回答Http Post request with content type application/x-www-form-urlencoded not working in Spring