如何在Spring MVC中配置自定义MediaType?

时间:2014-11-28 09:20:49

标签: xml json spring spring-mvc content-negotiation

使用Spring MVC,我已经有了JSON和XML媒体格式的控制器。 在内容协商配置中,我只想依赖Accept头,并引入自定义名称媒体类型,例如:“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);
    }
}

我的控制器:

@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标头:application/json生成JSON,application/xml生成XML。其他任何东西都返回406 Not Acceptable,甚至myXml

我期待xml虽然......

1 个答案:

答案 0 :(得分:3)

使用该配置,您基本上是:

  • 使用参数或路径扩展忽略内容协商
  • 已注册" json - >应用/ JSON" " xml - >应用/ XML" " myXml - >应用/ XML"作为协商这些媒体类型的可能的路径扩展/参数。 (see more about this here
  • 告诉Spring MVC,每当HTTP客户端发送"Accept: */*"或根本没有Accept头时,默认的ContentType应为" application / xml"

我不认为您打算像这样处理内容协商。

您可能想要自定义HttpMessageConverters(see here),例如注册Jaxb2RootElementHttpMessageConverter(如果使用JAXB)或MappingJackson2XmlHttpMessageConverter(如果使用Jackson)并将其注册到&#34 ;应用/ XML"和" myXml"媒体类型。

另外,不要忘记添加" myXml"在"生产" RequestMapping注释的一部分 - 你的控制器方法应该将它声明为它可以产生的媒体类型,否则它将再次抛出406。

我的建议

你绝对应该使用" application / vnd.foobar.v.1.0 + xml"等媒体类型。因为:

  • 这是与http客户端相关的内容
  • xml中的HttpMessageConverters已经注册处理" application / xml"和" application / * + xml"。

在这种情况下,您可以在配置中保留defaultContentType部分(并可能将其设置为您的自定义媒体类型)并丢弃其余部分。

在任何情况下,您仍应在映射注释的produce部分声明此自定义媒体类型。