【问题标题】:How to specify default media type for endpoints in a Spring Boot service如何在 Spring Boot 服务中为端点指定默认媒体类型
【发布时间】:2019-03-22 05:41:48
【问题描述】:

我正在构建一个带有多个端点的 Spring Boot 服务。我的服务需要同时支持jsonxml 输出。大多数端点将仅是json,而一些端点将仅是xml。我可以使用注释@RequestMapping 指定特定端点接受或返回的内容类型。例如:

@RequestMapping(method = RequestMethod.POST,
                consumes = {MediaType.APPLICATION_XML_VALUE},
                produces = {MediaType.APPLICATION_XML_VALUE})

但是,由于我的应用程序的大多数端点仅是 json,我想避免编写

consumes = {MediaType.APPLICATION_JSON_VALUE},
produces = {MediaType.APPLICATION_JSON_VALUE}

在所有这些中。有没有办法让用@RequestMapping 注释的方法具有默认的consumesproduces 媒体类型?每当我需要不同于默认值的东西时,我都可以指定它。

我已尝试设置内容协商,但不适用于此。我认为我可以通过自定义ContentNegotiationStrategy 的内容协商来做到这一点,但我需要该代码才能读取该请求的处理程序的注释(用@RequestMapping 注释的特定方法)和代码只得到一个NativeWebRequest

是否有用于实现此目的的全局 Spring 配置?

编辑: 设置内容协商

@Configuration
@EnableWebMvc
class ContentNegotiationConfiguration extends WebMvcConfigurerAdapter {
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorParameter(false)
                  .favorPathExtension(true)
                  .ignoreAcceptHeader(true)
                  .ignoreUnknownPathExtensions(false)
                  .useJaf(false)
                  .defaultContentType(MediaType.APPLICATION_JSON);
    }
}

和端点

@RequestMapping(method = RequestMethod.GET)

然后调用端点

GET https://localhost:8080/endpoint.xml

返回 xml 输出和 HTTP 200 而不是 HTTP 406

【问题讨论】:

    标签: java spring spring-boot


    【解决方案1】:

    请使用此 Java 配置

    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(true).
        favorParameter(false).
        parameterName("mediaType").
        ignoreAcceptHeader(false).
        useJaf(false).
        defaultContentType(MediaType.APPLICATION_JSON).
        mediaType("xml", MediaType.APPLICATION_XML). 
        mediaType("json", MediaType.APPLICATION_JSON); 
    }
    

    【讨论】:

      【解决方案2】:

      这完全取决于您返回的内容类型。如果您这样定义内容协商:

      @Override
      public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
          configurer
                  .favorPathExtension(false)
                  .favorParameter(true)
                  .mediaType("json", MediaType.APPLICATION_JSON)
                  .mediaType("xml", MediaType.APPLICATION_XML);
      }
      

      然后你可以有一个处理不同内容类型的方法,例如:

      @RequestMapping(value = "/process/{json}", method = RequestMethod.GET)
      public ResponseEntity<?> process(@PathVariable("json") boolean processJson) {
          if (processJson) {
              final HttpHeaders headers = new HttpHeaders();
              headers.setContentType(MediaType.APPLICATION_JSON);
              return new ResponseEntity<>("someJSONObject", headers, HttpStatus.OK);
          } else {
              final HttpHeaders headers = new HttpHeaders();
              headers.setContentType(MediaType.APPLICATION_XML);
              return new ResponseEntity<>("someXMLObject", headers, HttpStatus.OK);   
          }
      }
      

      如果您需要将对象直接传递给响应以便正确序列化它们,您还需要使用消息转换器。例如:

      @Override
      public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
          converters.add(new MappingJackson2HttpMessageConverter(objectMapper));
          converters.add(new MappingJackson2XmlHttpMessageConverter(objectMapper));
      }
      

      【讨论】:

        【解决方案3】:

        将此 bean 添加到您的配置中:

        @EnableWebMvc
        @Configuration
        @ComponentScan
        public class MyWebConfig extends WebMvcConfigurerAdapter {
        
          @Override
          public void configureContentNegotiation (ContentNegotiationConfigurer configurer) {
              configurer.defaultContentType(MediaType.APPLICATION_JSON);
          }
        }
        

        【讨论】:

        • 这并不像你认为的那样。我将提供示例。
        【解决方案4】:

        看看 ContentNegotiationConfigurer,它可以让您指定整个应用程序的内容类型。看到这个问题:Spring boot controller content negotiation

        【讨论】:

        • 编辑不会改变最初的问题,它明确指出内容协商不会做我想要的:)。
        • 嘿,两个人独立地将您指向 ContentNegotiationConfigurer。我现在出去了。
        猜你喜欢
        • 2016-05-14
        • 2017-12-27
        • 2020-09-20
        • 1970-01-01
        • 1970-01-01
        • 2018-03-07
        • 1970-01-01
        • 2017-08-07
        • 2016-09-06
        相关资源
        最近更新 更多