我正在构建一个具有多个端点的 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
。
看一下 ContentNegotiationConfigurer,它允许您指定整个应用程序的内容类型。看这个问题:Spring boot控制器内容协商
将此 bean 添加到您的配置中:
@EnableWebMvc
@Configuration
@ComponentScan
public class MyWebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation (ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON);
}
}
这完全取决于您返回的内容类型。如果您这样定义内容协商:
@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));
}
请使用此 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);
}