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

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

我正在构建一个具有多个端点的 Spring Boot 服务。我的服务需要支持

json
xml
输出。大多数端点仅是
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
注释的方法具有默认的
consumes
produces
媒体类型?每当我需要与默认不同的东西时,我可以指定它。

我已尝试设置内容协商,但它不适用于此。我认为我也许可以通过与自定义

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
4个回答
0
投票

看一下 ContentNegotiationConfigurer,它允许您指定整个应用程序的内容类型。看这个问题:Spring boot控制器内容协商


0
投票

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

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

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

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

0
投票

请使用此 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); 
}
© www.soinside.com 2019 - 2024. All rights reserved.