有道无术,术尚可求,有术无道,止于术。
本系列Jackson 版本 2.17.0
源码地址:https://gitee.com/pearl-organization/study-jaskson-demo
文章目录
- 1. 概述
- 2. 方法
- 2.1 构造
- 2.2 反序列化
- 2.3 null 处理
- 2.4 空值
- 2.5 其他
- 3. 实现类
- 3.1 StdDeserializer
- 3.1.1 成员属性
- 3.1.2 构造
- 3.1.3 反序列化
- 3.1.4 辅助方法
- 3.1.5 实现类
- 3.2 None
- 3.3 TypeWrappedDeserializer
- 3.4 AbstractDeserializer
- 3.5 ErrorThrowingDeserializer
1. 概述
JsonDeserializer
是一个用于将JSON
反序列化为任意类型的对象的抽象类,是Jackson
中的重要组件之一。
2. 方法
JsonDeserializer
声明了很多方法。
2.1 构造
Fluent
风格的工厂方法用于构建经过装饰或增强的对象(和JsonSerializer
类似)。
public JsonDeserializer<T> unwrappingDeserializer(NameTransformer unwrapper) {
return this;
}
public JsonDeserializer<?> replaceDelegatee(JsonDeserializer<?> delegatee) {
throw new UnsupportedOperationException();
}
2.2 反序列化
声明了核心的反序列化方法:
/**
* 反序列化
*
* @param p Json解析器
* @param ctxt 反序列化上下文
* @return 反序列化后的对象
*/
public abstract T deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JacksonException;
/**
* 反序列化
*
* @param p Json解析器
* @param ctxt 反序列化上下文
* @param intoValue 已经初始化的值实例
* @return 反序列化后的对象
*/
public T deserialize(JsonParser p, DeserializationContext ctxt, T intoValue)
throws IOException, JacksonException {
ctxt.handleBadMerge(this);
return deserialize(p, ctxt);
}
/**
* 反序列化
*
* @param p Json解析器
* @param ctxt 反序列化上下文
* @param typeDeserializer 反序列化类型
* @return 反序列化后的对象
*/
public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException, JacksonException {
// We could try calling
return typeDeserializer.deserializeTypedFromAny(p, ctxt);
}
/**
* 反序列化
*
* @param p Json解析器
* @param ctxt 反序列化上下文
* @param typeDeserializer 反序列化类型
* @param intoValue 已经初始化的值实例
* @return 反序列化后的对象
*/
public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
TypeDeserializer typeDeserializer, T intoValue)
throws IOException, JacksonException {
ctxt.handleBadMerge(this);
return deserializeWithType(p, ctxt, typeDeserializer);
}
2.3 null 处理
JSON
中的null
值在反序列时,需要一种可控和可预测的方式确定应该使用什么值来表示这个null
,对于引用类型(如对象或数组),通常直接使用Java
的null
。但对于原始数据类型(如int
、double
等),Java
没有null
的概念,因此需要一个特殊的策略来处理这种情况。
JsonDeserializer
声明了处理null
的方法:
/**
* 处理null,默认返回null
*/
@Override
public T getNullValue(DeserializationContext ctxt) throws JsonMappingException {
// Change the direction in 2.7
return getNullValue(); // 返回null
}
/**
* 处理null,getNullValue(DeserializationContext)方法的优化版
* 当getNullValue返回的值是静态的时,反序列化器可以缓存这个值,避免在每次需要时都重新计算。
*/
@Override
public AccessPattern getNullAccessPattern() {
// Default implementation assumes that the null value does not vary, which
// is usually the case for most implementations. But it is not necessarily
// `null`; so sub-classes may want to refine further.
return AccessPattern.CONSTANT;
}
/**
* 确定在没有从输入中获得值但需要传递值时所使用的占位符值。
* 目的:该方法用于处理一种特定情况,即当创建者(Creator)方法需要为每个参数传递一个值,但输入中并没有提供值时,我们需要提供一个占位符值。
* 常见情况:创建者方法通常指的是构造函数、工厂方法或其他用于创建对象实例的方法。这些方法可能要求为所有参数提供值,即使某些值在输入数据中并不存在。
* 占位符值:占位符值用于替代缺失的输入值。它通常与getNullValue方法返回的值相同(这通常就是Java的null),但对于特定类型,可能需要使用不同的“默认值”。
* 特定类型:对于某些类型(特别是原始数据类型或不能设置为null的类型),使用null作为占位符值是不合适的。因此,对于这些类型,可能需要重写此方法以提供适当的默认值(例如,对于整数类型,可能是0;对于布尔类型,可能是false等)。
* 调用频率:该方法每次需要确定占位符值时都会被调用。这意味着,在创建对象实例时,对于每个缺失的输入值,都可能调用此方法。
* 默认实现:该方法的默认实现是简单地调用getNullValue方法并返回其结果。这意味着,在大多数情况下,占位符值将与null值相同,除非特定类型重写了此方法。
*
* @since 2.13
*/
@Override
public Object getAbsentValue(DeserializationContext ctxt) throws JsonMappingException {
return getNullValue(ctxt);
}
2.4 空值
/**
* 空值处理
*/
public Object getEmptyValue(DeserializationContext ctxt) throws JsonMappingException {
return getNullValue(ctxt);
}
/**
* 检查是否需要仅调用一次(静态值),或者每次需要空值时都调用。
*
* @since 2.9
*/
public AccessPattern getEmptyAccessPattern() {
return AccessPattern.DYNAMIC;
}
2.5 其他
/**
* 获取处理类型
*
* @since 2.3
*/
public Class<?> handledType() {
return null;
}
/**
* 获取生成值的逻辑类型
*/
public LogicalType logicalType() {
return null;
}
/**
* 检查反序列化器实例是否可缓存,并可用于相同类型(创建实例的类型)的其他属性
*/
public boolean isCachable() {
return false;
}
/**
* 获取代理的反序列化器
*
* @since 2.1
*/
public JsonDeserializer<?> getDelegatee() {
return null;
}
/**
* 获取属性名称,仅用于错误报告和诊断目的
*
* @since 2.0
*/
public Collection<Object> getKnownPropertyNames() {
return null;
}
/**
* 获取对象标识符值,将其解析为实际的对象实例,并返回为反序列化值。
* @since 2.0
*/
public ObjectIdReader getObjectIdReader() {
return null;
}
/**
* 供 BeanDeserializerFactory 用于处理循环引用问题
*/
public SettableBeanProperty findBackReference(String refName) {
throw new IllegalArgumentException("Cannot handle managed/back reference '" + refName
+ "': type: value deserializer of type " + getClass().getName() + " does not support them");
}
/**
* 查看反序列化器是否支持现有值的更新(也称为“合并”)功能(@JavaMerge)
*
* @since 2.9
*/
public Boolean supportsUpdate(DeserializationConfig config) {
return null;
}
3. 实现类
JsonDeserializer
有很多的实现类,用于处理各种数据类型。
3.1 StdDeserializer
StdDeserializer
即标准的反序列化器,也是一个抽象类,是在JsonDeserializer
的基础上封装了一些通用方法,实现反序列化器时,应该继承该类,而不是JsonDeserializer
。
3.1.1 成员属性
掩码(Bitmask
)是一种位操作技术,它允许通过单个整数值来同时设置、检查或清除多个标志位。Jackson
允许使用掩码在单个操作中检查多个特性,从而提高性能。
F_MASK_INT_COERCIONS
声明的掩码用于于覆盖两个特定的反序列化特性:USE_BIG_INTEGER_FOR_INTS
和 USE_LONG_FOR_INTS
:
protected final static int F_MASK_INT_COERCIONS =
DeserializationFeature.USE_BIG_INTEGER_FOR_INTS.getMask()
| DeserializationFeature.USE_LONG_FOR_INTS.getMask();
StdDeserializer
还提供了两个成员属性,描述当前处理的值类型和Java
对象的类型,便于正确地将JSON
数据转换为Java
对象:
// 反序列化器处理的值类型
final protected Class<?> _valueClass;
// Java对象的类型信息
final protected JavaType _valueType;
3.1.2 构造
StdDeserializer
构造函数则比较简单,主要是对成员属性进行赋值:
protected StdDeserializer(Class<?> vc) {
_valueClass = vc;
_valueType = null;
}
protected StdDeserializer(JavaType valueType) {
// 26-Sep-2017, tatu: [databind#1764] need to add null-check back until 3.x
_valueClass = (valueType == null) ? Object.class : valueType.getRawClass();
_valueType = valueType;
}
protected StdDeserializer(StdDeserializer<?> src) {
_valueClass = src._valueClass;
_valueType = src._valueType;
}
3.1.3 反序列化
StdDeserializer
提供了一个不特定的类型反序列化方法,子类需要处理类型信息时,需要重写该方法:
@Override
public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
TypeDeserializer typeDeserializer) throws IOException {
return typeDeserializer.deserializeTypedFromAny(p, ctxt);
}
此外还提供了很多特定类型的反序列化方法:
protected T _deserializeFromArray(JsonParser p, DeserializationContext ctxt)
protected T _deserializeFromString(JsonParser p, DeserializationContext ctxt)
protected T _deserializeFromString(JsonParser p, DeserializationContext ctxt)
protected T _deserializeWrappedValue(JsonParser p, DeserializationContext ctxt)
protected final boolean _parseBooleanPrimitive(DeserializationContext ctxt, JsonParser p, Class<?> targetType)
protected final Boolean _parseBoolean(JsonParser p, DeserializationContext ctxt, Class<?> targetType)
protected final short _parseShortPrimitive(JsonParser p, DeserializationContext ctxt)
protected final int _parseIntPrimitive(JsonParser p, DeserializationContext ctxt)
protected final int _parseIntPrimitive(DeserializationContext ctxt, String text)
protected final int _parseIntPrimitive(DeserializationContext ctxt, String text)
protected final Integer _parseInteger(JsonParser p, DeserializationContext ctxt,Class<?> targetType)
protected final Integer _parseInteger(DeserializationContext ctxt, String text)
protected final long _parseLongPrimitive(JsonParser p, DeserializationContext ctxt)
protected final long _parseLongPrimitive(DeserializationContext ctxt, String text)
protected final Long _parseLong(JsonParser p, DeserializationContext ctxt, Class<?> targetType)
protected final Long _parseLong(DeserializationContext ctxt, String text)
//......................
3.1.4 辅助方法
检查特殊字符串的相关方法:
// 字符串值 "null",并且进一步确定是否应将其强制转换为 null
protected boolean _hasTextualNull(String value) {
return "null".equals(value);
}
protected final boolean _isNegInf(String text) {
return "-Infinity".equals(text) || "-INF".equals(text);
}
protected final boolean _isPosInf(String text) {
return "Infinity".equals(text) || "INF".equals(text);
}
protected final boolean _isNaN(String text) {
return "NaN".equals(text);
}
也提供了很多辅助方法,用于校验、查询、判断等,供子类直接调用(太多,这里只列举几个):
protected Object _coerceIntegral(JsonParser p, DeserializationContext ctxt) throws IOException {
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS)) {
return p.getBigIntegerValue();
} else {
return ctxt.isEnabled(DeserializationFeature.USE_LONG_FOR_INTS) ? p.getLongValue() : p.getNumberValue();
}
}
protected final void _verifyNullForPrimitive(DeserializationContext ctxt) throws JsonMappingException {
if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)) {
ctxt.reportInputMismatch(this, "Cannot coerce `null` to %s (disable `DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES` to allow)", new Object[]{this._coercedTypeDesc()});
}
}
3.1.5 实现类
StdDeserializer
也包含了多个子实现类,和JsonSerializer
类似,只不过是用于反序列化,这里就不再详细解析每个子类了:
3.2 None
和JsonSerializer.None
作用一样,是@JsonDeserializer
的标记类
3.3 TypeWrappedDeserializer
和TypeWrappedSerializer
一样,基于包装模式实现。
3.4 AbstractDeserializer
AbstractDeserializer
是一个仅用于处理处理反序列化过程中的多态类型的抽象类。
3.5 ErrorThrowingDeserializer
ErrorThrowingDeserializer
用于存储在构建反序列化器过程中捕获的 {@link Error}
,该错误需要被延迟处理,直到实际尝试反序列化给定类型的值时。