diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java
new file mode 100644
index 0000000000..19582f4171
--- /dev/null
+++ b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBean.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright 2002-2012 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.http.converter.json;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.springframework.beans.FatalBeanException;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.util.Assert;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.AnnotationIntrospector;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.MapperFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+/**
+ * A FactoryBean for creating a Jackson {@link ObjectMapper} with setters to
+ * enable or disable Jackson features from within XML configuration.
+ *
+ *
Example usage with
+ * {@link org.springframework.http.converter.json.MappingJackson2HttpMessageConverter}:
+ *
+ *
+ * <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
+ * <property name="objectMapper">
+ * <bean class="org.springframework.web.context.support.Jackson2ObjectMapperFactoryBean"
+ * p:autoDetectFields="false"
+ * p:autoDetectGettersSetters="false"
+ * p:annotationIntrospector-ref="jaxbAnnotationIntrospector" />
+ * </property>
+ * </bean>
+ *
+ *
+ * Example usage with {@link org.springframework.web.servlet.view.json.MappingJackson2JsonView}:
+ *
+ *
+ * <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
+ * <property name="objectMapper">
+ * <bean class="org.springframework.web.context.support.Jackson2ObjectMapperFactoryBean"
+ * p:failOnEmptyBeans="false"
+ * p:indentOutput="true">
+ * <property name="serializers">
+ * <array>
+ * <bean class="org.mycompany.MyCustomSerializer" />
+ * </array>
+ * </property>
+ * </bean>
+ * </property>
+ * </bean>
+ *
+ *
+ * In case there are no specific setters provided (for some rarely used
+ * options), you can still use the more general methods
+ * {@link #setFeaturesToEnable(Object[])} and {@link #setFeaturesToDisable(Object[])}.
+ *
+ *
+ * <bean class="org.springframework.web.context.support.Jackson2ObjectMapperFactoryBean">
+ * <property name="featuresToEnable">
+ * <array>
+ * <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature$WRAP_ROOT_VALUE"/>
+ * <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature$CLOSE_CLOSEABLE"/>
+ * </array>
+ * </property>
+ * <property name="featuresToDisable">
+ * <array>
+ * <util:constant static-field="com.fasterxml.jackson.databind.MapperFeature$USE_ANNOTATIONS"/>
+ * </array>
+ * </property>
+ * </bean>
+ *
+ *
+ * Note: This BeanFctory is singleton, so if you need more than one you'll need
+ * to configure multiple instances.
+ *
+ * @author Dmitry Katsubo
+ * @author Rossen Stoyanchev
+ *
+ * @since 3.2
+ */
+public class Jackson2ObjectMapperFactoryBean implements FactoryBean, InitializingBean {
+
+ private ObjectMapper objectMapper;
+
+ private Map features = new HashMap();
+
+ private DateFormat dateFormat;
+
+ private AnnotationIntrospector annotationIntrospector;
+
+ private final Map, JsonSerializer>> serializers = new LinkedHashMap, JsonSerializer>>();
+
+ private final Map, JsonDeserializer>> deserializers = new LinkedHashMap, JsonDeserializer>>();
+
+
+ /**
+ * Set the ObjectMapper instance to use. If not set, the ObjectMapper will
+ * be created using its default constructor.
+ */
+ public void setObjectMapper(ObjectMapper objectMapper) {
+ this.objectMapper = objectMapper;
+ }
+
+ /**
+ * Define the format for date/time with the given {@link DateFormat}.
+ * @see #setSimpleDateFormat(String)
+ */
+ public void setDateFormat(DateFormat dateFormat) {
+ this.dateFormat = dateFormat;
+ }
+
+ /**
+ * Define the date/time format with a {@link SimpleDateFormat}.
+ * @see #setDateFormat(DateFormat)
+ */
+ public void setSimpleDateFormat(String format) {
+ this.dateFormat = new SimpleDateFormat(format);
+ }
+
+ /**
+ * Set the {@link AnnotationIntrospector} for both serialization and
+ * deserialization.
+ */
+ public void setAnnotationIntrospector(AnnotationIntrospector annotationIntrospector) {
+ this.annotationIntrospector = annotationIntrospector;
+ }
+
+ /**
+ * Configure custom serializers. Each serializer is registered for the type
+ * returned by {@link JsonSerializer#handledType()}, which must not be
+ * {@code null}.
+ * @see #setSerializersByType(Map)
+ */
+ public void setSerializers(JsonSerializer>... serializers) {
+ if (serializers != null) {
+ for (JsonSerializer> serializer : serializers) {
+ Class> handledType = serializer.handledType();
+ Assert.isTrue(handledType != null && handledType != Object.class,
+ "Unknown handled type in " + serializer.getClass().getName());
+ this.serializers.put(serializer.handledType(), serializer);
+ }
+ }
+ }
+
+ /**
+ * Configure custom serializers for the given types.
+ * @see #setSerializers(JsonSerializer...)
+ */
+ public void setSerializersByType(Map, JsonSerializer>> serializers) {
+ if (serializers != null) {
+ this.serializers.putAll(serializers);
+ }
+ }
+
+ /**
+ * Configure custom deserializers for the given types.
+ */
+ public void setDeserializersByType(Map, JsonDeserializer>> deserializers) {
+ if (deserializers != null) {
+ this.deserializers.putAll(deserializers);
+ }
+ }
+
+ /**
+ * Shortcut for {@link MapperFeature#AUTO_DETECT_FIELDS} option.
+ */
+ public void setAutoDetectFields(boolean autoDetectFields) {
+ this.features.put(MapperFeature.AUTO_DETECT_FIELDS, autoDetectFields);
+ }
+
+ /**
+ * Shortcut for {@link MapperFeature#AUTO_DETECT_SETTERS}/
+ * {@link MapperFeature#AUTO_DETECT_GETTERS} option.
+ */
+ public void setAutoDetectGettersSetters(boolean autoDetectGettersSetters) {
+ this.features.put(MapperFeature.AUTO_DETECT_SETTERS, autoDetectGettersSetters);
+ this.features.put(MapperFeature.AUTO_DETECT_GETTERS, autoDetectGettersSetters);
+ }
+
+ /**
+ * Shortcut for {@link SerializationFeature#FAIL_ON_EMPTY_BEANS} option.
+ */
+ public void setFailOnEmptyBeans(boolean failOnEmptyBeans) {
+ this.features.put(SerializationFeature.FAIL_ON_EMPTY_BEANS, failOnEmptyBeans);
+ }
+
+ /**
+ * Shortcut for {@link SerializationFeature#INDENT_OUTPUT} option.
+ */
+ public void setIndentOutput(boolean indentOutput) {
+ this.features.put(SerializationFeature.INDENT_OUTPUT, indentOutput);
+ }
+
+ /**
+ * Specify features to enable.
+ *
+ * @see MapperFeature
+ * @see SerializationFeature
+ * @see DeserializationFeature
+ * @see JsonParser.Feature
+ * @see JsonGenerator.Feature
+ */
+ public void setFeaturesToEnable(Object... featuresToEnable) {
+ if (featuresToEnable != null) {
+ for (Object feature : featuresToEnable) {
+ this.features.put(feature, Boolean.TRUE);
+ }
+ }
+ }
+
+ /**
+ * Specify features to disable.
+ *
+ * @see MapperFeature
+ * @see SerializationFeature
+ * @see DeserializationFeature
+ * @see JsonParser.Feature
+ * @see JsonGenerator.Feature
+ */
+ public void setFeaturesToDisable(Object... featuresToDisable) {
+ if (featuresToDisable != null) {
+ for (Object feature : featuresToDisable) {
+ this.features.put(feature, Boolean.FALSE);
+ }
+ }
+ }
+
+ public void afterPropertiesSet() throws FatalBeanException {
+ if (this.objectMapper == null) {
+ this.objectMapper = new ObjectMapper();
+ }
+
+ if (this.dateFormat != null) {
+ this.objectMapper.setDateFormat(this.dateFormat);
+ }
+
+ if (this.serializers != null || this.deserializers != null) {
+ SimpleModule module = new SimpleModule();
+ addSerializers(module);
+ addDeserializers(module);
+ this.objectMapper.registerModule(module);
+ }
+
+ if (this.annotationIntrospector != null) {
+ this.objectMapper.setAnnotationIntrospector(this.annotationIntrospector);
+ }
+
+ for (Object feature : this.features.keySet()) {
+ configureFeature(feature, this.features.get(feature));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void addSerializers(SimpleModule module) {
+ for (Class> type : this.serializers.keySet()) {
+ module.addSerializer((Class extends T>) type, (JsonSerializer) this.serializers.get(type));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void addDeserializers(SimpleModule module) {
+ for (Class> type : this.deserializers.keySet()) {
+ module.addDeserializer((Class) type, (JsonDeserializer extends T>) this.deserializers.get(type));
+ }
+ }
+
+ private void configureFeature(Object feature, boolean enabled) {
+ if (feature instanceof MapperFeature) {
+ this.objectMapper.configure((MapperFeature) feature, enabled);
+ }
+ else if (feature instanceof DeserializationFeature) {
+ this.objectMapper.configure((DeserializationFeature) feature, enabled);
+ }
+ else if (feature instanceof SerializationFeature) {
+ this.objectMapper.configure((SerializationFeature) feature, enabled);
+ }
+ else if (feature instanceof JsonParser.Feature) {
+ this.objectMapper.configure((JsonParser.Feature) feature, enabled);
+ }
+ else if (feature instanceof JsonGenerator.Feature) {
+ this.objectMapper.configure((JsonGenerator.Feature) feature, enabled);
+ }
+ else {
+ throw new FatalBeanException("Unknown feature class " + feature.getClass().getName());
+ }
+ }
+
+ /**
+ * Return the singleton ObjectMapper.
+ */
+ public ObjectMapper getObject() {
+ return this.objectMapper;
+ }
+
+ public Class> getObjectType() {
+ return ObjectMapper.class;
+ }
+
+ public boolean isSingleton() {
+ return true;
+ }
+
+}
diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/JacksonObjectMapperFactoryBean.java b/spring-web/src/main/java/org/springframework/http/converter/json/JacksonObjectMapperFactoryBean.java
index 765e174255..db8a459a6a 100644
--- a/spring-web/src/main/java/org/springframework/http/converter/json/JacksonObjectMapperFactoryBean.java
+++ b/spring-web/src/main/java/org/springframework/http/converter/json/JacksonObjectMapperFactoryBean.java
@@ -35,7 +35,7 @@ import org.springframework.beans.factory.InitializingBean;
* A FactoryBean for creating a Jackson {@link ObjectMapper} with setters to
* enable or disable Jackson features from within XML configuration.
*
- * Example usage with MappingJacksonHttpMessageConverter:
+ * Example usage with MappingJacksonHttpMessageConverter:
*
* <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
* <property name="objectMapper">
@@ -47,7 +47,7 @@ import org.springframework.beans.factory.InitializingBean;
* </bean>
*
*
- * Example usage with MappingJacksonJsonView:
+ * Example usage with MappingJacksonJsonView:
*
* <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
* <property name="objectMapper">
@@ -89,10 +89,10 @@ public class JacksonObjectMapperFactoryBean implements FactoryBean
private Map features = new HashMap();
- private AnnotationIntrospector annotationIntrospector;
-
private DateFormat dateFormat;
+ private AnnotationIntrospector annotationIntrospector;
+
/**
* Set the ObjectMapper instance to use.
@@ -103,16 +103,15 @@ public class JacksonObjectMapperFactoryBean implements FactoryBean
}
/**
- * Define annotationIntrospector for
- * {@link SerializationConfig#setAnnotationIntrospector(AnnotationIntrospector)}.
+ * Define the format for date/time with the given {@link DateFormat}.
+ * @see #setSimpleDateFormat(String)
*/
- public void setAnnotationIntrospector(AnnotationIntrospector annotationIntrospector) {
- this.annotationIntrospector = annotationIntrospector;
+ public void setDateFormat(DateFormat dateFormat) {
+ this.dateFormat = dateFormat;
}
/**
- * Define the date/time format with the given string, which is in turn used
- * to create a {@link SimpleDateFormat}.
+ * Define the date/time format with a {@link SimpleDateFormat}.
* @see #setDateFormat(DateFormat)
*/
public void setSimpleDateFormat(String format) {
@@ -120,11 +119,12 @@ public class JacksonObjectMapperFactoryBean implements FactoryBean
}
/**
- * Define the format for date/time with the given {@link DateFormat} instance.
- * @see #setSimpleDateFormat(String)
+ * Set the {@link AnnotationIntrospector} for serialization and deserialization.
+ * @see SerializationConfig#setAnnotationIntrospector(AnnotationIntrospector)
+ * @see DeserializationConfig#setAnnotationIntrospector(AnnotationIntrospector)
*/
- public void setDateFormat(DateFormat dateFormat) {
- this.dateFormat = dateFormat;
+ public void setAnnotationIntrospector(AnnotationIntrospector annotationIntrospector) {
+ this.annotationIntrospector = annotationIntrospector;
}
/**
@@ -161,6 +161,7 @@ public class JacksonObjectMapperFactoryBean implements FactoryBean
/**
* Specify features to enable.
+ *
* @see SerializationConfig.Feature
* @see DeserializationConfig.Feature
* @see JsonParser.Feature
@@ -176,6 +177,7 @@ public class JacksonObjectMapperFactoryBean implements FactoryBean
/**
* Specify features to disable.
+ *
* @see SerializationConfig.Feature
* @see DeserializationConfig.Feature
* @see JsonParser.Feature
@@ -189,7 +191,6 @@ public class JacksonObjectMapperFactoryBean implements FactoryBean
}
}
-
public void afterPropertiesSet() {
if (this.objectMapper == null) {
this.objectMapper = new ObjectMapper();
@@ -203,11 +204,11 @@ public class JacksonObjectMapperFactoryBean implements FactoryBean
this.objectMapper.getSerializationConfig().setDateFormat(this.dateFormat);
}
for (Map.Entry entry : this.features.entrySet()) {
- setFeatureEnabled(entry.getKey(), entry.getValue());
+ configureFeature(entry.getKey(), entry.getValue().booleanValue());
}
}
- private void setFeatureEnabled(Object feature, boolean enabled) {
+ private void configureFeature(Object feature, boolean enabled) {
if (feature instanceof DeserializationConfig.Feature) {
this.objectMapper.configure((DeserializationConfig.Feature) feature, enabled);
}
@@ -225,7 +226,9 @@ public class JacksonObjectMapperFactoryBean implements FactoryBean
}
}
-
+ /**
+ * Return the singleton ObjectMapper.
+ */
public ObjectMapper getObject() {
return this.objectMapper;
}
diff --git a/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBeanTests.java b/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBeanTests.java
new file mode 100644
index 0000000000..bc52e4c402
--- /dev/null
+++ b/spring-web/src/test/java/org/springframework/http/converter/json/Jackson2ObjectMapperFactoryBeanTests.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2002-2012 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.http.converter.json;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.DirectFieldAccessor;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.MapperFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.cfg.DeserializerFactoryConfig;
+import com.fasterxml.jackson.databind.cfg.SerializerFactoryConfig;
+import com.fasterxml.jackson.databind.deser.std.DateDeserializers.DateDeserializer;
+import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector;
+import com.fasterxml.jackson.databind.ser.std.StdJdkSerializers.ClassSerializer;
+
+/**
+ * Test cases for {@link Jackson2ObjectMapperFactoryBean} class.
+ *
+ * @author Dmitry Katsubo
+ */
+public class Jackson2ObjectMapperFactoryBeanTests {
+
+ private static final String DATE_FORMAT = "yyyy-MM-dd";
+
+ private Jackson2ObjectMapperFactoryBean factory;
+
+ @Before
+ public void setUp() {
+ factory = new Jackson2ObjectMapperFactoryBean();
+ }
+
+ @Test
+ public void testSetFeaturesToEnableEmpty() {
+ this.factory.setFeaturesToEnable(new Object[0]);
+ this.factory.setFeaturesToDisable(new Object[0]);
+ }
+
+ @Test(expected = FatalBeanException.class)
+ public void testUnknownFeature() {
+ this.factory.setFeaturesToEnable(new Object[] { Boolean.TRUE });
+ this.factory.afterPropertiesSet();
+ }
+
+ @Test
+ public void testBooleanSetters() {
+ this.factory.setAutoDetectFields(false);
+ this.factory.setAutoDetectGettersSetters(false);
+ this.factory.setFailOnEmptyBeans(false);
+ this.factory.setIndentOutput(true);
+ this.factory.afterPropertiesSet();
+
+ ObjectMapper objectMapper = this.factory.getObject();
+
+ assertFalse(objectMapper.getSerializationConfig().isEnabled(MapperFeature.AUTO_DETECT_FIELDS));
+ assertFalse(objectMapper.getDeserializationConfig().isEnabled(MapperFeature.AUTO_DETECT_FIELDS));
+ assertFalse(objectMapper.getSerializationConfig().isEnabled(MapperFeature.AUTO_DETECT_GETTERS));
+ assertFalse(objectMapper.getDeserializationConfig().isEnabled(MapperFeature.AUTO_DETECT_SETTERS));
+ assertFalse(objectMapper.getSerializationConfig().isEnabled(SerializationFeature.FAIL_ON_EMPTY_BEANS));
+ assertTrue(objectMapper.getSerializationConfig().isEnabled(SerializationFeature.INDENT_OUTPUT));
+ }
+
+ @Test
+ public void testDateTimeFormatSetter() {
+ SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
+
+ this.factory.setDateFormat(dateFormat);
+ this.factory.afterPropertiesSet();
+
+ assertEquals(dateFormat, this.factory.getObject().getSerializationConfig().getDateFormat());
+ assertEquals(dateFormat, this.factory.getObject().getDeserializationConfig().getDateFormat());
+ }
+
+ @Test
+ public void testSimpleDateFormatStringSetter() {
+ SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
+
+ this.factory.setSimpleDateFormat(DATE_FORMAT);
+ this.factory.afterPropertiesSet();
+
+ assertEquals(dateFormat, this.factory.getObject().getSerializationConfig().getDateFormat());
+ assertEquals(dateFormat, this.factory.getObject().getDeserializationConfig().getDateFormat());
+ }
+
+ @Test
+ public void testSimpleSetup() {
+ this.factory.afterPropertiesSet();
+
+ assertNotNull(this.factory.getObject());
+ assertTrue(this.factory.isSingleton());
+ assertEquals(ObjectMapper.class, this.factory.getObjectType());
+ }
+
+ /**
+ * TODO: Remove use of {@link DirectFieldAccessor} with getters.
+ * See issue#65 .
+ */
+ private static final SerializerFactoryConfig getSerializerFactoryConfig(ObjectMapper objectMapper) {
+ Object factoryProp = new DirectFieldAccessor(objectMapper).getPropertyValue("_serializerFactory");
+ return (SerializerFactoryConfig) new DirectFieldAccessor(factoryProp).getPropertyValue("_factoryConfig");
+ }
+
+ private static final DeserializerFactoryConfig getDeserializerFactoryConfig(ObjectMapper objectMapper) {
+ Object contextProp = new DirectFieldAccessor(objectMapper).getPropertyValue("_deserializationContext");
+ Object factoryProp = new DirectFieldAccessor(contextProp).getPropertyValue("_factory");
+ return (DeserializerFactoryConfig) new DirectFieldAccessor(factoryProp).getPropertyValue("_factoryConfig");
+ }
+
+ @Test
+ public void testCompleteSetup() {
+ NopAnnotationIntrospector annotationIntrospector = NopAnnotationIntrospector.instance;
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ assertTrue(this.factory.isSingleton());
+ assertEquals(ObjectMapper.class, this.factory.getObjectType());
+
+ Map, JsonDeserializer>> deserializers = new HashMap, JsonDeserializer>>();
+ deserializers.put(Date.class, new DateDeserializer());
+
+ this.factory.setObjectMapper(objectMapper);
+ this.factory.setSerializers(new ClassSerializer());
+ this.factory.setDeserializersByType(deserializers);
+ this.factory.setAnnotationIntrospector(annotationIntrospector);
+
+ this.factory.setFeaturesToEnable(
+ SerializationFeature.FAIL_ON_EMPTY_BEANS,
+ DeserializationFeature.UNWRAP_ROOT_VALUE,
+ JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER,
+ JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS);
+
+ this.factory.setFeaturesToDisable(
+ MapperFeature.AUTO_DETECT_GETTERS,
+ MapperFeature.AUTO_DETECT_FIELDS,
+ JsonParser.Feature.AUTO_CLOSE_SOURCE,
+ JsonGenerator.Feature.QUOTE_FIELD_NAMES);
+
+ assertFalse(getSerializerFactoryConfig(objectMapper).hasSerializers());
+ assertFalse(getDeserializerFactoryConfig(objectMapper).hasDeserializers());
+
+ this.factory.afterPropertiesSet();
+
+ assertTrue(objectMapper == this.factory.getObject());
+
+ assertTrue(getSerializerFactoryConfig(objectMapper).hasSerializers());
+ assertTrue(getDeserializerFactoryConfig(objectMapper).hasDeserializers());
+
+ assertTrue(annotationIntrospector == objectMapper.getSerializationConfig().getAnnotationIntrospector());
+ assertTrue(annotationIntrospector == objectMapper.getDeserializationConfig().getAnnotationIntrospector());
+
+ assertTrue(objectMapper.getSerializationConfig().isEnabled(SerializationFeature.FAIL_ON_EMPTY_BEANS));
+ assertTrue(objectMapper.getDeserializationConfig().isEnabled(DeserializationFeature.UNWRAP_ROOT_VALUE));
+ assertTrue(objectMapper.getJsonFactory().isEnabled(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER));
+ assertTrue(objectMapper.getJsonFactory().isEnabled(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS));
+
+ assertFalse(objectMapper.getSerializationConfig().isEnabled(MapperFeature.AUTO_DETECT_GETTERS));
+ assertFalse(objectMapper.getDeserializationConfig().isEnabled(MapperFeature.AUTO_DETECT_FIELDS));
+ assertFalse(objectMapper.getJsonFactory().isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE));
+ assertFalse(objectMapper.getJsonFactory().isEnabled(JsonGenerator.Feature.QUOTE_FIELD_NAMES));
+ }
+}
diff --git a/spring-web/src/test/java/org/springframework/http/converter/json/JacksonObjectMapperFactoryBeanTests.java b/spring-web/src/test/java/org/springframework/http/converter/json/JacksonObjectMapperFactoryBeanTests.java
index 3a22dfddf1..a66f4e2fbb 100644
--- a/spring-web/src/test/java/org/springframework/http/converter/json/JacksonObjectMapperFactoryBeanTests.java
+++ b/spring-web/src/test/java/org/springframework/http/converter/json/JacksonObjectMapperFactoryBeanTests.java
@@ -32,8 +32,6 @@ import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.introspect.NopAnnotationIntrospector;
import org.junit.Before;
import org.junit.Test;
-import org.springframework.beans.FatalBeanException;
-import org.springframework.http.converter.json.JacksonObjectMapperFactoryBean;
/**
* @author Dmitry Katsubo
diff --git a/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java
index 603b6613ab..3579c5d464 100644
--- a/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java
+++ b/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java
@@ -52,7 +52,7 @@ public class MappingJackson2HttpMessageConverterTests extends AbstractMappingJac
@Override
protected JavaType getJavaType(Type type) {
- if (type instanceof Class && List.class.isAssignableFrom((Class)type)) {
+ if (type instanceof Class && List.class.isAssignableFrom((Class>)type)) {
return new ObjectMapper().getTypeFactory().constructCollectionType(ArrayList.class, MyBean.class);
}
else {
diff --git a/spring-web/src/test/java/org/springframework/http/converter/json/MappingJacksonHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/json/MappingJacksonHttpMessageConverterTests.java
index c3fe567a69..5f70a4d6d4 100644
--- a/spring-web/src/test/java/org/springframework/http/converter/json/MappingJacksonHttpMessageConverterTests.java
+++ b/spring-web/src/test/java/org/springframework/http/converter/json/MappingJacksonHttpMessageConverterTests.java
@@ -50,7 +50,7 @@ public class MappingJacksonHttpMessageConverterTests extends AbstractMappingJack
MappingJacksonHttpMessageConverter converter = new MappingJacksonHttpMessageConverter() {
@Override
protected JavaType getJavaType(Type type) {
- if (type instanceof Class && List.class.isAssignableFrom((Class)type)) {
+ if (type instanceof Class && List.class.isAssignableFrom((Class>)type)) {
return TypeFactory.collectionType(ArrayList.class, MyBean.class);
}
else {