美文网首页
Jackson 类路径变更后的反序列化

Jackson 类路径变更后的反序列化

作者: 蓝笔头 | 来源:发表于2021-08-27 09:55 被阅读0次

    需引入 Jackson 依赖,可参考 Jackson 使用简介

    @JsonTypeInfo 序列化

    1)定义序列化结构

    @Data
    public class LiveLesson {
        public static final TypeReference<Container> ITEMS_TYPE = new TypeReference<Container>() {
        };
    
        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        public static class Container {
            private List<Item> items;
        }
    
        @JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS)
        public interface Item {
        }
    
        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        public static class Item1 implements Item {
            private long id;
            private String item1Name;
        }
    
        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        public static class Item2 implements Item {
            private long id;
            private String item2Name;
        }
    }
    

    2)测试代码

    public class TestMain {
        public static void main(String[] args) {
            List<LiveLesson.Item> items = new ArrayList<>();
    
            items.add(new LiveLesson.Item1(1, "Item1"));
            items.add(new LiveLesson.Item2(2, "Item2"));
    
            LiveLesson.Container container = new LiveLesson.Container(items);
    
            System.out.println(serialize(items));
            System.out.println(serialize(container));
    
        }
    
        private static final ObjectMapper objectMapper = new ObjectMapper();
    
        @SneakyThrows
        public static String serialize(Object obj) {
            return objectMapper.writeValueAsString(obj);
        }
    }
    

    控制台输出:

    [{"id":1,"item1Name":"Item1"},{"id":2,"item2Name":"Item2"}]
    {"items":[{"@c":".LiveLesson$Item1","id":1,"item1Name":"Item1"},{"@c":".LiveLesson$Item2","id":2,"item2Name":"Item2"}]}
    

    可以发现不通过类进行包裹的话,序列化后不会出现 @c 字段。

    @JsonTypeInfo 反序列化

    public class TestMain {
        public static void main(String[] args) {
            List<LiveLesson.Item> items = new ArrayList<>();
    
            items.add(new LiveLesson.Item1(1, "Item1"));
            items.add(new LiveLesson.Item2(2, "Item2"));
    
            LiveLesson.Container container = new LiveLesson.Container(items);
            String serialize = serialize(container);
            System.out.println(serialize);
    
            LiveLesson.Container newContainer = deserialize(serialize, LiveLesson.ITEMS_TYPE);
            System.out.println(serialize(newContainer));
        }
    
        private static final ObjectMapper objectMapper = new ObjectMapper();
    
        @SneakyThrows
        public static String serialize(Object obj) {
            return objectMapper.writeValueAsString(obj);
        }
    
        @SneakyThrows
        public static <T> T deserialize(String json, TypeReference<T> valueTypeRef) {
            return objectMapper.readValue(json, valueTypeRef);
        }
    }
    

    控制台输出:

    {"items":[{"@c":".LiveLesson$Item1","id":1,"item1Name":"Item1"},{"@c":".LiveLesson$Item2","id":2,"item2Name":"Item2"}]}
    {"items":[{"@c":".LiveLesson$Item1","id":1,"item1Name":"Item1"},{"@c":".LiveLesson$Item2","id":2,"item2Name":"Item2"}]}
    

    变更路径后的反序列化

    1)定义反序列化结构

    除了 LiveLesson 变更为 LiveLessonInfo,其他的结构和上面的一样。

    @Data
    public class LiveLessonInfo {
        public static final TypeReference<Container> ITEMS_TYPE = new TypeReference<Container>() {
        };
    
        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        public static class Container {
            private List<Item> items;
        }
    
        @JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS)
        public interface Item {
        }
    
        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        public static class Item1 implements Item {
            private long id;
            private String item1Name;
        }
    
        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        public static class Item2 implements Item {
            private long id;
            private String item2Name;
        }
    }
    

    2)测试代码

        public static void main(String[] args) {
            List<LiveLesson.Item> items = new ArrayList<>();
    
            items.add(new LiveLesson.Item1(1, "Item1"));
            items.add(new LiveLesson.Item2(2, "Item2"));
    
            LiveLesson.Container container = new LiveLesson.Container(items);
            String serialize = serialize(container);
            System.out.println(serialize);
    
            // LiveLesson.ITEMS_TYPE 修改为 LiveLessonInfo.ITEMS_TYPE
            LiveLesson.Container newContainer = deserialize(serialize, LiveLesson.ITEMS_TYPE);
            System.out.println(serialize(newContainer));
        }
    

    控制台输出:

    {"items":[{"@c":".LiveLesson$Item1","id":1,"item1Name":"Item1"},{"@c":".LiveLesson$Item2","id":2,"item2Name":"Item2"}]}
    Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'org.company.jackson.LiveLesson$Item1' as a subtype of `org.company.jackson.LiveLessonInfo$Item`: Not a subtype
     at [Source: (String)"{"items":[{"@c":".LiveLesson$Item1","id":1,"item1Name":"Item1"},{"@c":".LiveLesson$Item2","id":2,"item2Name":"Item2"}]}"; line: 1, column: 17] (through reference chain: org.company.jackson.LiveLessonInfo$Container["items"]->java.util.ArrayList[0])
    

    3)使用 JsonTypeInfo.Id.NAME 替换 JsonTypeInfo.Id.MINIMAL_CLASS,新增 @JsonSubTypes 注解。

        @JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS)
        public interface Item {
        }
    
        @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "@c")
        @JsonSubTypes({
            @JsonSubTypes.Type(value = Item1.class, name = ".LiveLesson$Item1"),
            @JsonSubTypes.Type(value = Item2.class, name = ".LiveLesson$Item2")
        })
        public interface Item {
        }
    

    执行测试代码,控制台输出:

    {"items":[{"@c":".LiveLesson$Item1","id":1,"item1Name":"Item1"},{"@c":".LiveLesson$Item2","id":2,"item2Name":"Item2"}]}
    {"items":[{"@c":".LiveLesson$Item1","id":1,"item1Name":"Item1"},{"@c":".LiveLesson$Item2","id":2,"item2Name":"Item2"}]}
    

    参考

    相关文章

      网友评论

          本文标题:Jackson 类路径变更后的反序列化

          本文链接:https://www.haomeiwen.com/subject/obpuiltx.html