jQuery Spring @MVC 和带有 x-www-form-urlencoded 数据的 @RequestBody 注释?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16449141/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring @MVC and the @RequestBody annotation with x-www-form-urlencoded data?
提问by James Sumners
I am trying to figure out why I can't receive a request from a jQuery.ajax call when then Spring @Controller
handler method includes a @RequestBody
annotation. Consider the following:
我试图弄清楚为什么当 Spring@Controller
处理程序方法包含@RequestBody
注释时我无法从 jQuery.ajax 调用接收请求。考虑以下:
HTML/JavaScript:
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>
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);
}
The above will fail with the @RequestBody
annotation present and return a 415 error (no exception will be generated). But if the @RequestBody
annotation is removed (i.e. the parameter signature is just FormDataObject formData
) then the method will be called and JSON will be returned to the JavaScript.
以上将因@RequestBody
存在注释而失败并返回 415 错误(不会生成异常)。但是如果@RequestBody
注释被移除(即参数签名只是FormDataObject formData
),那么该方法将被调用并且 JSON 将返回给 JavaScript。
Why is this the case? A POST
request includes the data in the body of the request. Shouldn't the annotation process such a request?
为什么会这样?甲POST
请求包括在请求的主体中的数据。注释不应该处理这样的请求吗?
I realize that I could change the content type sent by the JavaScript to application/json
and the consumes
property to MediaType.APPLICATION_JSON_VALUE
to make the annotation work correctly. But why doesn't it work with a normal form request?
我意识到我可以更改 JavaScript 发送的内容类型 toapplication/json
和consumes
属性 toMediaType.APPLICATION_JSON_VALUE
以使注释正常工作。但是为什么它不适用于正常的表单请求?
Note: I am using Spring 3.1.4.
注意:我使用的是 Spring 3.1.4。
回答by Rossen Stoyanchev
Have you tried turning up logging on 'org.springframework.web' to find out the reason for the returned status code? There should be an exception raised and logged before it's translated to a 415.
您是否尝试过打开“org.springframework.web”登录以找出返回状态代码的原因?在将异常转换为 415 之前,应该引发并记录异常。
Also if sending form data, why not just leave out the @RequestBody. You'll then be use data binding (i.e. @ModelAttribute) that will apply Servlet request parameters to object fields. This is preferable to using the FormHttpMessageConverter.
此外,如果发送表单数据,为什么不忽略@RequestBody。然后,您将使用数据绑定(即@ModelAttribute)将 Servlet 请求参数应用于对象字段。这比使用 FormHttpMessageConverter 更可取。
回答by Qianyue
As the Spring Docs of @RequestBodysays, the request body would be converted to your object by HttpMessageConverter
.
正如@RequestBody的Spring Docs所说,请求正文将通过HttpMessageConverter
.
There are 4 default HttpMessageConverters:
有 4 个默认的 HttpMessageConverters:
- ByteArrayHttpMessageConverter: converts byte arrays.
- StringHttpMessageConverter: converts strings.
- FormHttpMessageConverter: converts form data to/from a MultiValueMap.
- SourceHttpMessageConverter: converts to/from a javax.xml.transform.Source.
- ByteArrayHttpMessageConverter: 转换字节数组。
- StringHttpMessageConverter:转换字符串。
- FormHttpMessageConverter:将表单数据与 MultiValueMap相互转换。
- SourceHttpMessageConverter:与 javax.xml.transform.Source相互转换。
To convert the url encoded form, which is ajax.serialize() create, it's the job of FormHttpMessageConverter
. Since you have a HttpMediaTypeNotSupportedException
exception, I guess that you didn't configure FormHttpMessageConverter
. Check your spring configuration file, here is an example :
要转换 url 编码形式,即 ajax.serialize() 创建,这是FormHttpMessageConverter
. 既然你有HttpMediaTypeNotSupportedException
例外,我猜你没有配置FormHttpMessageConverter
. 检查您的 spring 配置文件,这是一个示例:
< bean class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >
< property name= "messageConverters" >
< list>
< ref bean= "mappingHymansonHttpMessageConverter" />
< ref bean= "stringHttpMessageConverter" />
<!-- Do you have this converter ? -->
< ref bean= "formHttpMessageConverter" />
</ list>
</ property>
</ bean>
回答by Douglas Ribeiro
The problem is that when we use application/x-www-form-urlencoded, Spring doesn't understand it as a RequestBody. So, if we want to use this we must remove the @RequestBodyannotation.
问题是,当我们使用application/x-www-form-urlencoded 时,Spring 不会将其理解为 RequestBody。因此,如果我们想使用它,我们必须删除@RequestBody注释。
Then try the following:
然后尝试以下操作:
@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);
}
Note that removed the annotation @RequestBody
请注意,删除了注释@RequestBody
answer: Http Post request with content type application/x-www-form-urlencoded not working in Spring
答案:内容类型为 application/x-www-form-urlencoded 的 Http Post 请求在 Spring 中不起作用