|
|
|
@ -18,15 +18,10 @@ package org.springframework.http.converter.json; |
|
|
|
|
|
|
|
|
|
|
|
import java.text.DateFormat; |
|
|
|
import java.text.DateFormat; |
|
|
|
import java.text.SimpleDateFormat; |
|
|
|
import java.text.SimpleDateFormat; |
|
|
|
import java.util.HashMap; |
|
|
|
|
|
|
|
import java.util.LinkedHashMap; |
|
|
|
|
|
|
|
import java.util.LinkedList; |
|
|
|
|
|
|
|
import java.util.List; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
|
|
|
|
import com.fasterxml.jackson.annotation.JsonInclude; |
|
|
|
import com.fasterxml.jackson.annotation.JsonInclude; |
|
|
|
import com.fasterxml.jackson.core.JsonGenerator; |
|
|
|
|
|
|
|
import com.fasterxml.jackson.core.JsonParser; |
|
|
|
|
|
|
|
import com.fasterxml.jackson.databind.AnnotationIntrospector; |
|
|
|
import com.fasterxml.jackson.databind.AnnotationIntrospector; |
|
|
|
import com.fasterxml.jackson.databind.DeserializationFeature; |
|
|
|
import com.fasterxml.jackson.databind.DeserializationFeature; |
|
|
|
import com.fasterxml.jackson.databind.JsonDeserializer; |
|
|
|
import com.fasterxml.jackson.databind.JsonDeserializer; |
|
|
|
@ -36,16 +31,11 @@ import com.fasterxml.jackson.databind.Module; |
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper; |
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper; |
|
|
|
import com.fasterxml.jackson.databind.PropertyNamingStrategy; |
|
|
|
import com.fasterxml.jackson.databind.PropertyNamingStrategy; |
|
|
|
import com.fasterxml.jackson.databind.SerializationFeature; |
|
|
|
import com.fasterxml.jackson.databind.SerializationFeature; |
|
|
|
import com.fasterxml.jackson.databind.module.SimpleModule; |
|
|
|
|
|
|
|
import com.fasterxml.jackson.dataformat.xml.XmlMapper; |
|
|
|
import com.fasterxml.jackson.dataformat.xml.XmlMapper; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.beans.BeanUtils; |
|
|
|
|
|
|
|
import org.springframework.beans.FatalBeanException; |
|
|
|
|
|
|
|
import org.springframework.beans.factory.BeanClassLoaderAware; |
|
|
|
import org.springframework.beans.factory.BeanClassLoaderAware; |
|
|
|
import org.springframework.beans.factory.FactoryBean; |
|
|
|
import org.springframework.beans.factory.FactoryBean; |
|
|
|
import org.springframework.beans.factory.InitializingBean; |
|
|
|
import org.springframework.beans.factory.InitializingBean; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
|
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* A {@link FactoryBean} for creating a Jackson 2.x {@link ObjectMapper} (default) or |
|
|
|
* A {@link FactoryBean} for creating a Jackson 2.x {@link ObjectMapper} (default) or |
|
|
|
@ -54,8 +44,8 @@ import org.springframework.util.ClassUtils; |
|
|
|
* |
|
|
|
* |
|
|
|
* <p>It customizes Jackson defaults properties with the following ones: |
|
|
|
* <p>It customizes Jackson defaults properties with the following ones: |
|
|
|
* <ul> |
|
|
|
* <ul> |
|
|
|
* <li>{@link MapperFeature#DEFAULT_VIEW_INCLUSION} is disabled</li> |
|
|
|
* <li>{@link MapperFeature#DEFAULT_VIEW_INCLUSION} is disabled</li> |
|
|
|
* <li>{@link DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES} is disabled</li> |
|
|
|
* <li>{@link DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES} is disabled</li> |
|
|
|
* </ul> |
|
|
|
* </ul> |
|
|
|
* |
|
|
|
* |
|
|
|
* <p>Example usage with |
|
|
|
* <p>Example usage with |
|
|
|
@ -132,31 +122,9 @@ import org.springframework.util.ClassUtils; |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper>, BeanClassLoaderAware, InitializingBean { |
|
|
|
public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper>, BeanClassLoaderAware, InitializingBean { |
|
|
|
|
|
|
|
|
|
|
|
private ObjectMapper objectMapper; |
|
|
|
private final Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json(); |
|
|
|
|
|
|
|
|
|
|
|
private boolean createXmlMapper = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private DateFormat dateFormat; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private JsonInclude.Include serializationInclusion; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private AnnotationIntrospector annotationIntrospector; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Map<Class<?>, JsonSerializer<?>> serializers = new LinkedHashMap<Class<?>, JsonSerializer<?>>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Map<Class<?>, JsonDeserializer<?>> deserializers = new LinkedHashMap<Class<?>, JsonDeserializer<?>>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Map<Object, Boolean> features = new HashMap<Object, Boolean>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private List<Module> modules; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Class<? extends Module>[] modulesToInstall; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean findModulesViaServiceLoader; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private PropertyNamingStrategy propertyNamingStrategy; |
|
|
|
private ObjectMapper objectMapper; |
|
|
|
|
|
|
|
|
|
|
|
private ClassLoader beanClassLoader; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -170,9 +138,10 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper |
|
|
|
/** |
|
|
|
/** |
|
|
|
* If set to true and no custom {@link ObjectMapper} has been set, a {@link XmlMapper} |
|
|
|
* If set to true and no custom {@link ObjectMapper} has been set, a {@link XmlMapper} |
|
|
|
* will be created using its default constructor. |
|
|
|
* will be created using its default constructor. |
|
|
|
|
|
|
|
* @since 4.1 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setCreateXmlMapper(boolean createXmlMapper) { |
|
|
|
public void setCreateXmlMapper(boolean createXmlMapper) { |
|
|
|
this.createXmlMapper = createXmlMapper; |
|
|
|
this.builder.createXmlMapper(createXmlMapper); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -182,7 +151,7 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper |
|
|
|
* @see #setSimpleDateFormat(String) |
|
|
|
* @see #setSimpleDateFormat(String) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setDateFormat(DateFormat dateFormat) { |
|
|
|
public void setDateFormat(DateFormat dateFormat) { |
|
|
|
this.dateFormat = dateFormat; |
|
|
|
this.builder.dateFormat(dateFormat); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -192,14 +161,23 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper |
|
|
|
* @see #setDateFormat(DateFormat) |
|
|
|
* @see #setDateFormat(DateFormat) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setSimpleDateFormat(String format) { |
|
|
|
public void setSimpleDateFormat(String format) { |
|
|
|
this.dateFormat = new SimpleDateFormat(format); |
|
|
|
this.builder.simpleDateFormat(format); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Set an {@link AnnotationIntrospector} for both serialization and deserialization. |
|
|
|
* Set an {@link AnnotationIntrospector} for both serialization and deserialization. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setAnnotationIntrospector(AnnotationIntrospector annotationIntrospector) { |
|
|
|
public void setAnnotationIntrospector(AnnotationIntrospector annotationIntrospector) { |
|
|
|
this.annotationIntrospector = annotationIntrospector; |
|
|
|
this.builder.annotationIntrospector(annotationIntrospector); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Specify a {@link com.fasterxml.jackson.databind.PropertyNamingStrategy} to |
|
|
|
|
|
|
|
* configure the {@link ObjectMapper} with. |
|
|
|
|
|
|
|
* @since 4.0.2 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public void setPropertyNamingStrategy(PropertyNamingStrategy propertyNamingStrategy) { |
|
|
|
|
|
|
|
this.builder.propertyNamingStrategy(propertyNamingStrategy); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -207,7 +185,7 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper |
|
|
|
* @see com.fasterxml.jackson.annotation.JsonInclude.Include |
|
|
|
* @see com.fasterxml.jackson.annotation.JsonInclude.Include |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setSerializationInclusion(JsonInclude.Include serializationInclusion) { |
|
|
|
public void setSerializationInclusion(JsonInclude.Include serializationInclusion) { |
|
|
|
this.serializationInclusion = serializationInclusion; |
|
|
|
this.builder.serializationInclusion(serializationInclusion); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -217,14 +195,7 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper |
|
|
|
* @see #setSerializersByType(Map) |
|
|
|
* @see #setSerializersByType(Map) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setSerializers(JsonSerializer<?>... serializers) { |
|
|
|
public void setSerializers(JsonSerializer<?>... serializers) { |
|
|
|
if (serializers != null) { |
|
|
|
this.builder.serializers(serializers); |
|
|
|
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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -232,25 +203,21 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper |
|
|
|
* @see #setSerializers(JsonSerializer...) |
|
|
|
* @see #setSerializers(JsonSerializer...) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setSerializersByType(Map<Class<?>, JsonSerializer<?>> serializers) { |
|
|
|
public void setSerializersByType(Map<Class<?>, JsonSerializer<?>> serializers) { |
|
|
|
if (serializers != null) { |
|
|
|
this.builder.serializersByType(serializers); |
|
|
|
this.serializers.putAll(serializers); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Configure custom deserializers for the given types. |
|
|
|
* Configure custom deserializers for the given types. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setDeserializersByType(Map<Class<?>, JsonDeserializer<?>> deserializers) { |
|
|
|
public void setDeserializersByType(Map<Class<?>, JsonDeserializer<?>> deserializers) { |
|
|
|
if (deserializers != null) { |
|
|
|
this.builder.deserializersByType(deserializers); |
|
|
|
this.deserializers.putAll(deserializers); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Shortcut for {@link MapperFeature#AUTO_DETECT_FIELDS} option. |
|
|
|
* Shortcut for {@link MapperFeature#AUTO_DETECT_FIELDS} option. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setAutoDetectFields(boolean autoDetectFields) { |
|
|
|
public void setAutoDetectFields(boolean autoDetectFields) { |
|
|
|
this.features.put(MapperFeature.AUTO_DETECT_FIELDS, autoDetectFields); |
|
|
|
this.builder.autoDetectFields(autoDetectFields); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -258,36 +225,37 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper |
|
|
|
* {@link MapperFeature#AUTO_DETECT_GETTERS} option. |
|
|
|
* {@link MapperFeature#AUTO_DETECT_GETTERS} option. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setAutoDetectGettersSetters(boolean autoDetectGettersSetters) { |
|
|
|
public void setAutoDetectGettersSetters(boolean autoDetectGettersSetters) { |
|
|
|
this.features.put(MapperFeature.AUTO_DETECT_GETTERS, autoDetectGettersSetters); |
|
|
|
this.builder.autoDetectGettersSetters(autoDetectGettersSetters); |
|
|
|
this.features.put(MapperFeature.AUTO_DETECT_SETTERS, autoDetectGettersSetters); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Shortcut for {@link DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES} option. |
|
|
|
* Shortcut for {@link MapperFeature#DEFAULT_VIEW_INCLUSION} option. |
|
|
|
|
|
|
|
* @since 4.1 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setFailOnUnknownProperties(boolean failOnUnknownProperties) { |
|
|
|
public void setDefaultViewInclusion(boolean defaultViewInclusion) { |
|
|
|
this.features.put(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, failOnUnknownProperties); |
|
|
|
this.builder.defaultViewInclusion(defaultViewInclusion); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Shortcut for {@link MapperFeature#DEFAULT_VIEW_INCLUSION} option. |
|
|
|
* Shortcut for {@link DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES} option. |
|
|
|
|
|
|
|
* @since 4.1.1 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setDefaultViewInclusion(boolean defaultViewInclusion) { |
|
|
|
public void setFailOnUnknownProperties(boolean failOnUnknownProperties) { |
|
|
|
this.features.put(MapperFeature.DEFAULT_VIEW_INCLUSION, defaultViewInclusion); |
|
|
|
this.builder.failOnUnknownProperties(failOnUnknownProperties); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Shortcut for {@link SerializationFeature#FAIL_ON_EMPTY_BEANS} option. |
|
|
|
* Shortcut for {@link SerializationFeature#FAIL_ON_EMPTY_BEANS} option. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setFailOnEmptyBeans(boolean failOnEmptyBeans) { |
|
|
|
public void setFailOnEmptyBeans(boolean failOnEmptyBeans) { |
|
|
|
this.features.put(SerializationFeature.FAIL_ON_EMPTY_BEANS, failOnEmptyBeans); |
|
|
|
this.builder.failOnEmptyBeans(failOnEmptyBeans); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Shortcut for {@link SerializationFeature#INDENT_OUTPUT} option. |
|
|
|
* Shortcut for {@link SerializationFeature#INDENT_OUTPUT} option. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setIndentOutput(boolean indentOutput) { |
|
|
|
public void setIndentOutput(boolean indentOutput) { |
|
|
|
this.features.put(SerializationFeature.INDENT_OUTPUT, indentOutput); |
|
|
|
this.builder.indentOutput(indentOutput); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -299,11 +267,7 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper |
|
|
|
* @see com.fasterxml.jackson.databind.MapperFeature |
|
|
|
* @see com.fasterxml.jackson.databind.MapperFeature |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setFeaturesToEnable(Object... featuresToEnable) { |
|
|
|
public void setFeaturesToEnable(Object... featuresToEnable) { |
|
|
|
if (featuresToEnable != null) { |
|
|
|
this.builder.featuresToEnable(featuresToEnable); |
|
|
|
for (Object feature : featuresToEnable) { |
|
|
|
|
|
|
|
this.features.put(feature, Boolean.TRUE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -315,11 +279,7 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper |
|
|
|
* @see com.fasterxml.jackson.databind.MapperFeature |
|
|
|
* @see com.fasterxml.jackson.databind.MapperFeature |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setFeaturesToDisable(Object... featuresToDisable) { |
|
|
|
public void setFeaturesToDisable(Object... featuresToDisable) { |
|
|
|
if (featuresToDisable != null) { |
|
|
|
this.builder.featuresToDisable(featuresToDisable); |
|
|
|
for (Object feature : featuresToDisable) { |
|
|
|
|
|
|
|
this.features.put(feature, Boolean.FALSE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -333,7 +293,7 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper |
|
|
|
* @see com.fasterxml.jackson.databind.Module |
|
|
|
* @see com.fasterxml.jackson.databind.Module |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setModules(List<Module> modules) { |
|
|
|
public void setModules(List<Module> modules) { |
|
|
|
this.modules = new LinkedList<Module>(modules); |
|
|
|
this.builder.modules(modules); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -347,7 +307,7 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper |
|
|
|
* @see com.fasterxml.jackson.databind.Module |
|
|
|
* @see com.fasterxml.jackson.databind.Module |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setModulesToInstall(Class<? extends Module>... modules) { |
|
|
|
public void setModulesToInstall(Class<? extends Module>... modules) { |
|
|
|
this.modulesToInstall = modules; |
|
|
|
this.builder.modulesToInstall(modules); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -360,165 +320,23 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper |
|
|
|
* @see com.fasterxml.jackson.databind.ObjectMapper#findModules() |
|
|
|
* @see com.fasterxml.jackson.databind.ObjectMapper#findModules() |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public void setFindModulesViaServiceLoader(boolean findModules) { |
|
|
|
public void setFindModulesViaServiceLoader(boolean findModules) { |
|
|
|
this.findModulesViaServiceLoader = findModules; |
|
|
|
this.builder.findModulesViaServiceLoader(findModules); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Specify a {@link com.fasterxml.jackson.databind.PropertyNamingStrategy} to |
|
|
|
|
|
|
|
* configure the {@link ObjectMapper} with. |
|
|
|
|
|
|
|
* @since 4.0.2 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public void setPropertyNamingStrategy(PropertyNamingStrategy propertyNamingStrategy) { |
|
|
|
|
|
|
|
this.propertyNamingStrategy = propertyNamingStrategy; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void setBeanClassLoader(ClassLoader beanClassLoader) { |
|
|
|
public void setBeanClassLoader(ClassLoader beanClassLoader) { |
|
|
|
this.beanClassLoader = beanClassLoader; |
|
|
|
this.builder.moduleClassLoader(beanClassLoader); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
public void afterPropertiesSet() { |
|
|
|
public void afterPropertiesSet() { |
|
|
|
if (this.objectMapper == null) { |
|
|
|
if (this.objectMapper != null) { |
|
|
|
if(this.createXmlMapper) { |
|
|
|
this.builder.configure(this.objectMapper); |
|
|
|
ClassLoader cl = this.beanClassLoader; |
|
|
|
|
|
|
|
if (cl == null) { |
|
|
|
|
|
|
|
cl = getClass().getClassLoader(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
Class<? extends ObjectMapper> xmlMapper = (Class<? extends ObjectMapper>) |
|
|
|
|
|
|
|
cl.loadClass("com.fasterxml.jackson.dataformat.xml.XmlMapper"); |
|
|
|
|
|
|
|
this.objectMapper = BeanUtils.instantiate(xmlMapper); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (ClassNotFoundException ex) { |
|
|
|
|
|
|
|
throw new IllegalStateException("Could not instantiate XmlMapper", ex); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
this.objectMapper = new ObjectMapper(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this.dateFormat != null) { |
|
|
|
|
|
|
|
this.objectMapper.setDateFormat(this.dateFormat); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this.annotationIntrospector != null) { |
|
|
|
|
|
|
|
this.objectMapper.setAnnotationIntrospector(this.annotationIntrospector); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this.serializationInclusion != null) { |
|
|
|
|
|
|
|
this.objectMapper.setSerializationInclusion(this.serializationInclusion); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!this.serializers.isEmpty() || !this.deserializers.isEmpty()) { |
|
|
|
|
|
|
|
SimpleModule module = new SimpleModule(); |
|
|
|
|
|
|
|
addSerializers(module); |
|
|
|
|
|
|
|
addDeserializers(module); |
|
|
|
|
|
|
|
this.objectMapper.registerModule(module); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!features.containsKey(MapperFeature.DEFAULT_VIEW_INCLUSION)) { |
|
|
|
|
|
|
|
configureFeature(MapperFeature.DEFAULT_VIEW_INCLUSION, false); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(!features.containsKey(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) { |
|
|
|
|
|
|
|
configureFeature(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for (Object feature : this.features.keySet()) { |
|
|
|
|
|
|
|
configureFeature(feature, this.features.get(feature)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this.modules != null) { |
|
|
|
|
|
|
|
// Complete list of modules given
|
|
|
|
|
|
|
|
for (Module module : this.modules) { |
|
|
|
|
|
|
|
// Using Jackson 2.0+ registerModule method, not Jackson 2.2+ registerModules
|
|
|
|
|
|
|
|
this.objectMapper.registerModule(module); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
// Combination of modules by class names specified and class presence in the classpath
|
|
|
|
this.objectMapper = this.builder.build(); |
|
|
|
if (this.modulesToInstall != null) { |
|
|
|
|
|
|
|
for (Class<? extends Module> module : this.modulesToInstall) { |
|
|
|
|
|
|
|
this.objectMapper.registerModule(BeanUtils.instantiate(module)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (this.findModulesViaServiceLoader) { |
|
|
|
|
|
|
|
// Jackson 2.2+
|
|
|
|
|
|
|
|
this.objectMapper.registerModules(ObjectMapper.findModules(this.beanClassLoader)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
registerWellKnownModulesIfAvailable(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this.propertyNamingStrategy != null) { |
|
|
|
|
|
|
|
this.objectMapper.setPropertyNamingStrategy(this.propertyNamingStrategy); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
|
|
|
|
private <T> void addSerializers(SimpleModule module) { |
|
|
|
|
|
|
|
for (Class<?> type : this.serializers.keySet()) { |
|
|
|
|
|
|
|
module.addSerializer((Class<? extends T>) type, (JsonSerializer<T>) this.serializers.get(type)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
|
|
|
|
private <T> void addDeserializers(SimpleModule module) { |
|
|
|
|
|
|
|
for (Class<?> type : this.deserializers.keySet()) { |
|
|
|
|
|
|
|
module.addDeserializer((Class<T>) type, (JsonDeserializer<? extends T>) this.deserializers.get(type)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void configureFeature(Object feature, boolean enabled) { |
|
|
|
|
|
|
|
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 if (feature instanceof SerializationFeature) { |
|
|
|
|
|
|
|
this.objectMapper.configure((SerializationFeature) feature, enabled); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (feature instanceof DeserializationFeature) { |
|
|
|
|
|
|
|
this.objectMapper.configure((DeserializationFeature) feature, enabled); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (feature instanceof MapperFeature) { |
|
|
|
|
|
|
|
this.objectMapper.configure((MapperFeature) feature, enabled); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
throw new FatalBeanException("Unknown feature class: " + feature.getClass().getName()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
|
|
|
|
private void registerWellKnownModulesIfAvailable() { |
|
|
|
|
|
|
|
ClassLoader cl = this.beanClassLoader; |
|
|
|
|
|
|
|
if (cl == null) { |
|
|
|
|
|
|
|
cl = getClass().getClassLoader(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Java 8 java.time package present?
|
|
|
|
|
|
|
|
if (ClassUtils.isPresent("java.time.LocalDate", cl)) { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
Class<? extends Module> jsr310Module = (Class<? extends Module>) |
|
|
|
|
|
|
|
cl.loadClass("com.fasterxml.jackson.datatype.jsr310.JSR310Module"); |
|
|
|
|
|
|
|
this.objectMapper.registerModule(BeanUtils.instantiate(jsr310Module)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (ClassNotFoundException ex) { |
|
|
|
|
|
|
|
// jackson-datatype-jsr310 not available
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Joda-Time present?
|
|
|
|
|
|
|
|
if (ClassUtils.isPresent("org.joda.time.LocalDate", cl)) { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
Class<? extends Module> jodaModule = (Class<? extends Module>) |
|
|
|
|
|
|
|
cl.loadClass("com.fasterxml.jackson.datatype.joda.JodaModule"); |
|
|
|
|
|
|
|
this.objectMapper.registerModule(BeanUtils.instantiate(jodaModule)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (ClassNotFoundException ex) { |
|
|
|
|
|
|
|
// jackson-datatype-joda not available
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -533,7 +351,7 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public Class<?> getObjectType() { |
|
|
|
public Class<?> getObjectType() { |
|
|
|
return (this.objectMapper != null) ? this.objectMapper.getClass() : null; |
|
|
|
return (this.objectMapper != null ? this.objectMapper.getClass() : null); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
|