Gson与fastGson—反序列化及泛型嵌套

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”}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值