• gson如何序列化子类


    需求

    目前有一个需求,不同对象有一些公共属性,分别也有一些不同的属性。对方传过来的json字符串中,把这些对象组成了一个数组返回过来的。这样该如何反序列化呢?

    举例

    定义Person类、Student类、Worker类;

    @Data
    @ToString
    public class Person {
        //姓名
        private String name;
        //年龄
        private Integer age;
        //类型,0代表Student,1代表worker
        private Integer type;
    }
    
    @Data
    @ToString
    public class Student extends Person{
        //学校
        private String school;
    }
    
    @Data
    @ToString
    public class Worker extends Person{
        //薪水
        private Integer salary;
    }
    

    字符串为:

    {
        "group":[
            {
                "school":"Hello中学",
                "name":"张三",
                "age":16,
                "type":0
            },
            {
                "salary":100000,
                "name":"李四",
                "age":35,
                "type":1
            }
        ]
    }
    

    如果我们直接使用Gson来解析,解析代码如下:

    public class MyTest {
        public static void main(String[] args) {
            Gson gson = new Gson();
            String jsonStr = "{\"group\":[{\"school\":\"Hello中学\",\"name\":\"张三\",\"age\":16,\"type\":0},{\"salary\":100000,\"name\":\"李四\",\"age\":35,\"type\":1}]}";
            Type type = new TypeToken() {
            }.getType();
    
            PersonGroup personGroup = gson.fromJson(jsonStr, type);
            //为了打断点
            System.out.println();
        }
    }
    

    解析后的内容如下:

    解析后的内容

    通过解析后的内容可以发现,并不能满足我们的需求。

    解决方案

    自定义一个反序列化配置,用来识别父类下的各个子类,反序列化时装配其原始类型。

    public class PersonDesrializer implements JsonDeserializer {
        private Gson gson = new Gson();
    
        private Mapextends Person>> typeMap = new HashMap<>();
    
        public PersonDesrializer() {
            typeMap.put(0,Student.class);
            typeMap.put(1,Worker.class);
        }
    
        @Override
        public Person deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
            JsonObject jsonObject = jsonElement.getAsJsonObject();
            Classextends Person> typeClazz = this.typeMap.get(jsonObject.get("type").getAsInt());
            return gson.fromJson(jsonElement,typeClazz);
        }
    }
    

    反序列化方式如下:

    public class MyTest {
        public static void main(String[] args) {
            Gson gson = new GsonBuilder()
                    .serializeNulls()
                    .registerTypeAdapter(Person.class, new PersonDesrializer())
                    .create();
            String jsonStr = "{\"group\":[{\"school\":\"Hello中学\",\"name\":\"张三\",\"age\":16,\"type\":0},{\"salary\":100000,\"name\":\"李四\",\"age\":35,\"type\":1}]}";
            Type type = new TypeToken() {
            }.getType();
    
            PersonGroup personGroup = gson.fromJson(jsonStr, type);
            //为了打断点
            System.out.println();
        }
    }
    

    序列化结果

    从序列化结果来看,已经转换成功,满足我们的要求。

  • 相关阅读:
    Atlas 200 DK开发板问题总结
    Activiti 8.0.0 发布,业务流程管理与工作流系统
    600+,亮眼数据背后的康铂酒店品牌硬实力
    Ubuntu22.04下安装kafka_2.12-2.6.0并运行简单实例
    我的创作纪念日
    返回Series或DataFrame中指定列中指定数量的最小值nsmallest()函数
    光伏系统MPPT、恒功率控制切换Simulink仿真
    【自用】Linux服务器部署Oracle并使用数据库管理工具Navicat远程连接(包含远程Navicat配置)
    python xlrd+xlwt+xlutils处理excel
    <VB.net>下CSV文件的导入(读取到DataGridView)和导出(DataGirdView保存到csv)
  • 原文地址:https://www.cnblogs.com/nicaicai/p/17775515.html