有道无术,术尚可求,有术无道,止于术。
本系列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;}// 省略其他..........