使用 Spring MVC,我的 Controller 已经适用于 JSON 和 XML 媒体格式。 在内容协商配置中,我想只依赖 Accept header,并引入自定义名称媒体类型,例如:“myXml”
我的配置:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.favorPathExtension(false)
.favorParameter(false)
.ignoreAcceptHeader(false)
.useJaf(false)
.mediaType(MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_JSON)
.mediaType(MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_XML)
.mediaType("myXml", MediaType.APPLICATION_XML)
.defaultContentType(MediaType.APPLICATION_JSON);
}
}
我的 Controller :
@RequestMapping(value = "/manager/{id}",
method = RequestMethod.GET,
produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}
)
@ResponseBody public Manager managers(@PathVariable long id){
return repo.getManagerById(id);
}
效果很好,Accept header :application/json
生成 JSON,application/xml
生成 XML。任何其他内容都会返回 406 Not Acceptable,即使是 myXml
。
虽然我期待 xml...
最佳答案
有了那个配置,你基本上:
- 忽略了使用参数或路径扩展的内容协商
- 注册“json -> application/json”“xml -> application/xml”“myXml -> application/xml”作为可能的路径扩展/参数,用于协商这些媒体类型。 ( see more about this here )
- 告诉 Spring MVC,每当 HTTP 客户端发送
“Accept: */*”
或根本没有 Accept header 时,默认的 ContentType 应该是“application/xml”
我不认为你打算像这样处理内容协商。
您可能想要自定义 HttpMessageConverters ( see here ),例如注册 Jaxb2RootElementHttpMessageConverter
(如果使用 JAXB)或 MappingJackson2XmlHttpMessageConverter
(如果使用 Jackson)并将它们注册到“application/xml”和“myXml”媒体类型。
此外,不要忘记在 RequestMapping 注释的“produces”部分添加“myXml”——您的 Controller 方法应将其声明为它可以生成的媒体类型,否则它将再次抛出 406。
我的建议
你绝对应该使用像“application/vnd.foobar.v.1.0+xml”这样的媒体类型,因为:
- 这是与 http 客户端相关的内容
- Spring 中的 xml HttpMessageConverter 已经注册为处理“application/xml”和“application/*+xml”。
在那种情况下,您可以将 defaultContentType 部分保留在您的配置中(并可能将其设置为您的自定义媒体类型)并丢弃其余部分。
无论如何,您仍然应该在映射注释的生成部分中声明此自定义媒体类型。
关于xml - 如何在 Spring MVC 中配置自定义 MediaType?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27185375/