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

时间:2018-02-03 15:07:32

标签: java jackson

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

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

和扩展EnumA, EnumB的具体课程AbstractEnum。 业务对象可能看起来像

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

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

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

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

2 个答案:

答案 0 :(得分:0)

可能是您可以使用字段名来区分类型,而不必依赖工厂或其他任何东西。我在这里假设名为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\": null\n" + "}"; ObjectMapper om = new ObjectMapper(); Obj obj = om.readValue(json, Obj.class); System.out.println("obj = " + obj); } } ,依此类推。下面是一些测试代码,它使用您的代码并尝试单独显示字段名称可能会起作用。

{{1}}

此代码的输出是

  

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

表明JSON已正确反序列化。

答案 1 :(得分:0)

我按照建议here使用ContextualDeserializer解决了问题:在createContextual()中我抓住了具体的类,在deserialize()中我调用我的工厂来获取基于{的实例{1}}和ID。