JSON反序列化泛型丢失问题

一、问题描述

最近开发业务中遇到一个有趣的问题,我本来是想提取一个公共的抽象类,完成从redis缓存中获取到json后进行反序列化成继承类的泛型对象,这个泛型类是List,在反序列化时,list类型是正常的,但是list里的对象却不正确。

原本实现:

	@Test
    public void run1(){
        var userService = new UserService();
        var json = """
                [
                    {"name":"张三","age":12},
                    {"name":"李四","age":17}
                ]
                """;
        List<User> users = userService.json2Pojo(json);
        User user = users.get(0); // 这里会报错,因为类型不匹配,集合中的对象类型是LinkedHashMap
        System.out.println(users);
    }

    //实现类
    class UserService extends AbstractService<List<User>>{
    }
    //抽象类
    abstract class  AbstractService<T>{
        public final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
        public T json2Pojo(String json){
            try {
                return OBJECT_MAPPER.readValue(json, new TypeReference<T>() {
                });
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    //对象
    @Data
    static class User{
        private String name;
        private Integer age;
    }

测试代码中的反序列化集合users返回结构是:
在这里插入图片描述

注意这里的类型原本应该是User,但是却变为了LinkedHashMap
这里我使用的json工具是jackson,以为是因为这个框架不支持导致的泛型丢失,然后尝试使用Gson,结果也是一样的。

二、解决方案

1、json反序列化交给实现类完成

这是下下策,因为已经提取抽象类了,我们就是要减少实现类的开发,虽然这样没有太多的开发代码,但是总归感觉别扭,不建议这样实现

2、通过spring工具获取泛型类型,然后反序列化

	abstract class  AbstractService<T>{
        public final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
        // 通过spring工具获取泛型类型
        private final JavaType JAVA_TYPE = TypeFactory
                .defaultInstance()
                .constructType(ResolvableType.forClass(this.getClass()).getSuperType().getGeneric(0).getType());
        public T json2Pojo(String json){
            try {
                Object o = OBJECT_MAPPER.readValue(json, JAVA_TYPE);
                return (T) o;
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

这里users集合中的对象已经是User对象了
在这里插入图片描述


版权声明:本文为weixin_33613947原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。