Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
cc.shacocloud.mirage.web.bind.converter.json.Jackson2ObjectMapperBuilder Maven / Gradle / Ivy
package cc.shacocloud.mirage.web.bind.converter.json;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import java.util.function.Function;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonFactory;
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.KeyDeserializer;
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.databind.cfg.HandlerInstantiator;
import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair;
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
import com.fasterxml.jackson.dataformat.smile.SmileFactory;
import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule;
import com.fasterxml.jackson.dataformat.xml.XmlFactory;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.FatalBeanException;
import org.springframework.context.ApplicationContext;
import org.springframework.core.KotlinDetector;
import org.jetbrains.annotations.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.StaxUtils;
/**
* 用于使用连贯API创建{@link ObjectMapper}实例的构建器。
*
*
* 它定制Jackson的默认属性如下:
*
* {@link MapperFeature#DEFAULT_VIEW_INCLUSION} 是禁用的
* {@link DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES} 是禁用的
*
*
*
* 如果在类路径中被检测到,它还会自动注册以下众所周知的模块:
*
*
* @see #build()
* @see #configure(ObjectMapper)
*/
public class Jackson2ObjectMapperBuilder {
private static volatile boolean kotlinWarningLogged = false;
private final Log logger = LogFactory.getLog(getClass());
private final Map, Class>> mixIns = new LinkedHashMap<>();
private final Map, JsonSerializer>> serializers = new LinkedHashMap<>();
private final Map, JsonDeserializer>> deserializers = new LinkedHashMap<>();
private final Map visibilities = new LinkedHashMap<>();
private final Map features = new LinkedHashMap<>();
private boolean createXmlMapper = false;
@Nullable
private JsonFactory factory;
@Nullable
private DateFormat dateFormat;
@Nullable
private Locale locale;
@Nullable
private TimeZone timeZone;
@Nullable
private AnnotationIntrospector annotationIntrospector;
@Nullable
private PropertyNamingStrategy propertyNamingStrategy;
@Nullable
private TypeResolverBuilder> defaultTyping;
@Nullable
private JsonInclude.Include serializationInclusion;
@Nullable
private FilterProvider filters;
@Nullable
private List modules;
@Nullable
private Class extends Module>[] moduleClasses;
private boolean findModulesViaServiceLoader = false;
private boolean findWellKnownModules = true;
private ClassLoader moduleClassLoader = getClass().getClassLoader();
@Nullable
private HandlerInstantiator handlerInstantiator;
@Nullable
private ApplicationContext applicationContext;
@Nullable
private Boolean defaultUseWrapper;
/**
* 如果设置为{@code true},将使用其默认构造函数创建一个{@link XmlMapper}。
* 这只适用于{@link #build()}调用,不适用于{@link #configure}调用。
*/
public Jackson2ObjectMapperBuilder createXmlMapper(boolean createXmlMapper) {
this.createXmlMapper = createXmlMapper;
return this;
}
/**
* 定义用于创建{@link ObjectMapper} 实例的{@link JsonFactory}。
*
* @since 5.0
*/
public Jackson2ObjectMapperBuilder factory(JsonFactory factory) {
this.factory = factory;
return this;
}
/**
* 使用给定的{@link DateFormat}定义日期/时间的格式
*
* 注意:根据Jackson的线程安全规则,设置这个属性将使暴露的{@link ObjectMapper} 是非线程安全的。
*
* @see #simpleDateFormat(String)
*/
public Jackson2ObjectMapperBuilder dateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
return this;
}
/**
* 使用{@link SimpleDateFormat}定义日期/时间格式。
*
* 注意:根据Jackson的线程安全规则,设置这个属性将使暴露的{@link ObjectMapper} 是非线程安全的。
*
* @see #dateFormat(DateFormat)
*/
public Jackson2ObjectMapperBuilder simpleDateFormat(String format) {
this.dateFormat = new SimpleDateFormat(format);
return this;
}
/**
* 重写用于格式化的默认{@link Locale}。
* 使用的默认值是{@link Locale#getDefault()}。
*/
public Jackson2ObjectMapperBuilder locale(Locale locale) {
this.locale = locale;
return this;
}
/**
* 重写用于格式化的默认{@link Locale}。
* 使用的默认值是{@link Locale#getDefault()}。
*
* @param localeString 区域设置ID作为字符串表示
*/
public Jackson2ObjectMapperBuilder locale(String localeString) {
this.locale = StringUtils.parseLocale(localeString);
return this;
}
/**
* 重写用于格式化的默认{@link TimeZone}。
* 默认值是UTC(不是本地时区)。
*/
public Jackson2ObjectMapperBuilder timeZone(TimeZone timeZone) {
this.timeZone = timeZone;
return this;
}
/**
* 重写用于格式化的默认{@link TimeZone}。
* 默认值是UTC(不是本地时区)。
*
* @param timeZoneString 区域ID作为字符串表示
*/
public Jackson2ObjectMapperBuilder timeZone(String timeZoneString) {
this.timeZone = StringUtils.parseTimeZoneString(timeZoneString);
return this;
}
/**
* 为序列化和反序列化设置{@link AnnotationIntrospector}。
*/
public Jackson2ObjectMapperBuilder annotationIntrospector(AnnotationIntrospector annotationIntrospector) {
this.annotationIntrospector = annotationIntrospector;
return this;
}
/**
* 可选的{@link #annotationIntrospector} ,该方法允许与当前设置的内省器(例如via)组合而不是替换
* {@link AnnotationIntrospectorPair#pair(AnnotationIntrospector, AnnotationIntrospector)}.
*
* @param pairingFunction 要应用于当前设置的内省器(可能是{@code null})的函数;函数的结果变成新的自省器。
*/
public Jackson2ObjectMapperBuilder annotationIntrospector(
Function pairingFunction) {
this.annotationIntrospector = pairingFunction.apply(this.annotationIntrospector);
return this;
}
/**
* 指定{@link com.fasterxml.jackson.databind。配置{@link ObjectMapper}。
*/
public Jackson2ObjectMapperBuilder propertyNamingStrategy(PropertyNamingStrategy propertyNamingStrategy) {
this.propertyNamingStrategy = propertyNamingStrategy;
return this;
}
/**
* 指定一个{@link TypeResolverBuilder}用于Jackson的默认输入。
*/
public Jackson2ObjectMapperBuilder defaultTyping(TypeResolverBuilder> typeResolverBuilder) {
this.defaultTyping = typeResolverBuilder;
return this;
}
/**
* 为序列化设置自定义包含策略。
*
* @see com.fasterxml.jackson.annotation.JsonInclude.Include
*/
public Jackson2ObjectMapperBuilder serializationInclusion(JsonInclude.Include serializationInclusion) {
this.serializationInclusion = serializationInclusion;
return this;
}
/**
* 设置要使用的全局过滤器,以支持{@link JsonFilter @JsonFilter}注解的POJO。
*
* @see MappingJacksonValue#setFilters(FilterProvider)
*/
public Jackson2ObjectMapperBuilder filters(FilterProvider filters) {
this.filters = filters;
return this;
}
/**
* 添加混合注解以用于扩充指定的类或接口。
*
* @param target 要有效覆盖其注解的类(或接口)
* @param mixinSource 类(或接口),其注解将作为值“添加”到目标的注解中
* @see com.fasterxml.jackson.databind.ObjectMapper#addMixIn(Class, Class)
*/
public Jackson2ObjectMapperBuilder mixIn(Class> target, Class> mixinSource) {
this.mixIns.put(target, mixinSource);
return this;
}
/**
* 添加混合注解以用于扩充指定的类或接口。
*
* @param mixIns 一个带有目标类(或接口)的条目的映射,
* 目标类(或接口)的注解要有效地作为键覆盖,
* 而混合类(或接口)的注解要作为值“添加”到目标的注解。
* @see com.fasterxml.jackson.databind.ObjectMapper#addMixIn(Class, Class)
*/
public Jackson2ObjectMapperBuilder mixIns(Map, Class>> mixIns) {
this.mixIns.putAll(mixIns);
return this;
}
/**
* 配置自定义序列化器。每个序列化器都为{@link JsonSerializer#handledType()}返回的类型注册,该类型不能是{@code null}。
*
* @see #serializersByType(Map)
*/
public Jackson2ObjectMapperBuilder serializers(JsonSerializer>... serializers) {
for (JsonSerializer> serializer : serializers) {
Class> handledType = serializer.handledType();
if (handledType == null || handledType == Object.class) {
throw new IllegalArgumentException("Unknown handled type in " + serializer.getClass().getName());
}
this.serializers.put(serializer.handledType(), serializer);
}
return this;
}
/**
* 为给定类型配置自定义序列化器。
*
* @see #serializers(JsonSerializer...)
*/
public Jackson2ObjectMapperBuilder serializerByType(Class> type, JsonSerializer> serializer) {
this.serializers.put(type, serializer);
return this;
}
/**
* 为给定类型配置自定义序列化器。
*
* @see #serializers(JsonSerializer...)
*/
public Jackson2ObjectMapperBuilder serializersByType(Map, JsonSerializer>> serializers) {
this.serializers.putAll(serializers);
return this;
}
/**
* 配置自定义反序列化器。每个反序列化器都为{@link JsonDeserializer#handledType()}返回的类型注册,该类型不能是{@code null}。
*
* @see #deserializersByType(Map)
*/
public Jackson2ObjectMapperBuilder deserializers(JsonDeserializer>... deserializers) {
for (JsonDeserializer> deserializer : deserializers) {
Class> handledType = deserializer.handledType();
if (handledType == null || handledType == Object.class) {
throw new IllegalArgumentException("Unknown handled type in " + deserializer.getClass().getName());
}
this.deserializers.put(deserializer.handledType(), deserializer);
}
return this;
}
/**
* 为给定类型配置自定义反序列化器。
*/
public Jackson2ObjectMapperBuilder deserializerByType(Class> type, JsonDeserializer> deserializer) {
this.deserializers.put(type, deserializer);
return this;
}
/**
* 为给定类型配置自定义反序列化器。
*/
public Jackson2ObjectMapperBuilder deserializersByType(Map, JsonDeserializer>> deserializers) {
this.deserializers.putAll(deserializers);
return this;
}
/**
* {@link MapperFeature#AUTO_DETECT_FIELDS}选项的快捷方式。
*/
public Jackson2ObjectMapperBuilder autoDetectFields(boolean autoDetectFields) {
this.features.put(MapperFeature.AUTO_DETECT_FIELDS, autoDetectFields);
return this;
}
/**
* {@link MapperFeature#AUTO_DETECT_SETTERS}
* {@link MapperFeature#AUTO_DETECT_GETTERS}
* {@link MapperFeature#AUTO_DETECT_IS_GETTERS}
*/
public Jackson2ObjectMapperBuilder autoDetectGettersSetters(boolean autoDetectGettersSetters) {
this.features.put(MapperFeature.AUTO_DETECT_GETTERS, autoDetectGettersSetters);
this.features.put(MapperFeature.AUTO_DETECT_SETTERS, autoDetectGettersSetters);
this.features.put(MapperFeature.AUTO_DETECT_IS_GETTERS, autoDetectGettersSetters);
return this;
}
/**
* {@link MapperFeature#DEFAULT_VIEW_INCLUSION}选项的快捷方式。
*/
public Jackson2ObjectMapperBuilder defaultViewInclusion(boolean defaultViewInclusion) {
this.features.put(MapperFeature.DEFAULT_VIEW_INCLUSION, defaultViewInclusion);
return this;
}
/**
* {@link DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES}选项的快捷方式。
*/
public Jackson2ObjectMapperBuilder failOnUnknownProperties(boolean failOnUnknownProperties) {
this.features.put(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, failOnUnknownProperties);
return this;
}
/**
* {@link SerializationFeature#FAIL_ON_EMPTY_BEANS}选项的快捷方式。
*/
public Jackson2ObjectMapperBuilder failOnEmptyBeans(boolean failOnEmptyBeans) {
this.features.put(SerializationFeature.FAIL_ON_EMPTY_BEANS, failOnEmptyBeans);
return this;
}
/**
* {@link SerializationFeature#INDENT_OUTPUT}选项的快捷方式。
*/
public Jackson2ObjectMapperBuilder indentOutput(boolean indentOutput) {
this.features.put(SerializationFeature.INDENT_OUTPUT, indentOutput);
return this;
}
/**
* 定义包装器在默认情况下是否用于索引(列表,数组)属性(仅适用于{@link XmlMapper})。
*/
public Jackson2ObjectMapperBuilder defaultUseWrapper(boolean defaultUseWrapper) {
this.defaultUseWrapper = defaultUseWrapper;
return this;
}
/**
* 指定可见性以限制自动检测的属性类型。
*
* @see com.fasterxml.jackson.annotation.PropertyAccessor
* @see com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility
*/
public Jackson2ObjectMapperBuilder visibility(PropertyAccessor accessor, JsonAutoDetect.Visibility visibility) {
this.visibilities.put(accessor, visibility);
return this;
}
/**
* 指定要启用的特性。
*
* @see com.fasterxml.jackson.core.JsonParser.Feature
* @see com.fasterxml.jackson.core.JsonGenerator.Feature
* @see com.fasterxml.jackson.databind.SerializationFeature
* @see com.fasterxml.jackson.databind.DeserializationFeature
* @see com.fasterxml.jackson.databind.MapperFeature
*/
public Jackson2ObjectMapperBuilder featuresToEnable(Object... featuresToEnable) {
for (Object feature : featuresToEnable) {
this.features.put(feature, Boolean.TRUE);
}
return this;
}
/**
* 指定要禁用的特性。
*
* @see com.fasterxml.jackson.core.JsonParser.Feature
* @see com.fasterxml.jackson.core.JsonGenerator.Feature
* @see com.fasterxml.jackson.databind.SerializationFeature
* @see com.fasterxml.jackson.databind.DeserializationFeature
* @see com.fasterxml.jackson.databind.MapperFeature
*/
public Jackson2ObjectMapperBuilder featuresToDisable(Object... featuresToDisable) {
for (Object feature : featuresToDisable) {
this.features.put(feature, Boolean.FALSE);
}
return this;
}
/**
* 指定要向{@link ObjectMapper}注册的一个或多个模块。多个调用不是附加的,最后一个定义要*注册的模块。
* 注意:如果设置了此选项,将不会发现模块——不是通过 Jackson找到的,
* 因此,在这里指定一个空列表将禁止任何类型的模块检测。
*
* 指定this或{@link #modulesToInstall},不要同时指定两者。
*
* @see #modules(List)
* @see com.fasterxml.jackson.databind.Module
*/
public Jackson2ObjectMapperBuilder modules(Module... modules) {
return modules(Arrays.asList(modules));
}
/**
* @see #modules(Module...)
* @see com.fasterxml.jackson.databind.Module
*/
public Jackson2ObjectMapperBuilder modules(List modules) {
this.modules = new LinkedList<>(modules);
this.findModulesViaServiceLoader = false;
this.findWellKnownModules = false;
return this;
}
/**
* 指定要向{@link ObjectMapper}注册的一个或多个模块。
* 多个调用不是附加的,最后一个调用定义了要注册的模块。
*
* 这里指定的模块将在 Spring对JSR-310和Joda-Time的自动检测之后注册,或Jackson对模块的查找之后注册(参见{@link #findModulesViaServiceLoader}),
* 允许最终覆盖它们的配置。
*
* 指定this或{@link #modules},不要同时指定两者。
*
* @see com.fasterxml.jackson.databind.Module
*/
public Jackson2ObjectMapperBuilder modulesToInstall(Module... modules) {
this.modules = Arrays.asList(modules);
this.findWellKnownModules = true;
return this;
}
/**
* @see #modulesToInstall(Module...)
* @see com.fasterxml.jackson.databind.Module
*/
@SuppressWarnings("unchecked")
public Jackson2ObjectMapperBuilder modulesToInstall(Class extends Module>... modules) {
this.moduleClasses = modules;
this.findWellKnownModules = true;
return this;
}
/**
* 根据类路径中的META-INF元数据,设置是否让Jackson通过JDK ServiceLoader查找可用模块。
*
* 如果没有设置此模式,则Spring的Jackson2ObjectMapperBuilder本身将尝试在类路径中找到JSR-310和Joda-Time支持模块,
* 条件是Java 8和Joda-Time本身都是可用的。
*
* @see com.fasterxml.jackson.databind.ObjectMapper#findModules()
*/
public Jackson2ObjectMapperBuilder findModulesViaServiceLoader(boolean findModules) {
this.findModulesViaServiceLoader = findModules;
return this;
}
/**
* 设置用于加载Jackson扩展模块的类加载器。
*/
public Jackson2ObjectMapperBuilder moduleClassLoader(ClassLoader moduleClassLoader) {
this.moduleClassLoader = moduleClassLoader;
return this;
}
/**
* 定制Jackson处理程序的构造({@link JsonSerializer}、{@link JsonDeserializer}、{@link KeyDeserializer}、
* {@code TypeResolverBuilder}和{@code TypeIdResolver})。
*
* @see Jackson2ObjectMapperBuilder#applicationContext(ApplicationContext)
*/
public Jackson2ObjectMapperBuilder handlerInstantiator(HandlerInstantiator handlerInstantiator) {
this.handlerInstantiator = handlerInstantiator;
return this;
}
/**
* 设置Spring {@link ApplicationContext}来自动连接Jackson处理程序({@link JsonSerializer}、 {@link JsonDeserializer}、
* {@link KeyDeserializer}、{@code TypeResolverBuilder}和{@code TypeIdResolver})。
*/
public Jackson2ObjectMapperBuilder applicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
return this;
}
/**
* 构建一个新的{@link ObjectMapper}实例。
*
* 每个构建操作都会生成一个独立的{@link ObjectMapper}实例。
* 构建器的设置可以被修改,通过随后的构建操作然后根据最近的设置生成一个新的{@link ObjectMapper}。
*
* @return 新构建的ObjectMapper
*/
@SuppressWarnings("unchecked")
public T build() {
ObjectMapper mapper;
if (this.createXmlMapper) {
mapper = (this.defaultUseWrapper != null ?
new XmlObjectMapperInitializer().create(this.defaultUseWrapper, this.factory) :
new XmlObjectMapperInitializer().create(this.factory));
} else {
mapper = (this.factory != null ? new ObjectMapper(this.factory) : new ObjectMapper());
}
configure(mapper);
return (T) mapper;
}
/**
* 使用此构建器的设置配置现有的{@link ObjectMapper}实例。这可以应用于任意数量的{@code ObjectMappers}。
*
* @param objectMapper 要配置的ObjectMapper
*/
public void configure(ObjectMapper objectMapper) {
Assert.notNull(objectMapper, "ObjectMapper must not be null");
MultiValueMap modulesToRegister = new LinkedMultiValueMap<>();
if (this.findModulesViaServiceLoader) {
ObjectMapper.findModules(this.moduleClassLoader).forEach(module -> registerModule(module, modulesToRegister));
} else if (this.findWellKnownModules) {
registerWellKnownModulesIfAvailable(modulesToRegister);
}
if (this.modules != null) {
this.modules.forEach(module -> registerModule(module, modulesToRegister));
}
if (this.moduleClasses != null) {
for (Class extends Module> moduleClass : this.moduleClasses) {
registerModule(BeanUtils.instantiateClass(moduleClass), modulesToRegister);
}
}
List modules = new ArrayList<>();
for (List nestedModules : modulesToRegister.values()) {
modules.addAll(nestedModules);
}
objectMapper.registerModules(modules);
if (this.dateFormat != null) {
objectMapper.setDateFormat(this.dateFormat);
}
if (this.locale != null) {
objectMapper.setLocale(this.locale);
}
if (this.timeZone != null) {
objectMapper.setTimeZone(this.timeZone);
}
if (this.annotationIntrospector != null) {
objectMapper.setAnnotationIntrospector(this.annotationIntrospector);
}
if (this.propertyNamingStrategy != null) {
objectMapper.setPropertyNamingStrategy(this.propertyNamingStrategy);
}
if (this.defaultTyping != null) {
objectMapper.setDefaultTyping(this.defaultTyping);
}
if (this.serializationInclusion != null) {
objectMapper.setSerializationInclusion(this.serializationInclusion);
}
if (this.filters != null) {
objectMapper.setFilterProvider(this.filters);
}
this.mixIns.forEach(objectMapper::addMixIn);
if (!this.serializers.isEmpty() || !this.deserializers.isEmpty()) {
SimpleModule module = new SimpleModule();
addSerializers(module);
addDeserializers(module);
objectMapper.registerModule(module);
}
this.visibilities.forEach(objectMapper::setVisibility);
customizeDefaultFeatures(objectMapper);
this.features.forEach((feature, enabled) -> configureFeature(objectMapper, feature, enabled));
if (this.handlerInstantiator != null) {
objectMapper.setHandlerInstantiator(this.handlerInstantiator);
} else if (this.applicationContext != null) {
objectMapper.setHandlerInstantiator(
new SpringHandlerInstantiator(this.applicationContext.getAutowireCapableBeanFactory()));
}
}
private void registerModule(Module module, MultiValueMap modulesToRegister) {
if (module.getTypeId() == null) {
modulesToRegister.add(SimpleModule.class.getName(), module);
} else {
modulesToRegister.set(module.getTypeId(), module);
}
}
// Any change to this method should be also applied to spring-jms and spring-messaging
// MappingJackson2MessageConverter default constructors
private void customizeDefaultFeatures(ObjectMapper objectMapper) {
if (!this.features.containsKey(MapperFeature.DEFAULT_VIEW_INCLUSION)) {
configureFeature(objectMapper, MapperFeature.DEFAULT_VIEW_INCLUSION, false);
}
if (!this.features.containsKey(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) {
configureFeature(objectMapper, DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
}
@SuppressWarnings("unchecked")
private void addSerializers(SimpleModule module) {
this.serializers.forEach((type, serializer) ->
module.addSerializer((Class extends T>) type, (JsonSerializer) serializer));
}
@SuppressWarnings("unchecked")
private void addDeserializers(SimpleModule module) {
this.deserializers.forEach((type, deserializer) ->
module.addDeserializer((Class) type, (JsonDeserializer extends T>) deserializer));
}
private void configureFeature(ObjectMapper objectMapper, Object feature, boolean enabled) {
if (feature instanceof JsonParser.Feature) {
objectMapper.configure((JsonParser.Feature) feature, enabled);
} else if (feature instanceof JsonGenerator.Feature) {
objectMapper.configure((JsonGenerator.Feature) feature, enabled);
} else if (feature instanceof SerializationFeature) {
objectMapper.configure((SerializationFeature) feature, enabled);
} else if (feature instanceof DeserializationFeature) {
objectMapper.configure((DeserializationFeature) feature, enabled);
} else if (feature instanceof MapperFeature) {
objectMapper.configure((MapperFeature) feature, enabled);
} else {
throw new FatalBeanException("未知功能类: " + feature.getClass().getName());
}
}
@SuppressWarnings("unchecked")
private void registerWellKnownModulesIfAvailable(MultiValueMap modulesToRegister) {
try {
Class extends Module> jdk8ModuleClass = (Class extends Module>)
ClassUtils.forName("com.fasterxml.jackson.datatype.jdk8.Jdk8Module", this.moduleClassLoader);
Module jdk8Module = BeanUtils.instantiateClass(jdk8ModuleClass);
modulesToRegister.set(jdk8Module.getTypeId(), jdk8Module);
} catch (ClassNotFoundException ex) {
// jackson-datatype-jdk8 not available
}
try {
Class extends Module> javaTimeModuleClass = (Class extends Module>)
ClassUtils.forName("com.fasterxml.jackson.datatype.jsr310.JavaTimeModule", this.moduleClassLoader);
Module javaTimeModule = BeanUtils.instantiateClass(javaTimeModuleClass);
modulesToRegister.set(javaTimeModule.getTypeId(), javaTimeModule);
} catch (ClassNotFoundException ex) {
// jackson-datatype-jsr310 not available
}
// Joda-Time present?
if (ClassUtils.isPresent("org.joda.time.LocalDate", this.moduleClassLoader)) {
try {
Class extends Module> jodaModuleClass = (Class extends Module>)
ClassUtils.forName("com.fasterxml.jackson.datatype.joda.JodaModule", this.moduleClassLoader);
Module jodaModule = BeanUtils.instantiateClass(jodaModuleClass);
modulesToRegister.set(jodaModule.getTypeId(), jodaModule);
} catch (ClassNotFoundException ex) {
// jackson-datatype-joda not available
}
}
// Kotlin present?
if (KotlinDetector.isKotlinPresent()) {
try {
Class extends Module> kotlinModuleClass = (Class extends Module>)
ClassUtils.forName("com.fasterxml.jackson.module.kotlin.KotlinModule", this.moduleClassLoader);
Module kotlinModule = BeanUtils.instantiateClass(kotlinModuleClass);
modulesToRegister.set(kotlinModule.getTypeId(), kotlinModule);
} catch (ClassNotFoundException ex) {
if (!kotlinWarningLogged) {
kotlinWarningLogged = true;
logger.warn("对于Jackson Kotlin类支持,请添加 " +
"\"com.fasterxml.jackson.module:jackson-module-kotlin\" 到类路径");
}
}
}
}
// Convenience factory methods
/**
* 获取一个{@link Jackson2ObjectMapperBuilder}实例,以便构建一个普通的JSON {@link ObjectMapper}实例。
*/
public static Jackson2ObjectMapperBuilder json() {
return new Jackson2ObjectMapperBuilder();
}
/**
* 获取一个{@link Jackson2ObjectMapperBuilder}实例,以便构建一个{@link XmlMapper}实例。
*/
public static Jackson2ObjectMapperBuilder xml() {
return new Jackson2ObjectMapperBuilder().createXmlMapper(true);
}
/**
* 获取一个{@link Jackson2ObjectMapperBuilder}实例,以构建一个Smile数据格式{@link ObjectMapper}实例。
*/
public static Jackson2ObjectMapperBuilder smile() {
return new Jackson2ObjectMapperBuilder().factory(new SmileFactoryInitializer().create());
}
/**
* 获取一个{@link Jackson2ObjectMapperBuilder}实例,以便构建一个CBOR数据格式{@link ObjectMapper}实例。
*/
public static Jackson2ObjectMapperBuilder cbor() {
return new Jackson2ObjectMapperBuilder().factory(new CborFactoryInitializer().create());
}
private static class XmlObjectMapperInitializer {
public ObjectMapper create(@Nullable JsonFactory factory) {
if (factory != null) {
return new XmlMapper((XmlFactory) factory);
} else {
return new XmlMapper(StaxUtils.createDefensiveInputFactory());
}
}
public ObjectMapper create(boolean defaultUseWrapper, @Nullable JsonFactory factory) {
JacksonXmlModule module = new JacksonXmlModule();
module.setDefaultUseWrapper(defaultUseWrapper);
if (factory != null) {
return new XmlMapper((XmlFactory) factory, module);
} else {
return new XmlMapper(new XmlFactory(StaxUtils.createDefensiveInputFactory()), module);
}
}
}
private static class SmileFactoryInitializer {
public JsonFactory create() {
return new SmileFactory();
}
}
private static class CborFactoryInitializer {
public JsonFactory create() {
return new CBORFactory();
}
}
}