- 对于有子父类继承关系的java类,子父类序列化和反序列化经常容易报错
- 报错情况举例:子类序列化,用父类的class进行反序列化
- 原因:反序列化的时候,不清楚具体的类型信息
- 解决:jackson允许配置多态类型处理,通过给类配置注解,添加类型信息,可以使得多态的序列化和反序列化正常运行。
一般由
JsonTypeInfo
和JsonTypeInfo
配合使用public @interface JsonTypeInfo {
//定义使用哪一种类型识别码,可选值在枚举中
JsonTypeInfo.Id use();
//可选,指定识别码是如何被包含进去的,可选值在As枚举中
JsonTypeInfo.As include() default JsonTypeInfo.As.PROPERTY;
//可选,指定识别码的属性名称
String property() default "";
Class<?> defaultImpl() default JsonTypeInfo.class;
boolean visible() default false;
/** @deprecated */
@Deprecated
public abstract static class None {
public None() {
}
}
public static enum As {
PROPERTY,//作为数据的兄弟属性
WRAPPER_OBJECT,//作为一个包装的对象
WRAPPER_ARRAY,//作为一个包装的数组
EXTERNAL_PROPERTY,//作为扩展属性
EXISTING_PROPERTY;//作为POJO中已经存在的属性
private As() {
}
}
//类型识别码的可选值
public static enum Id {
//不使用识别码
NONE((String)null),
//使用完全限定类名做识别
CLASS("@class"),
//若基类和子类在同一包类,使用类名(忽略包名)作为识别码
MINIMAL_CLASS("@c"),
//一个合乎逻辑的指定名称
NAME("@type"),
//自定义识别码
CUSTOM((String)null);
private final String _defaultPropertyName;
private Id(String defProp) {
this._defaultPropertyName = defProp;
}
public String getDefaultPropertyName() {
return this._defaultPropertyName;
}
}
- 另一种解决方式是,全局Default Typing机制
开启DefaultTyping,并且让所有的非final类型对象持久化时都存储类型信息,显然能准确的反序列多态类型的数据。
- Jackson里使用@JsonTypeInfo注解处理多态类型的序列化和反序列化