假设Spring MVC控制器中的JSON内容类型

时间:2013-10-10 15:32:13

标签: spring-mvc

我有一个与此类似的Spring 3.1 Controller方法

@RequestMapping(method = RequestMethod.POST)
public void (@RequestBody SomeObject obj) {
    // Do something
}

正确设置spring配置文件以接受JSON。如果我发送一个内容类型设置为“application / json”的请求并使用JSON发送正确的正文,那么一切都按照预期进行。

如果我没有将Content Type指定为“application / json”,则返回HTTP 415,这也是基于配置所期望的。反正有没有告诉Spring总是将RequestBody视为JSON而不管内容类型如何?

1 个答案:

答案 0 :(得分:1)

要处理@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标头专门用于此场景,您应该使用它。