10

我试图弄清楚为什么当 Spring@Controller处理程序方法包含@RequestBody注释时我无法接收来自 jQuery.ajax 调用的请求。考虑以下:

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/jsonconsumes属性以MediaType.APPLICATION_JSON_VALUE使注释正常工作。但是为什么它不适用于普通的表单请求?

注意:我使用的是 Spring 3.1.4。

4

3 回答 3

7

您是否尝试过登录“org.springframework.web”以找出返回状态码的原因?在将其转换为 415 之前,应该引发并记录一个异常。

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

于 2013-05-09T21:38:09.737 回答
6

正如@RequestBody 的Spring Docs所说,请求正文将通过HttpMessageConverter.

有 4 个默认的 HttpMessageConverters:

要转换 url 编码的形式,也就是 ajax.serialize() 创建,这是FormHttpMessageConverter. 既然你有一个HttpMediaTypeNotSupportedException例外,我猜你没有配置FormHttpMessageConverter. 检查您的弹簧配置文件,这是一个示例:

< 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>
于 2015-03-01T10:32:03.427 回答
-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

答案内容类型为 application/x-www-form-urlencoded 的 Http Post 请求在 Spring 中不起作用

于 2016-07-07T18:40:56.610 回答