有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

无类型信息子类的java反序列化

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

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中相应的属性类型推断出来的

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

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


共 (1) 个答案

  1. # 1 楼答案

    在这种情况下,您可以使用字段名来区分类型,而不必依赖工厂或其他任何东西。这里我假设名为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\": null\n"
                    + "}";
    
            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被正确反序列化