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

问题描述 投票:0回答:2

使用 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);
}

它工作得很好,接受头:

application/json
生成JSON,
application/xml
生成XML。其他任何情况都会返回 406 Not Acceptable,甚至
myXml

不过我期望的是 xml...

xml json spring spring-mvc content-negotiation
2个回答
3
投票

通过该配置,您基本上:

  • 使用参数或路径扩展忽略内容协商
  • 注册了“json -> application/json”“xml -> application/xml”“myXml -> application/xml”作为可能的路径扩展/参数来协商这些媒体类型。 (在这里查看更多相关信息
  • 告诉Spring MVC,每当HTTP客户端发送
    "Accept: */*"
    或根本不发送Accept标头时,默认的ContentType应该是“application/xml”

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

您可能想要自定义 HttpMessageConverters(参见此处),例如注册

Jaxb2RootElementHttpMessageConverter
(如果使用 JAXB)或
MappingJackson2XmlHttpMessageConverter
(如果使用 Jackson)并将它们注册到“application/xml”和“myXml”媒体类型。

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

我的建议

您绝对应该使用像“application/vnd.foobar.v.1.0+xml”这样的媒体类型,因为:

  • 这与 http 客户端相关
  • Spring 中的 xml HttpMessageConverters 已经注册来处理“application/xml”和“application/*+xml”。

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

无论如何,您仍然应该在映射注释的 Produce 部分中声明此自定义媒体类型。


0
投票

对于 2.x 和 3.x 版本,如果有人想要为特定文件扩展名指定响应类型,则可以使用

WebServerFactoryCustomizer
来完成此操作。这样可以自定义
TomcatServletWebServerFactory
映射以包含所需的文件扩展名和相应的内容类型。

示例代码-

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.MimeMappings;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class MimeMappingCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        MimeMappings mm = factory.getMimeMappings();
        mm.add("mjs", "application/javascript");

        factory.setMimeMappings(mm);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.