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的工作。 由于您有HttpMediaTypeNotSupportedException
exception,我猜您没有配置FormHttpMessageConverter
。 检查你的spring配置文件,这是一个例子:
< bean class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" > < property name= "messageConverters" > < list> < ref bean= "mappingJacksonHttpMessageConverter" /> < ref bean= "stringHttpMessageConverter" /> < ref bean= "formHttpMessageConverter" /> list> property> bean>
问题是,当我们使用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中不起作用