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

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

HTML / JavaScript

 
$(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); } }); }); });

Java

 @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错误(不会生成exception)。 但是如果删除了@RequestBody注释(即参数签名只是FormDataObject formData ),那么将调用该方法并将JSON返回给JavaScript。

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

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

注意 :我使用的是Spring 3.1.4。

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

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

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

有4个默认的HttpMessageConverters:

  • ByteArrayHttpMessageConverter :转换字节数组。
  • StringHttpMessageConverter :转换字符串。
  • FormHttpMessageConverter :将表单数据转换为MultiValueMap或从MultiValueMap转换表单数据。
  • SourceHttpMessageConverter :转换为/从javax.xml.transform.Source转换。

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

 < bean class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" > < property name= "messageConverters" > < list> < ref bean= "mappingJacksonHttpMessageConverter" /> < ref bean= "stringHttpMessageConverter" />  < ref bean= "formHttpMessageConverter" />    

问题是,当我们使用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请求内容类型为application / x-www-form-urlencoded在Spring中不起作用