Support Jackson based XML serialization and Jackson2ObjectMapperBuilder
This commit introduces support for Jackson based XML serialization, using the new MappingJackson2XmlHttpMessageConverter provided by Spring Framework 4.1. It is automatically activated when Jackson XML extension is detected on the classpath. Jackson2ObjectMapperBuilder is now used to create ObjectMapper and XmlMapper instances with the following customized properties: - MapperFeature.DEFAULT_VIEW_INCLUSION is disabled - DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES is disabled JodaModuleAutoConfiguration and Jsr310ModuleAutoConfiguration have been removed since their behaviors are now handled directly by the ObjectMapper builder. In addition to the existing @Bean of type ObjectMapper support, it is now possible to customize Jackson based serialization properties by declaring a @Bean of type Jackson2ObjectMapperBuilder. Fixes gh-1237 Fixes gh-1580 Fixes gh-1644
This commit is contained in:
committed by
Andy Wilkinson
parent
0773b89b75
commit
315213ea4e
@@ -20,6 +20,7 @@ import java.lang.reflect.Field;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
@@ -29,41 +30,33 @@ import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnJava;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnJava.JavaVersion;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.web.HttpMapperProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.MapperFeature;
|
||||
import com.fasterxml.jackson.databind.Module;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.datatype.joda.JodaModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JSR310Module;
|
||||
|
||||
/**
|
||||
* Auto configuration for Jackson. The following auto-configuration will get applied:
|
||||
* <ul>
|
||||
* <li>an {@link ObjectMapper} in case none is already configured.</li>
|
||||
* <li>the {@link JodaModule} registered if it's on the classpath.</li>
|
||||
* <li>the {@link JSR310Module} registered if it's on the classpath and the application is
|
||||
* running on Java 8 or better.</li>
|
||||
* <li>a {@link Jackson2ObjectMapperBuilder} in case none is already configured.</li>
|
||||
* <li>auto-registration for all {@link Module} beans with all {@link ObjectMapper} beans
|
||||
* (including the defaulted ones).</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Andy Wilkinson
|
||||
* @author Sebastien Deleuze
|
||||
* @author Marcel Overdijk
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@@ -88,10 +81,23 @@ public class JacksonAutoConfiguration {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(ObjectMapper.class)
|
||||
@EnableConfigurationProperties({ HttpMapperProperties.class, JacksonProperties.class })
|
||||
@ConditionalOnClass({ ObjectMapper.class, Jackson2ObjectMapperBuilder.class })
|
||||
static class JacksonObjectMapperAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
@ConditionalOnMissingBean(ObjectMapper.class)
|
||||
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
|
||||
return builder.createXmlMapper(false).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass({ ObjectMapper.class, Jackson2ObjectMapperBuilder.class })
|
||||
@EnableConfigurationProperties({ HttpMapperProperties.class, JacksonProperties.class })
|
||||
static class JacksonObjectMapperBuilderAutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
private HttpMapperProperties httpMapperProperties = new HttpMapperProperties();
|
||||
|
||||
@@ -99,29 +105,39 @@ public class JacksonAutoConfiguration {
|
||||
private JacksonProperties jacksonProperties = new JacksonProperties();
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
@ConditionalOnMissingBean
|
||||
public ObjectMapper jacksonObjectMapper() {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
@ConditionalOnMissingBean(Jackson2ObjectMapperBuilder.class)
|
||||
public Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder() {
|
||||
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
|
||||
|
||||
if (this.httpMapperProperties.isJsonSortKeys()) {
|
||||
objectMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS,
|
||||
true);
|
||||
builder.featuresToEnable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS);
|
||||
}
|
||||
|
||||
configureDeserializationFeatures(objectMapper);
|
||||
configureSerializationFeatures(objectMapper);
|
||||
configureMapperFeatures(objectMapper);
|
||||
configureParserFeatures(objectMapper);
|
||||
configureGeneratorFeatures(objectMapper);
|
||||
configureFeatures(builder, this.jacksonProperties.getDeserialization());
|
||||
configureFeatures(builder, this.jacksonProperties.getSerialization());
|
||||
configureFeatures(builder, this.jacksonProperties.getMapper());
|
||||
configureFeatures(builder, this.jacksonProperties.getParser());
|
||||
configureFeatures(builder, this.jacksonProperties.getGenerator());
|
||||
|
||||
configureDateFormat(objectMapper);
|
||||
configurePropertyNamingStrategy(objectMapper);
|
||||
configureDateFormat(builder);
|
||||
configurePropertyNamingStrategy(builder);
|
||||
|
||||
return objectMapper;
|
||||
return builder;
|
||||
}
|
||||
|
||||
private void configurePropertyNamingStrategy(ObjectMapper objectMapper) {
|
||||
private void configureFeatures(Jackson2ObjectMapperBuilder builder,
|
||||
Map<?, Boolean> features) {
|
||||
for (Entry<?, Boolean> entry : features.entrySet()) {
|
||||
if (entry.getValue() != null && entry.getValue()) {
|
||||
builder.featuresToEnable(entry.getKey());
|
||||
}
|
||||
else {
|
||||
builder.featuresToDisable(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void configurePropertyNamingStrategy(Jackson2ObjectMapperBuilder builder) {
|
||||
// We support a fully qualified class name extending Jackson's
|
||||
// PropertyNamingStrategy or a string value corresponding to the constant
|
||||
// names in PropertyNamingStrategy which hold default provided implementations
|
||||
@@ -130,9 +146,8 @@ public class JacksonAutoConfiguration {
|
||||
if (propertyNamingStrategy != null) {
|
||||
try {
|
||||
Class<?> clazz = ClassUtils.forName(propertyNamingStrategy, null);
|
||||
objectMapper
|
||||
.setPropertyNamingStrategy((PropertyNamingStrategy) BeanUtils
|
||||
.instantiateClass(clazz));
|
||||
builder.propertyNamingStrategy((PropertyNamingStrategy) BeanUtils
|
||||
.instantiateClass(clazz));
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
// Find the field (this way we automatically support new constants
|
||||
@@ -141,9 +156,8 @@ public class JacksonAutoConfiguration {
|
||||
propertyNamingStrategy, PropertyNamingStrategy.class);
|
||||
if (field != null) {
|
||||
try {
|
||||
objectMapper
|
||||
.setPropertyNamingStrategy((PropertyNamingStrategy) field
|
||||
.get(null));
|
||||
builder.propertyNamingStrategy((PropertyNamingStrategy) field
|
||||
.get(null));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
@@ -158,85 +172,21 @@ public class JacksonAutoConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
private void configureDateFormat(ObjectMapper objectMapper) {
|
||||
private void configureDateFormat(Jackson2ObjectMapperBuilder builder) {
|
||||
// We support a fully qualified class name extending DateFormat or a date
|
||||
// pattern string value
|
||||
String dateFormat = this.jacksonProperties.getDateFormat();
|
||||
if (dateFormat != null) {
|
||||
try {
|
||||
Class<?> clazz = ClassUtils.forName(dateFormat, null);
|
||||
objectMapper.setDateFormat((DateFormat) BeanUtils
|
||||
.instantiateClass(clazz));
|
||||
builder.dateFormat((DateFormat) BeanUtils.instantiateClass(clazz));
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
objectMapper.setDateFormat(new SimpleDateFormat(dateFormat));
|
||||
builder.dateFormat(new SimpleDateFormat(dateFormat));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void configureDeserializationFeatures(ObjectMapper objectMapper) {
|
||||
for (Entry<DeserializationFeature, Boolean> entry : this.jacksonProperties
|
||||
.getDeserialization().entrySet()) {
|
||||
objectMapper.configure(entry.getKey(), isFeatureEnabled(entry));
|
||||
}
|
||||
}
|
||||
|
||||
private void configureSerializationFeatures(ObjectMapper objectMapper) {
|
||||
for (Entry<SerializationFeature, Boolean> entry : this.jacksonProperties
|
||||
.getSerialization().entrySet()) {
|
||||
objectMapper.configure(entry.getKey(), isFeatureEnabled(entry));
|
||||
}
|
||||
}
|
||||
|
||||
private void configureMapperFeatures(ObjectMapper objectMapper) {
|
||||
for (Entry<MapperFeature, Boolean> entry : this.jacksonProperties.getMapper()
|
||||
.entrySet()) {
|
||||
objectMapper.configure(entry.getKey(), isFeatureEnabled(entry));
|
||||
}
|
||||
}
|
||||
|
||||
private void configureParserFeatures(ObjectMapper objectMapper) {
|
||||
for (Entry<JsonParser.Feature, Boolean> entry : this.jacksonProperties
|
||||
.getParser().entrySet()) {
|
||||
objectMapper.configure(entry.getKey(), isFeatureEnabled(entry));
|
||||
}
|
||||
}
|
||||
|
||||
private void configureGeneratorFeatures(ObjectMapper objectMapper) {
|
||||
for (Entry<JsonGenerator.Feature, Boolean> entry : this.jacksonProperties
|
||||
.getGenerator().entrySet()) {
|
||||
objectMapper.configure(entry.getKey(), isFeatureEnabled(entry));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isFeatureEnabled(Entry<?, Boolean> entry) {
|
||||
return entry.getValue() != null && entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(JodaModule.class)
|
||||
static class JodaModuleAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public JodaModule jacksonJodaModule() {
|
||||
return new JodaModule();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnJava(JavaVersion.EIGHT)
|
||||
@ConditionalOnClass(JSR310Module.class)
|
||||
static class Jsr310ModuleAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public JSR310Module jacksonJsr310Module() {
|
||||
return new JSR310Module();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,6 +25,7 @@ import java.util.List;
|
||||
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.AbstractXmlHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
|
||||
@@ -141,7 +142,8 @@ public class HttpMessageConverters implements Iterable<HttpMessageConverter<?>>
|
||||
for (Iterator<HttpMessageConverter<?>> iterator = converters.iterator(); iterator
|
||||
.hasNext();) {
|
||||
HttpMessageConverter<?> converter = iterator.next();
|
||||
if (converter instanceof AbstractXmlHttpMessageConverter) {
|
||||
if ((converter instanceof AbstractXmlHttpMessageConverter)
|
||||
|| (converter instanceof MappingJackson2XmlHttpMessageConverter)) {
|
||||
xml.add(converter);
|
||||
iterator.remove();
|
||||
}
|
||||
|
||||
@@ -29,9 +29,12 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.GsonHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/**
|
||||
@@ -42,6 +45,7 @@ import com.google.gson.Gson;
|
||||
* @author Piotr Maj
|
||||
* @author Oliver Gierke
|
||||
* @author David Liu
|
||||
* @author Sebastien Deleuze
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Configuration
|
||||
@@ -78,6 +82,27 @@ public class HttpMessageConvertersAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(XmlMapper.class)
|
||||
@ConditionalOnBean(Jackson2ObjectMapperBuilder.class)
|
||||
@EnableConfigurationProperties(HttpMapperProperties.class)
|
||||
protected static class XmlMappers {
|
||||
|
||||
@Autowired
|
||||
private HttpMapperProperties properties = new HttpMapperProperties();
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter(
|
||||
Jackson2ObjectMapperBuilder builder) {
|
||||
MappingJackson2XmlHttpMessageConverter converter = new MappingJackson2XmlHttpMessageConverter();
|
||||
converter.setObjectMapper(builder.createXmlMapper(true).build());
|
||||
converter.setPrettyPrint(this.properties.isJsonPrettyPrint());
|
||||
return converter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(Gson.class)
|
||||
@ConditionalOnBean(Gson.class)
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.springframework.boot.autoconfigure.jackson;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.LocalDateTime;
|
||||
@@ -33,6 +32,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
@@ -45,11 +45,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.datatype.joda.JodaModule;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -63,6 +60,7 @@ import static org.mockito.Mockito.verify;
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Oliver Gierke
|
||||
* @author Sebastien Deleuze
|
||||
* @author Andy Wilkinson
|
||||
* @author Marcel Overdijk
|
||||
*/
|
||||
@@ -86,9 +84,6 @@ public class JacksonAutoConfigurationTests {
|
||||
public void registersJodaModuleAutomatically() {
|
||||
this.context.register(JacksonAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
Map<String, Module> modules = this.context.getBeansOfType(Module.class);
|
||||
assertThat(modules.size(), greaterThanOrEqualTo(1)); // Depends on the JDK
|
||||
assertThat(modules.get("jacksonJodaModule"), is(instanceOf(JodaModule.class)));
|
||||
ObjectMapper objectMapper = this.context.getBean(ObjectMapper.class);
|
||||
assertThat(objectMapper.canSerialize(LocalDateTime.class), is(true));
|
||||
}
|
||||
@@ -339,6 +334,26 @@ public class JacksonAutoConfigurationTests {
|
||||
.isEnabled(JsonGenerator.Feature.AUTO_CLOSE_TARGET));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultObjectMapperBuilder() throws Exception {
|
||||
this.context.register(JacksonAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
Jackson2ObjectMapperBuilder builder = this.context
|
||||
.getBean(Jackson2ObjectMapperBuilder.class);
|
||||
ObjectMapper mapper = builder.build();
|
||||
assertTrue(MapperFeature.DEFAULT_VIEW_INCLUSION.enabledByDefault());
|
||||
assertFalse(mapper.getDeserializationConfig().isEnabled(
|
||||
MapperFeature.DEFAULT_VIEW_INCLUSION));
|
||||
assertTrue(MapperFeature.DEFAULT_VIEW_INCLUSION.enabledByDefault());
|
||||
assertFalse(mapper.getDeserializationConfig().isEnabled(
|
||||
MapperFeature.DEFAULT_VIEW_INCLUSION));
|
||||
assertFalse(mapper.getSerializationConfig().isEnabled(
|
||||
MapperFeature.DEFAULT_VIEW_INCLUSION));
|
||||
assertTrue(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES.enabledByDefault());
|
||||
assertFalse(mapper.getDeserializationConfig().isEnabled(
|
||||
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class ModulesConfig {
|
||||
|
||||
|
||||
@@ -25,7 +25,9 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.converter.json.GsonHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.gson.Gson;
|
||||
@@ -40,6 +42,7 @@ import static org.junit.Assert.assertTrue;
|
||||
* @author Oliver Gierke
|
||||
* @author David Liu
|
||||
* @author Andy Wilkinson
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class HttpMessageConvertersAutoConfigurationTests {
|
||||
|
||||
@@ -59,11 +62,13 @@ public class HttpMessageConvertersAutoConfigurationTests {
|
||||
assertTrue(this.context.getBeansOfType(ObjectMapper.class).isEmpty());
|
||||
assertTrue(this.context.getBeansOfType(MappingJackson2HttpMessageConverter.class)
|
||||
.isEmpty());
|
||||
assertTrue(this.context.getBeansOfType(
|
||||
MappingJackson2XmlHttpMessageConverter.class).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultJacksonConverter() throws Exception {
|
||||
this.context.register(JacksonConfig.class,
|
||||
this.context.register(JacksonObjectMapperConfig.class,
|
||||
HttpMessageConvertersAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
@@ -73,9 +78,25 @@ public class HttpMessageConvertersAutoConfigurationTests {
|
||||
assertConverterBeanRegisteredWithHttpMessageConverters(MappingJackson2HttpMessageConverter.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultJacksonConvertersWithBuilder() throws Exception {
|
||||
this.context.register(JacksonObjectMapperBuilderConfig.class,
|
||||
HttpMessageConvertersAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
assertConverterBeanExists(MappingJackson2HttpMessageConverter.class,
|
||||
"mappingJackson2HttpMessageConverter");
|
||||
assertConverterBeanExists(MappingJackson2XmlHttpMessageConverter.class,
|
||||
"mappingJackson2XmlHttpMessageConverter");
|
||||
|
||||
assertConverterBeanRegisteredWithHttpMessageConverters(MappingJackson2HttpMessageConverter.class);
|
||||
assertConverterBeanRegisteredWithHttpMessageConverters(MappingJackson2XmlHttpMessageConverter.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customJacksonConverter() throws Exception {
|
||||
this.context.register(JacksonConfig.class, JacksonConverterConfig.class,
|
||||
this.context.register(JacksonObjectMapperConfig.class,
|
||||
JacksonConverterConfig.class,
|
||||
HttpMessageConvertersAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
|
||||
@@ -128,13 +149,27 @@ public class HttpMessageConvertersAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class JacksonConfig {
|
||||
protected static class JacksonObjectMapperConfig {
|
||||
@Bean
|
||||
public ObjectMapper objectMapper() {
|
||||
return new ObjectMapper();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class JacksonObjectMapperBuilderConfig {
|
||||
|
||||
@Bean
|
||||
public ObjectMapper objectMapper() {
|
||||
return new ObjectMapper();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Jackson2ObjectMapperBuilder builder() {
|
||||
return new Jackson2ObjectMapperBuilder();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class JacksonConverterConfig {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,7 +30,7 @@ import org.springframework.http.converter.ResourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
@@ -63,7 +63,7 @@ public class HttpMessageConvertersTests {
|
||||
ResourceHttpMessageConverter.class, SourceHttpMessageConverter.class,
|
||||
AllEncompassingFormHttpMessageConverter.class,
|
||||
MappingJackson2HttpMessageConverter.class,
|
||||
Jaxb2RootElementHttpMessageConverter.class)));
|
||||
MappingJackson2XmlHttpMessageConverter.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -106,7 +106,7 @@ public class HttpMessageConvertersTests {
|
||||
List<HttpMessageConverter<?>> converters) {
|
||||
for (Iterator<HttpMessageConverter<?>> iterator = converters.iterator(); iterator
|
||||
.hasNext();) {
|
||||
if (iterator.next() instanceof Jaxb2RootElementHttpMessageConverter) {
|
||||
if (iterator.next() instanceof MappingJackson2XmlHttpMessageConverter) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user