需求
目前有一个需求,不同对象有一些公共属性,分别也有一些不同的属性。对方传过来的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<PersonGroup>() {
}.getType();
PersonGroup personGroup = gson.fromJson(jsonStr, type);
//为了打断点
System.out.println();
}
}
解析后的内容如下:
通过解析后的内容可以发现,并不能满足我们的需求。
解决方案
自定义一个反序列化配置,用来识别父类下的各个子类,反序列化时装配其原始类型。
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);
}
}
反序列化方式如下:
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();
}
}
从序列化结果来看,已经转换成功,满足我们的要求。