gson如何序列化子类

需求

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

举例

定义Person类、Student类、Worker类;

java 复制代码
@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;
}

字符串为:

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

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

java 复制代码
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<PersonGroup>() {
        }.getType();

        PersonGroup personGroup = gson.fromJson(jsonStr, type);
        //为了打断点
        System.out.println();
    }
}

解析后的内容如下:

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

解决方案

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

java 复制代码
public class PersonDesrializer implements JsonDeserializer<Person> {
    private Gson gson = new Gson();

    private Map<Integer, Class<? extends 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();
        Class<? extends Person> typeClazz = this.typeMap.get(jsonObject.get("type").getAsInt());
        return gson.fromJson(jsonElement,typeClazz);
    }
}

反序列化方式如下:

java 复制代码
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<PersonGroup>() {
        }.getType();

        PersonGroup personGroup = gson.fromJson(jsonStr, type);
        //为了打断点
        System.out.println();
    }
}

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

相关推荐
考虑考虑4 小时前
JDK26中的Map.ofLazy
java·后端·java ee
鶴哥只手遮天7 小时前
Spring AI 2.0.1 深度解析-第 14 章 MCP 服务端(上):注解式实现与工具来源
java·人工智能·开源
鶴哥只手遮天7 小时前
Spring AI 2.0.1 深度解析-第 15 章 MCP 服务端(下):三种协议形态、Streamable 传输与状态管理
java·人工智能·开源
鶴哥只手遮天7 小时前
Spring AI 2.0.1 深度解析-第 16 章 向量存储(上):`VectorStore` 接口体系、`BatchingStrategy`
java·人工智能·开源
鶴哥只手遮天7 小时前
Spring AI 2.0.1 深度解析-第 12 章 工具循环的流式形态、Usage 累加与扩展体系
java·人工智能·开源
鶴哥只手遮天7 小时前
Spring AI 2.0.1 深度解析-第 23 章 模型供应商实现:从 `OpenAiSetup` 到 Bedrock
java·人工智能·开源
鶴哥只手遮天7 小时前
Spring AI 2.0.1 深度解析-第 06 章 内置 Advisor 全景:13 个实现逐个剖到源码级
java·人工智能·开源
鶴哥只手遮天7 小时前
Spring AI 2.0.1 深度解析-第 03 章 消息体系与 Prompt:不可变模型、`ChatOptions` 与模板渲染
java·人工智能·开源
鶴哥只手遮天7 小时前
Spring AI 2.0.1 深度解析-第 24 章 生产实践与 2.x 迁移:陷阱清单、AOT 与调优
java·人工智能·开源
鶴哥只手遮天7 小时前
Spring AI 2.0.1 深度解析-第 10 章 工具调用(中):执行链路、结果转换与工具限制
java·人工智能·开源