1、定义实体对象
首先定义两个实体对象Teacher 与Student
public class Teacher<T> implements Serializable {
private static final long serialVersionUID = xxx;
private Long id;
private String name;
private List<T> list;
}
public class Student implements Serializable {
private Long id;
private String name;
}
1.1 FastJson的序列化
1.1.1 序列化
Teacher<Student> teacher = new Teacher<>();
teacher.setId(1L);
teacher.setName("teacher");
List<Student> students = Lists.newArrayList();
Student student = new Student();
student.setId(11L);
student.setName("student1");
students.add(student);
Student student1 = new Student();
student1.setId(12L);
student1.setName("student2");
students.add(student1);
teacher.setList(students);
String serialStr = JSON.toJSONString(teacher);
System.out.println(serialStr);
结果如下:
{“id”:1,“list”:[{“id”:11,“name”:“student1”},{“id”:12,“name”:“student2”}],“name”:“teacher”}
下面我们来对这个字符串进行反序列化
1.1.2 反序列化
- 正常解析
以上面结果测试,可以看到反序列化结果正常:
String json = "{\"id\":1,\"list\":[{\"id\":11,\"name\":\"student1\"},{\"id\":12,\"name\":\"student2\"}],\"name\":\"teacher\"}";
Teacher<Student> teacher = JSON.parseObject(json, Teacher.class);
System.out.println(JSON.toJSONString(teacher));
- 异常解析
在看两个案例,修改字符串会不会正常解析?
// 添加多余字段,会看到解析异常
String json = "{\"id\":1,\"sex\":man,\"list\":[{\"id\":11,\"name\":\"student1\"},{\"id\":12,\"name\":\"student2\"}],\"name\":\"teacher\"}";
// id重复,可以正常解析,解析的值id=1
String json = "{\"id\":1,\"id\":2,\"list\":[{\"id\":11,\"name\":\"student1\"},{\"id\":12,\"name\":\"student2\"}],\"name\":\"teacher\"}";
- 泛型解析
以上序列化存在泛型嵌套时不能正常解析, 下面看一下fastjson的泛型序列化实现:
String json = "{\"id\":1,\"id\":2,\"list\":[{\"id\":11,\"name\":\"student1\"},{\"id\":12,\"name\":\"student2\"}],\"name\":\"teacher\"}";
TypeReference typeReference = new TypeReference<Teacher<Student>>() {};
Teacher<Student> teacher = JSON.parseObject(json, typeReference.getType());
{“id”:1,“list”:[{“id”:11,“name”:“student1”},{“id”:12,“name”:“student2”}],“name”:“teacher”}
- 自定义反序列化
ParserConfig.getGlobalInstance().putDeserializer(Teacher.class, new ObjectDeserializer() {
@Override
public Teacher deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
JSONObject jsonObject = parser.parseObject();
String name = jsonObject.getString("name");
Long id = jsonObject.getLong("id");
Teacher teacher = new Teacher();
teacher.setId(id);
teacher.setName(name);
List<Student> list = Lists.newArrayList();
JSONArray jsonArray =jsonObject.getJSONArray("list");
jsonArray.size();
for (Student student:jsonArray.toJavaList(Student.class)) {
list.add(student);
}
teacher.setList(list);
return teacher;
}
@Override
public int getFastMatchToken() {
return JSONToken.LITERAL_INT;
}
});
String json = "{\"id\":1,\"id\":2,\"list\":[{\"id\":11,\"name\":\"student1\"},{\"id\":12,\"name\":\"student2\"}],\"name\":\"teacher\"}";
Teacher<Student> teacher = JSON.parseObject(json, Teacher.class);
1.2 Gson序列化
1.2.1 序列化
Teacher<Student> teacher = new Teacher<>();
teacher.setId(1L);
teacher.setName("teacher1");
List<Student> students = Lists.newArrayList();
Student student = new Student();
student.setId(11L);
student.setName("student1");
Student student1 = new Student();
student1.setId(12L);
student1.setName("student2");
students.add(student);
students.add(student1);
teacher.setList(students);
Gson gson = new Gson();
String json = gson.toJson(teacher);
{“id”:1,“name”:“teacher1”,“list”:[{“id”:11,“name”:“student1”},{“id”:12,“name”:“student2”}]}
1.2.2 反序列化
- 解析序列化字符串
String json = "{\"id\":1,\"name\":\"teacher1\",\"list\":[{\"id\":11,\"name\":\"student1\"},{\"id\":12,\"name\":\"student2\"}]}\n";
Teacher<List<Student>> teacher = new Gson().fromJson(json, Teacher.class);
System.out.println(JSON.toJSONString(teacher));
{“id”:1,“list”:[{“id”:11.0,“name”:“student1”},{“id”:12.0,“name”:“student2”}],“name”:“teacher1”}
此时解析不正确,内部嵌套不能正常解析,我们可以看一下例子:
String json = "{\"id\":1,\"name\":\"teacher1\",\"list\":[{\"id\":11,\"id\":p,\"name\":\"student1\"},{\"id\":12,\"name\":\"student2\"}]}\n";
Teacher<List<Student>> teacher = new Gson().fromJson(json, Teacher.class);
{“id”:1,“list”:[{“id”:“p”,“name”:“student1”},{“id”:12.0,“name”:“student2”}],“name”:“teacher1”}
student的id本来为Long类型,转换为“p”,即嵌套泛型解析失效
- gson反序列处理嵌套类型
String json = "{\"id\":1,\"name\":\"teacher1\",\"list\":[{\"id\":11,\"name\":\"student1\"},{\"id\":12,\"name\":\"student2\"}]}\n";
Type type = new TypeToken<Teacher<Student>>(){}.getType();
Teacher<Student> teacher = new Gson().fromJson(json, type);
{“id”:1,“list”:[{“id”:11,“name”:“student1”},{“id”:12,“name”:“student2”}],“name”:“teacher1”}
- 自定义反序列化
Gson gson = new GsonBuilder().registerTypeAdapter(Teacher.class, new JsonDeserializer <Teacher> () {
@Override
public Teacher deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
// 基本类型getAsJsonPrimitive
// 对象类型:getAsJsonObject
// list类型: getAsJsonArray
Long id = jsonObject.getAsJsonPrimitive("id").getAsLong();
String name = jsonObject.getAsJsonPrimitive("name").getAsString();
List<Student> students = Lists.newArrayList();
Teacher teacher1 = new Teacher();
teacher1.setId(id);
teacher1.setName(name);
return teacher1;
}
}).create();
String json = "{\"id\":1,\"name\":\"teacher1\",\"list\":[{\"id\":11,\"name\":\"student1\"},{\"id\":12,\"name\":\"student2\"}]}\n";
Teacher<Student> teacher = gson.fromJson(json, Teacher.class);
System.out.println(JSON.toJSONString(teacher));
{“id”:1,“name”:“teacher1”}