有道无术,术尚可求,有术无道,止于术。
本系列Jackson 版本 2.17.0
源码地址:https://gitee.com/pearl-organization/study-jaskson-demo
文章目录
- 1. 前言
- 2. Spring Web
- 3. Jackson2ObjectMapperBuilder
- 3.1 成员属性
- 3.2 静态方法
- 3.3 自定义序列化/反序列化器
- 3.4 模块注册
- 3.5 启用/禁用特征
- 3.6 混合注解
- 3.7 构建
- 3.8 配置
- 3.9 其他
1. 前言
Spring
生态使用Jackson
作为默认的JSON
处理框架,这些年随着Spring
的大发异彩和Jackson
本身的优越特性,已成为世界上最流行的JSON
库。
接下来,本系列会讲解Spring MVC
、Spring Boot
中如何使用Jackson
,以及Spring
对其进行扩展增强的相关源码,所以需要读者有一定的Spring
、Spring Boot
开发经验。
2. Spring Web
Spring MVC
对于后端开发人员来说已经很熟悉了,它是一个构建在Servlet
之上的一个Web
框架,而Spring Web
是Spring MVC
的基础模块(还有一个Spring Flux
),它们同属于spring-framework
框架。
Web
框架在处理HTTP
请求响应时,需要将请求报文反序列化为Java
对象进行接收处理,在响应阶段,需要将Java
对象反序列化为报文写出,所以需要依赖JSON
框架去处理。
Spring Web
中可以看到引入了Jackson
、GJson
:
在spring-web
模块的org.springframework.http.converter.json
包下,可以看到Json
集成的代码:
集成Jackson
的主要有:
Jackson2ObjectMapperBuilder
:ObjectMapper
构建器Jackson2ObjectMapperFactoryBean
:创建和管理ObjectMapper Bean
对象MappingJackson2HttpMessageConverter
:基于Jackson
的消息转换器SpringHandlerInstantiator
:Spring
环境集成JacksonModulesRuntimeHints
:Spring AOT
所需的RuntimeHints
(运行时提示)
3. Jackson2ObjectMapperBuilder
Jackson2ObjectMapperBuilder
从名字上看已经很好理解,它是一个Jackson
的ObjectMapper
构建器,提供了Fluent API
来定制ObjectMapper
的默认属性并构建实例。
在之前我们都是通过new
的方式创建ObjectMapper
实例,现在可以使用构建者模式,这也是Spring
自身使用和推荐使用的方式。
3.1 成员属性
// 是否引入了`jackson-dataformat-xml`模块private static final boolean jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", Jackson2ObjectMapperBuilder.class.getClassLoader());// 混合注解类private final Map<Class<?>, Class<?>> mixIns = new LinkedHashMap<>();// 序列化器private final Map<Class<?>, JsonSerializer<?>> serializers = new LinkedHashMap<>();// 反序列化器private final Map<Class<?>, JsonDeserializer<?>> deserializers = new LinkedHashMap<>();private final Map<PropertyAccessor, JsonAutoDetect.Visibility> visibilities = new LinkedHashMap<>();// 特征private final Map<Object, Boolean> features = new LinkedHashMap<>();// 是否创建`XmlMapper`private boolean createXmlMapper = false;// 模块@Nullableprivate List<Module> modules;// JsonFactory@Nullableprivate JsonFactory factory;// 省略.........
3.2 静态方法
它的构造方法是public
的,说明可以直接new
创建Jackson2ObjectMapperBuilder
:
public Jackson2ObjectMapperBuilder() {}
提供了多个创建不同数据类型支持的静态方法:
// 构建 Jackson2ObjectMapperBuilderpublic static Jackson2ObjectMapperBuilder json() {return new Jackson2ObjectMapperBuilder();}// 构建 Jackson2ObjectMapperBuilder,并设置需要创建 XmlMapper,需要引入`jackson-dataformat-xml`模块,用于支持`XML`数据格式public static Jackson2ObjectMapperBuilder xml() {return new Jackson2ObjectMapperBuilder().createXmlMapper(true);}// 指定 JsonFactory-》SmileFactory,需要引入`jackson-dataformat-smile`模块,用于支持`Smile`数据格式public static Jackson2ObjectMapperBuilder smile() {return new Jackson2ObjectMapperBuilder().factory(new SmileFactoryInitializer().create());}// 指定 JsonFactory-》CBORFactory-》需要引入`jackson-dataformat-cbor`模块,用于支持`CBOR`数据格式public static Jackson2ObjectMapperBuilder cbor() {return new Jackson2ObjectMapperBuilder().factory(new CborFactoryInitializer().create());}
一般场景中,使用json()
创建即可:
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build();
3.3 自定义序列化/反序列化器
提供了多个方法用于配置自定义序列化/反序列化器,相较于ObjectMapper
不能直接添加来说,方便了很多。
// 配置自定义序列化器(多个)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;}// 为给定的类型配置自定义的序列化器(单个)public Jackson2ObjectMapperBuilder serializerByType(Class<?> type, JsonSerializer<?> serializer) {this.serializers.put(type, serializer);return this;}// 通过Map给定的类型配置自定义的序列化器(多个)public Jackson2ObjectMapperBuilder serializersByType(Map<Class<?>, JsonSerializer<?>> serializers) {this.serializers.putAll(serializers);return this;}// 添加自定义反序列化器public Jackson2ObjectMapperBuilder deserializers(JsonDeserializer<?>... deserializers) {// 省略.......return this;}// 省略其他类似.......
3.4 模块注册
提供了多个方法用于进行模块注册:
public Jackson2ObjectMapperBuilder modules(Module... modules) {return modules(Arrays.asList(modules));}public Jackson2ObjectMapperBuilder modules(List<Module> modules) {// 省略......return this;}public Jackson2ObjectMapperBuilder modules(Consumer<List<Module>> consumer) {// 省略......return this;}public Jackson2ObjectMapperBuilder modulesToInstall(Module... modules) {// 省略......return this;}// 省略其他类似......
3.5 启用/禁用特征
提供了启用、禁用特征的相关方法:
/*** 启用特征** @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;}
提供了直接配置一些特殊特征的开启/禁用方法:
// MapperFeature#AUTO_DETECT_FIELDSpublic Jackson2ObjectMapperBuilder autoDetectFields(boolean autoDetectFields) {this.features.put(MapperFeature.AUTO_DETECT_FIELDS, autoDetectFields);return this;}// MapperFeature.AUTO_DETECT_GETTERS// MapperFeature.AUTO_DETECT_SETTERS// MapperFeature.AUTO_DETECT_IS_GETTERSpublic 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;}// MapperFeature#DEFAULT_VIEW_INCLUSIONpublic Jackson2ObjectMapperBuilder defaultViewInclusion(boolean defaultViewInclusion) {this.features.put(MapperFeature.DEFAULT_VIEW_INCLUSION, defaultViewInclusion);return this;}// DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIESpublic Jackson2ObjectMapperBuilder failOnUnknownProperties(boolean failOnUnknownProperties) {this.features.put(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, failOnUnknownProperties);return this;}// SerializationFeature#FAIL_ON_EMPTY_BEANSpublic Jackson2ObjectMapperBuilder failOnEmptyBeans(boolean failOnEmptyBeans) {this.features.put(SerializationFeature.FAIL_ON_EMPTY_BEANS, failOnEmptyBeans);return this;}// SerializationFeature#INDENT_OUTPUTpublic Jackson2ObjectMapperBuilder indentOutput(boolean indentOutput) {this.features.put(SerializationFeature.INDENT_OUTPUT, indentOutput);return this;}
3.6 混合注解
提供了直接添加混合注解类(覆盖某个类的注解)的相关方法:
public Jackson2ObjectMapperBuilder mixIn(Class<?> target, Class<?> mixinSource) {this.mixIns.put(target, mixinSource);return this;}public Jackson2ObjectMapperBuilder mixIns(Map<Class<?>, Class<?>> mixIns) {this.mixIns.putAll(mixIns);return this;}
3.7 构建
用于构建一个ObjectMapper
实例,每次调用都会返回一个新的对象,对于处理不同JSON
格式或需要不同序列化/反序列化行为的场景,可以构建新的实例来处理。
@SuppressWarnings("unchecked")public <T extends ObjectMapper> T build() {// 创建实例ObjectMapper mapper;if (this.createXmlMapper) {// 需要创建XmlMapper,则使用 XmlFactorymapper = (this.defaultUseWrapper != null ?new XmlObjectMapperInitializer().create(this.defaultUseWrapper, this.factory) :new XmlObjectMapperInitializer().create(this.factory));} else {// 不需要创建XmlMapper,则使用指定的工厂mapper = (this.factory != null ? new ObjectMapper(this.factory) : new ObjectMapper());}// 配置configure(mapper);return (T) mapper;}
3.8 配置
用于将成员属性都设置给已存在的ObjectMapper
实例:
public void configure(ObjectMapper objectMapper) {Assert.notNull(objectMapper, "ObjectMapper must not be null");// 注册模块MultiValueMap<Object, Module> modulesToRegister = new LinkedMultiValueMap<>();if (this.findModulesViaServiceLoader) {ObjectMapper.findModules(this.moduleClassLoader).forEach(module -> registerModule(module, modulesToRegister));} else if (this.findWellKnownModules : modulesToRegister.values()) {modules.addAll(nestedModules);}objectMapper.registerModules(modules);// 设置时间日期格式化if (this.dateFormat != null) {objectMapper.setDateFormat(this.dateFormat);}// 设置 Localeif (this.locale != null) {objectMapper.setLocale(this.locale);}// 设置 TimeZone 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.configurer != null) {this.configurer.accept(objectMapper);}}
3.9 其他
此外还提供了其他的方法,使用率较低,就不在一一讲解了。
// 是否创建 XmlMapperpublic Jackson2ObjectMapperBuilder createXmlMapper(boolean createXmlMapper) {this.createXmlMapper = createXmlMapper;return this;}// 设置 JsonFactorypublic Jackson2ObjectMapperBuilder factory(JsonFactory factory) {this.factory = factory;return this;}// 设置 DateFormatpublic Jackson2ObjectMapperBuilder dateFormat(DateFormat dateFormat) {this.dateFormat = dateFormat;return this;}// 省略其他..........