0

我正在序列化和反序列化一个包含两个对象的列表,在那里有循环引用。

首先,我尝试ObjectIdGenerators.StringIdGenerator作为生成器。

//Using latest version for the dependencies
//jackson.version = 2.13.1
//jackson-jsog = 1.1.2

    @NoArgsConstructor
    @JsonIdentityInfo(generator = ObjectIdGenerators.StringIdGenerator.class)
    public static class Outer {
        @Setter
        @Getter
        private Inner inner;
    }

    @NoArgsConstructor
    @JsonIdentityInfo(generator = ObjectIdGenerators.StringIdGenerator.class)
    public static class Inner {

        @Getter
        private Outer outer;

        public Inner(Outer outer) {
            this.outer = outer;
            outer.setInner(this);
        }
    }

public static void main(String[] args) throws Exception {
        // There are circular references between Outer and Inner
        Outer outer = new Outer();
        Inner inner = new Inner(outer);
        // Turn on type info
        PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().allowIfSubType(Object.class).build();
        ObjectMapper mapper = new ObjectMapper()
                .activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.EVERYTHING,
                        JsonTypeInfo.As.PROPERTY);

        List<Object> source = Lists.newArrayList(outer, inner);
        String json = mapper.writeValueAsString(source);
        System.out.println(json);
        //This is the json serialized by StringIdGenerator, which doesn't make sense for the second instance(no type info there,just a UUID)
        //See below
        List<Object> target = mapper.readerForListOf(Object.class).readValue(json);
        System.out.println(target);
        //So I finally got an Outer instance and a string in the target list, not equal to source list at all
        //[com.foo.bar.SomeTest$Outer@4b29d1d2, acb5231d-13de-4e22-92c6-cb1ec0530de1]

    }

这是由 StringIdGenerator 序列化的 json,对于第二个实例没有意义(那里没有类型信息,只有一个 UUID)

[
    "java.util.ArrayList",
    [
        {
            "@class": "com.foo.bar.SomeTest$Outer",
            "@id": "df6ed346-6b27-4983-8dc2-5c07ddfa8f8f",
            "inner":
            {
                "@class": "com.foo.bar.SomeTest$Inner",
                "@id": "acb5231d-13de-4e22-92c6-cb1ec0530de1",
                "outer": "df6ed346-6b27-4983-8dc2-5c07ddfa8f8f"
            }
        },
        "acb5231d-13de-4e22-92c6-cb1ec0530de1"
    ]
]

然后我尝试了JSOGGenerator


    @NoArgsConstructor
    @JsonIdentityInfo(generator = JSOGGenerator.class)
    public static class Outer {
        @Setter
        @Getter
        private Inner inner;
    }

    @NoArgsConstructor
    @JsonIdentityInfo(generator = JSOGGenerator.class)
    public static class Inner {

        @Getter
        private Outer outer;

        public Inner(Outer outer) {
            this.outer = outer;
            outer.setInner(this);
        }
    }

    public static void main(String[] args) throws Exception {
        // There are circular references between Outer and Inner
        Outer outer = new Outer();
        Inner inner = new Inner(outer);
        // Turn on type info
        PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().allowIfSubType(Object.class).build();
        ObjectMapper mapper = new ObjectMapper()
                .activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.EVERYTHING,
                        JsonTypeInfo.As.PROPERTY);

        List<Object> source = Lists.newArrayList(outer, inner);
        String json = mapper.writeValueAsString(source);
        System.out.println(json);
        //This is the json serialized by JSOGGenerator, which does make sense
        //See below
        List<Object> target = mapper.readerForListOf(Object.class).readValue(json);
        //However, I got an InvalidTypeIdException while deserializing
        //Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve subtype of [simple type, class com.voodoodyne.jackson.jsog.JSOGRef]: missing type id property '@class'

    }


这是JSOGGenerator序列化的json,确实有道理。


[
    "java.util.ArrayList",
    [
        {
            "@class": "com.foo.bar.SomeTest$Outer",
            "@id": "1",
            "inner":
            {
                "@class": "com.foo.bar.SomeTest$Inner",
                "@id": "2",
                "outer":
                {
                    "@ref": "1"
                }
            }
        },
        {
            "@ref": "2"
        }
    ]
]

但是,我有一段InvalidTypeIdException时间反序列化。而且我发现属性“@id”没有正确处理。

ObjectIdValueProperty._valueDeserializer._baseType,这是哪种类型JSOGRef,它不能将“1”(字符串)解析为对象 id 值。

我的问题

  • 处理这个问题的正确方法是什么?
  • 我们有其他的发电机可以尝试吗?
4

0 回答 0