为了处理带@RequestBody
注释的参数并注入参数,Spring 使用RequestResponseBodyMethodProcessor
. 这样做的第一件事HandlerMethodArgumentResolver
是检查Content-Type
标题。如果缺少它,则默认为application/octet-stream
. 然后它获取已注册HttpMessageConverter
实例的列表。默认情况下,这些是
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
stringConverter.setWriteAcceptCharset(false);
messageConverters.add(new ByteArrayHttpMessageConverter()); // if your argument is a byte[]
messageConverters.add(stringConverter); // if your argument is a String
messageConverters.add(new ResourceHttpMessageConverter()); // if your argument is a Resource
messageConverters.add(new SourceHttpMessageConverter<Source>()); // if your argument is one of the javax.xml Source classes
messageConverters.add(new AllEncompassingFormHttpMessageConverter()); // for application/x-www-form-urlencoded content-type
if (romePresent) {
messageConverters.add(new AtomFeedHttpMessageConverter()); // for application/atom+xml content-type
messageConverters.add(new RssChannelHttpMessageConverter()); // for application/rss+xml content-type
}
if (jaxb2Present) {
messageConverters.add(new Jaxb2RootElementHttpMessageConverter()); // if your argument class is annotated with @XmlRootElement or @XmlType
}
if (jackson2Present) {
messageConverters.add(new MappingJackson2HttpMessageConverter()); // for content-type application/json and application/*+json (wildcard json)
}
else if (jacksonPresent) {
messageConverters.add(new MappingJacksonHttpMessageConverter()); // in case, but rarely, same as above
}
然后RequestResponseBodyMethodProcessor
按顺序遍历此列表,并调用canRead()
每个HttpMessageConverter
. 如果它返回true
,则RequestResponseBodyMethodProcessor
使用它HttpMessageConverter
来创建参数。如果它永远找不到,它会抛出HttpMediaTypeNotSupportedException
一个DispatcherServlet
415 响应。
使用上述默认值,这是不可能的。您必须创建并注册自己的HttpMessageConverter
可以做到这一点。请注意,它将适用于所有带有@RequestBody
注释参数的处理程序方法。
作为建议,Content-Type
标头专门用于此场景,您应该使用它。