有道无术,术尚可求,有术无道,止于术。
本系列Jackson 版本 2.17.0
源码地址:https://gitee.com/pearl-organization/study-jaskson-demo
文章目录
- 1. 概述
- 2. 方法
- 2.1 构造
- 2.2 序列化
- 2.3 其他
- 3. 实现类
- 3.1 StdSerializer
- 3.1.1 源码
- 3.1.2 ContainerSerializer
- 3.1.3 ToStringSerializerBase
- 3.1.4 NullSerializer
- 3.1.5 BeanSerializerBase
- 3.2 None
- 3.3 TypeWrappedSerializer
1. 概述
JsonSerializer
是一个用于序列化Java
对象为JSON
的抽象类,是Jackson
中的重要组件之一。
2. 方法
JsonSerializer
没有成员属性,但是声明了很多方法。
2.1 构造
Fluent
风格的工厂方法用于构建经过装饰或增强的序列化器对象。
/*** 未包装的序列化器对象** @param unwrapper 用于在包装器属性名称之间转换的名称转换器*/public JsonSerializer<T> unwrappingSerializer(NameTransformer unwrapper) {return this;}/*** 用于尝试替换此序列化器所委托调用的序列化器,如果不支持,则应抛出 {@link UnsupportedOperationException}或者直接返回此序列化器本身。** @since 2.1*/public JsonSerializer<T> replaceDelegatee(JsonSerializer<?> delegatee) {throw new UnsupportedOperationException();}/*** 支持过滤的子类,如果过滤器发生变化,则需要创建并返回新的实例。** @since 2.6*/public JsonSerializer<?> withFilterId(Object filterId) {return this;}/*** 用于在排除指定名称的属性集后创建新的实例(如果存在的话)** @param ignoredProperties 忽略序列化的一组属性名称* @return 序列化器实例,它不会忽略指定的属性集(如果存在的话)* @since 2.16*/public JsonSerializer<?> withIgnoredProperties(Set<String> ignoredProperties) {return this;}
2.2 序列化
序列化是将对象状态转换为可以存储或传输的形式的过程,JsonGenerator
声明了两个序列化方法,这是我们需要关注的重点。
/*** 序列化** @param value 要序列化的值,不能为null* @param gen 用于输出Json内容的生成器* @param serializers 提供者,可用于获取序列化包含在值中的对象所需的序列化器(如果有的话)*/public abstract void serialize(T value, JsonGenerator gen, SerializerProvider serializers) throws IOException;/*** 使用指定的类型序列化器来序列化** @param value 要序列化的值,不能为null* @param gen 用于输出Json内容的生成器* @param serializers 提供者,可用于获取序列化包含在值中的对象所需的序列化器(如果有的话)* @param typeSer 指定的类型序列化器*/public void serializeWithType(T value, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException {Class<?> clz = handledType();if (clz == null) {clz = value.getClass();}serializers.reportBadDefinition(clz, String.format("Type id handling not implemented for type %s (by serializer of type %s)", clz.getName(), getClass().getName()));}
2.3 其他
其他的一些方法,了解即可。
/*** 获取序列化器可以处理的对象类型*/public Class<T> handledType() {return null;}/*** 检查可序列化值是否被视为“空”值(用于抑制空值的序列化)。** @deprecated 自2.5版本起,请使用 {@link #isEmpty(SerializerProvider, Object)} 替代,在3.0版本中将被移除。*/@Deprecatedpublic boolean isEmpty(T value) {return isEmpty(null, value);}/*** 检查可序列化值是否被视为“空”值(用于抑制空值的序列化)。** @since 2.5*/public boolean isEmpty(SerializerProvider provider, T value) {return (value == null);}/*** 查询此序列化器实例是否将使用ObjectId来处理循环引用。*/public boolean usesObjectId() {return false;}/*** 用于检查此序列化器是否为“解包”序列化器*/public boolean isUnwrappingSerializer() {return false;}/*** 用于确定此序列化器是否通过使用另一个序列化器进行实际序列化(通过委托调用),如果是,则返回该序列化器,否则返回null。** @since 2.1*/public JsonSerializer<?> getDelegatee() {return null;}/*** 迭代此序列化器所处理类型的逻辑属性。** @since 2.6*/public Iterator<PropertyWriter> properties() {return ClassUtil.emptyIterator();}/*** 默认实现只是调用 {@link JsonFormatVisitorWrapper#expectAnyFormat(JavaType)}。** @since 2.1*/@Overridepublic void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type) throws JsonMappingException {visitor.expectAnyFormat(type);}
3. 实现类
JsonSerializer
有很多的实现类,用于处理各种数据类型。
3.1 StdSerializer
StdSerializer
即标准的序列化器,也是一个抽象类,是在JsonSerializer
的基础上封装了一些通用方法,实现序列化器时,应该继承该类,而不是JsonSerializer
。
3.1.1 源码
StdSerializer
声明了两个成员属性和一些构造方法:
/*** 用于存储锁对象的键,以防止在构造转换序列化器时发生无限递归** @since 2.9*/private final static Object KEY_CONTENT_CONVERTER_LOCK = new Object();/*** 支持的类型,通常是所使用的序列化器对应属性的声明类型。*/protected final Class<T> _handledType;protected StdSerializer(Class<T> t) {_handledType = t;}@SuppressWarnings("unchecked")protected StdSerializer(JavaType type) {_handledType = (Class<T>) type.getRawClass();}/*** 用来解决泛型类型处理中的一些问题*/@SuppressWarnings("unchecked")protected StdSerializer(Class<?> t, boolean dummy) {_handledType = (Class<T>) t;}/*** @since 2.6*/@SuppressWarnings("unchecked")protected StdSerializer(StdSerializer<?> src) {_handledType = (Class<T>) src._handledType;}
核心的序列化方法任然是抽象的,需要子类去实现:
@Overridepublic abstract void serialize(T value, JsonGenerator gen, SerializerProvider provider)throws IOException;
提供了很多辅助方法,供子类调用,例如用于标识底层JSON
类型的方法:
/*** 辅助方法,用于调用必要的访问方法,以指示底层JSON类型为JSON字符串。** @since 2.7*/protected void visitStringFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint)throws JsonMappingException {/*JsonStringFormatVisitor v2 =*/visitor.expectStringFormat(typeHint);}/*** 辅助方法,用于调用必要的访问方法,以指示底层JSON类型为JSON字符串,但存在更精细的逻辑类型。** @since 2.7*/protected void visitStringFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint,JsonValueFormat format)throws JsonMappingException {JsonStringFormatVisitor v2 = visitor.expectStringFormat(typeHint);if (v2 != null) {v2.format(format);}}/*** 辅助方法,用于调用必要的访问方法,以指示底层JSON类型为JSON整数。** @since 2.7*/protected void visitIntFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint,NumberType numberType)throws JsonMappingException {JsonIntegerFormatVisitor v2 = visitor.expectIntegerFormat(typeHint);if (_neitherNull(v2, numberType)) {v2.numberType(numberType);}}/*** 辅助方法,用于调用必要的访问方法,以指示底层JSON类型为JSON整数,但还涉及进一步的格式限制。** @since 2.7*/protected void visitIntFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint,NumberType numberType, JsonValueFormat format)throws JsonMappingException {JsonIntegerFormatVisitor v2 = visitor.expectIntegerFormat(typeHint);if (v2 != null) {if (numberType != null) {v2.numberType(numberType);}if (format != null) {v2.format(format);}}}/*** 辅助方法,用于调用必要的访问方法,以指示底层JSON类型为浮点型JSON数字。** @since 2.7*/protected void visitFloatFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint,NumberType numberType)throws JsonMappingException {JsonNumberFormatVisitor v2 = visitor.expectNumberFormat(typeHint);if (v2 != null) {v2.numberType(numberType);}}/*** @since 2.7*/protected void visitArrayFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint,JsonSerializer<?> itemSerializer, JavaType itemType)throws JsonMappingException {JsonArrayFormatVisitor v2 = visitor.expectArrayFormat(typeHint);if (_neitherNull(v2, itemSerializer)) {v2.itemsFormat(itemSerializer, itemType);}}/*** @since 2.7*/protected void visitArrayFormat(JsonFormatVisitorWrapper visitor, JavaType typeHint,JsonFormatTypes itemType)throws JsonMappingException {JsonArrayFormatVisitor v2 = visitor.expectArrayFormat(typeHint);if (v2 != null) {v2.itemsFormat(itemType);}}
用于包装处理异常的辅助方法:
public void wrapAndThrow(SerializerProvider provider,Throwable t, Object bean, String fieldName)throws IOException { //..............}public void wrapAndThrow(SerializerProvider provider,Throwable t, Object bean, int index)throws IOException {//..............}
和注解相关的辅助方法:
/*** 用于检查指定的属性是否具有指示需要对包含的值(结构化类型的内容;数组/列表/映射值)使用转换器的注解。*/protected JsonSerializer<?> findContextualConvertingSerializer(SerializerProvider provider,BeanProperty property, JsonSerializer<?> existingSerializer)throws JsonMappingException { //..............}/*** 根据 ID 查询 PropertyFilter*/protected PropertyFilter findPropertyFilter(SerializerProvider provider,Object filterId, Object valueToFilter)throws JsonMappingException {//..............}/*** 辅助方法,可用于查找此反序列化器是否具有特定的 {@link JsonFormat} 设置*/protected JsonFormat.Value findFormatOverrides(SerializerProvider provider,BeanProperty prop, Class<?> typeForDefaults) {//..............}/*** 查找JsonFormat.Feature特性是否已被特别标记为启用或禁用*/protected Boolean findFormatFeature(SerializerProvider provider,BeanProperty prop, Class<?> typeForDefaults, JsonFormat.Feature feat) {//..............}/*** 查找是否包含@JsonInclude.Value*/protected JsonInclude.Value findIncludeOverrides(SerializerProvider provider,BeanProperty prop, Class<?> typeForDefaults) {//..............}/*** 辅助方法,用于查找可能已配置的内容值序列化器。*/protected JsonSerializer<?> findAnnotatedContentSerializer(SerializerProvider serializers,BeanProperty property)throws JsonMappingException {//..............}
3.1.2 ContainerSerializer
Jackson
默认提供了很多StdSerializer
的实现类:
这里挑出一些常用的进行讲解,首先是ContainerSerializer
,可以直接看出是用于集合类型的序列化:
示例,在序列化List<T>
时,调用的是IndexedListSerializer
:
JsonMapper jsonMapper = JsonMapper.builder().build();List<String> list=new ArrayList<>();list.add("haha");list.add("heihei");String jsonValue = jsonMapper.writeValueAsString(list);System.out.println(jsonValue);
3.1.3 ToStringSerializerBase
ToStringSerializerBase
用于将值序列化为字符串,支持BigDecimal
、ZoneId
、String
类型:
3.1.4 NullSerializer
NullSerializer
用于序列化null
值,可以看到直接调用了JsonGenerator.writeNull()
方法,JSON
中直接使用null
表示:
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {gen.writeNull();}public void serializeWithType(Object value, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException {gen.writeNull();}
3.1.5 BeanSerializerBase
BeanSerializerBase
是一个用于序列化JavaBean
对象的基础类,提供了一些可重用且可扩展的方法,开发者可以只注重于实现自定义的序列化逻辑。
BeanSerializerBase
会处理 JavaBean
的一些通用特性,如属性的访问(通过 getter
和 setter
方法)、属性的过滤(基于注解或其他配置)、属性的排序等。
其包含了几个实现类,其中BeanSerializer
是标准实现:
3.2 None
None
是JsonSerializer
的一个内部抽象类,用于标识@JsonSerialize
注解,明确表示不使用任何特定的序列化器,而是使用默认的序列化机制。
/*** 注解 {@link com.fasterxml.jackson.databind.annotation.JsonSerialize} 的标记*/
public abstract static class None extends JsonSerializer<Object> {
}
@JsonSerialize
中可以看到默认用的None
,表示没有指定序列化器(使用默认的):
@JacksonAnnotation
public @interface JsonSerialize {Class<? extends JsonSerializer> using() default JsonSerializer.None.class;//.......
3.3 TypeWrappedSerializer
TypeWrappedSerializer
类型包装序列化器,可以看到有一个TypeSerializer
和一个JsonSerializer
属性,序列化都是调用JsonSerializer
的serializeWithType
方法。
很好理解,这是一个包装模式,包装JsonSerializer
使用指定的TypeSerializer
进行序列化。
protected final TypeSerializer _typeSerializer;protected final JsonSerializer<Object> _serializer;public void serialize(Object value, JsonGenerator g, SerializerProvider provider) throws IOException {this._serializer.serializeWithType(value, g, provider, this._typeSerializer);}public void serializeWithType(Object value, JsonGenerator g, SerializerProvider provider, TypeSerializer typeSer) throws IOException {this._serializer.serializeWithType(value, g, provider, typeSer);}