没有类型信息的子类的反序列化



我有一个表示有限域值的类(类似于枚举):

public abstract class AbstractEnum {
private String id;
// ...
}

和具体的类EnumA, EnumB扩展AbstractEnum. 业务对象可能如下所示

public class Obj {
private EnumA a;
private EnumB b;
// ...
}

EnumA, EnumB的实例由工厂管理。当反序列化一个Obj时,我想调用工厂而不是构造函数。具体类型(EnumAEnumB)不能从枚举值的JSON表示中推断出来,因为它们只包含它们的ID,而是从Obj中相应的属性类型推断出来的。

我尝试在AbstractEnum上使用@JsonCreator@JsonDeserialize(带转换器),但创建者/转换器似乎无法使用属性类型。似乎我必须使用@JsonTypeInfo来序列化额外的类型信息(这似乎是多余的),或者为每个具体的AbstractEnum子类定义一个创建者/转换器,其中不止两个。 还有别的办法吗?

编辑EnumA的实例可以与EnumB的实例具有相同的ID,因此ID不能用于推断类型。

可能是您可以使用字段名称来区分类型,而不必依赖工厂或其他任何内容。 我在这里假设名为a的字段将始终引用类型EnumA等等。 下面是一些测试代码,它使用您的代码并尝试显示字段名称本身就可以解决问题。

public class SpikeJson {
public static abstract class AbstractEnum {
private final String id;
protected AbstractEnum(String id) {
this.id = id;
}
@Override
public String toString() {
return "AbstractEnum{" + "id=" + id + '}';
}
}
public static class EnumA extends AbstractEnum {
public EnumA() {
super("enuma");
}
}
public static class EnumB extends AbstractEnum {
public EnumB() {
super("enumb");
}
}
public static class EnumC extends AbstractEnum {
public EnumC() {
super("enumc");
}
}
public static class Obj {
@JsonProperty
private EnumA a;
@JsonProperty
private EnumB b;
@JsonProperty
private EnumC c;
@Override
public String toString() {
return "Obj{" + "a=" + a + ", b=" + b + ", c=" + c + '}';
}
}
public static void main(String[] args) throws IOException {
//{
//  "a": {},
//  "b": null
//}
String json = "{n"
+ " "a": {},n"
+ " "b": nulln"
+ "}";
ObjectMapper om = new ObjectMapper();
Obj obj = om.readValue(json, Obj.class);
System.out.println("obj = " + obj);
}
}

此代码的输出为

obj = Obj{a=AbstractEnum{id=enuma}, b=null, c=null}

这表明 JSON 已正确反序列化。

我按照此处的建议使用ContextualDeserializer解决了它:createContextual()中,我获取具体类,deserialize()中,我调用我的工厂以获取基于targetClass和ID的实例。

最新更新