如何在Spring Boot服务中为端点指定默认媒体类型

时间:2018-10-17 13:55:50

标签: java spring spring-boot

我正在构建具有多个端点的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进行内容协商来做到这一点,但我需要该代码才能读取该请求的处理程序注释(用{{1}注释的特定方法}),而代码仅获得@RequestMapping

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

编辑: 使用

设置内容协商
NativeWebRequest

和端点

@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 的输出和HTTP xml而不是HTTP 200

4 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

@EnableWebMvc
@Configuration
@ComponentScan
public class MyWebConfig extends WebMvcConfigurerAdapter {

  @Override
  public void configureContentNegotiation (ContentNegotiationConfigurer configurer) {
      configurer.defaultContentType(MediaType.APPLICATION_JSON);
  }
}

答案 2 :(得分:0)

请使用此Java配置

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

答案 3 :(得分:0)

这与返回的内容类型有关。如果您这样定义内容协商:

@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));
}