Spring mvc: изменение формата ответа по умолчанию от xml до json
Я прошел через другие подобные вопросы, но ничего не работало для меня.
Все мои API возвращают JSON как ответ по умолчанию:
Из-за некоторого XML API мне пришлось добавить jackson-xml
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
Теперь по умолчанию " Без заголовка принятия" Все ответы XML.
Я хотел бы иметь JSON в качестве формата ответа по умолчанию.
Как указано в документе:
https://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc
Я реализовал следующую конфигурацию:
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false).favorParameter(true).parameterName("mediaType").ignoreAcceptHeader(true)
.useJaf(false).defaultContentType(MediaType.APPLICATION_JSON)
.mediaType("xml", MediaType.APPLICATION_XML).mediaType("json", MediaType.APPLICATION_JSON);
}
Случай 1:, если я создаю ignoreAcceptHeader(true)
, тогда все JSON даже XML API возвращает JSON.
Случай 2:, когда ignoreAcceptHeader(false)
, по умолчанию, является XML.
Я забыл упомянуть, что мой API выглядит так:
@RequestMapping(value = "/getXml", method = RequestMethod.GET)
public ResponseEntity<String> getXml( HttpServletRequest request)
throws JAXBException {
return returnXml();
}
Я совсем потерялся здесь. Все, что я хочу, это Default (Without AcceptHeader), должен быть JSON. (API возвращает XML как String)
И когда Accept Header: "Application/xml" определен, тогда ответ должен быть XML.
Любой совет будет очень полезен.
Спасибо.
Ответы
Ответ 1
В общем, если вы хотите получить ответ json, вам нужен модуль jackson-databind:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${json-jackson-version}</version>
</dependency>
а затем вы должны определить MappingJackson2HttpMessageConverter
в своей конфигурации:
@Configuration
@EnableWebMvc
public class WebAppMainConfiguration extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2HttpMessageConverter());
[..]
super.configureMessageConverters(converters);
}
[...]
}
В вашем случае вы можете реализовать свой собственный AbstractGenericHttpMessageConverter, чтобы вы могли включить этот конвертер между различными бетонными преобразователями в зависимости от типа носителя.
Проверьте метод AbstractGenericHttpMessageConverter#writeInternal(..)
Ответ 2
Поскольку вы установили ignoreAcceptHeader в true, а favourPathExtension в false, Spring будет полагаться на другие альтернативы для согласования содержимого. Значит будет выглядеть параметр URL, который вы настроили XML и JSON
так как @stan указал /getXml?mediaType=xml
будет возвращать ответ XML, иначе он будет по умолчанию json(defaultContentType(MediaType.APPLICATION_JSON))
Ответ 3
Для меня добавление
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON_UTF8);
}
}
решил проблему.
Теперь по умолчанию все RestController
возвращают JSON, если в запросе нет заголовка Accept
.
Также, если передается заголовок Accept: application/xml
, то результатом является XML.
Также стоит прочитать: https://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc