如何从Fastjson迁移到Gson

JSON 库在在日常的开发中使用很普遍,序列化数据,服务之间交换数据。

常用的 JSON 库很多,比如阿里巴巴的 Fastjson,谷歌的 Gson,以及 Jackjson。

由于 Fastjson 漏洞问题,所以准备使用 Gson 来替代 FastJson。虽然 Fastjson 号称是最快的 JSON 工具,但其实 Gson 和 Jackson 等工具与它的差距很小了,相比与追求这一点性能的提升,系统的安全更重要。

而且个人觉得 Gson 的文档比 fastjson 要更好一些(文档时程序员的必修课)。

本文就来说明一下,如何从 Fastjson 平滑的迁移到 Gson,尽量不说废话,使用代码来说明问题

注:本文代码使用 Fastjson-1.2.60,Gson-2.8.6

使用 Fastjson时, 最主要的功能如下:

  • 将对象转成 JSON
  • 将 JSON 转成对象
  • 解析 JSON 字符串
  • 处理 JSON 数组
  • 处理 泛型对象

下面分别来看看 Gson 中如何实现这些。示例代码中使用的两个类如下(省略了 get 和 set 方法):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Student {
private long id;
private String name;
private String gender;
private int age;

public Student(long id, String name, String gender, int age) {
this.id = id;
this.name = name;
this.gender = gender;
this.age = age;
}
}
public class ClassRoom {

private long id;
private String className;
private List<Student> students;

public ClassRoom(long id, String className, List<Student> students) {
this.id = id;
this.className = className;
this.students = students;
}
}

对象和 JSON 的互相转换

对象转 JSON

fastjson:

1
2
Student s1 = new Student(1, "小明", "男", 12);
String studentJson = JSON.toJSONString(s1);

gson:

1
2
3
Student s1 = new Student(1, "小明", "男", 12);
Gson gson = new Gson();
String studentJson = gson.toJson(s1);

JSON 转对象

fastjson:

1
2
String json = "{\"age\":12,\"gender\":\"男\",\"id\":1,\"name\":\"小明\"}";
Student student = JSON.parseObject(json, Student.class);

gson:

1
2
3
 String json = "{\"age\":12,\"gender\":\"男\",\"id\":1,\"name\":\"小明\"}";
Gson gson = new Gson();
Student student = gson.fromJson(json, Student.class);

上面处理的时简单的对象,对于有嵌套的对象,处理起来同样简单:

fastjson:

1
2
3
4
5
6
7
8
Student s1 = new Student(1, "小明", "男", 12);
Student s2 = new Student(2, "小芳", "女", 12);

List<Student> students = Arrays.asList(s1, s2);
ClassRoom classRoom = new ClassRoom(1, "六年级一班", students);

String classRoomJson = JSON.toJSONString(classRoom); // 将嵌套对象转成 JSON
ClassRoom classRoom = JSON.parseObject(json, ClassRoom.class); // 将 JSON 转成嵌套的对象

gson:

1
2
3
4
5
6
7
8
9
Student s1 = new Student(1, "小明", "男", 12);
Student s2 = new Student(2, "小芳", "女", 12);

List<Student> students = Arrays.asList(s1, s2);
ClassRoom classRoom = new ClassRoom(1, "六年级一班", students);

Gson gson = new Gson();
String classRoomJson = gson.toJson(classRoom); // 将嵌套对象转成 JSON
ClassRoom classRoom = gson.fromJson(json, ClassRoom.class); // 将 JSON 转成嵌套对象

JSON 字符串解析

上面的例子演示的是 JSON 和对象之间的相互转化,如果在有些情况下,JSON 没有对应的 Java 类型,这个时候该怎么处理:

fastjson:

1
2
3
4
5
String json = "{\"age\":18, \"grade\": \"六年级\", \"name\": \"小明\", \"score\": 99}";
JSONObject jsonObject = JSON.parseObject(json);

jsonObject.getString("name"); // 小明
jsonObject.getInteger("score"); // 99

gson:

1
2
3
4
5
6
String json = "{\"age\":18, \"grade\": \"六年级\", \"name\": \"小明\", \"score\": 99}";

Gson gson = new Gson();
JsonObject jsonObject = gson.fromJson(json, JsonObject.class);
jsonObject.get("name").getAsString(); // 小明
jsonObject.get("score").getAsInt(); // 99

JSON 数组处理

对于更复杂一点的情况,json是一个数组,但没关系,处理起来同样简单:

fastjson:

1
2
3
4
5
6
String json = "[{\"age\":18, \"grade\": \"六年级\", \"name\": \"小明\", \"score\": 99},{\"age\":18, \"grade\": \"六年级\", \"name\": \"小芳\", \"score\": 100}]";

JSONArray jsonArray = JSON.parseArray(json);

jsonArray.getJSONObject(0).getString("name"); // 小明
jsonArray.getJSONObject(1).getString("name"); // 小芳

gson:

1
2
3
4
5
6
String json = "[{\"age\":18, \"grade\": \"六年级\", \"name\": \"小明\", \"score\": 99},{\"age\":18, \"grade\": \"六年级\", \"name\": \"小芳\", \"score\": 100}]";
Gson gson = new Gson();

JsonArray jsonArray = gson.fromJson(json, JsonArray.class);
jsonArray.get(0).getAsJsonObject().get("name").getAsString(); // 小明
jsonArray.get(1).getAsJsonObject().get("name").getAsString(); // 小芳

泛型对象处理

泛型对象在日常开发中用的也挺多的,比如 List 和 Map,这两个类库也都提供了相应的方法:

fastjson:

1
2
3
4
5
6
7
8
Student s1 = new Student(1, "小明", "男", 12);
Student s2 = new Student(2, "小芳", "女", 12);
List<Student> students = Arrays.asList(s1,s2);

String json = JSON.toJSONString(students);

Type type = new TypeReference<List<Student>>(){}.getType(); // 在这里需要获取完整的泛型类型
students = JSON.parseObject(json, type);

gson:

1
2
3
4
5
6
7
8
Student s1 = new Student(1, "小明", "男", 12);
Student s2 = new Student(2, "小芳", "女", 12);
List<Student> students = Arrays.asList(s1,s2);
Gson gson = new Gson();
Type type = new TypeToken<List<Student>>() {}.getType(); // 获取泛型类型

String json = gson.toJson(students);
students = gson.fromJson(json, type);

通过上面的对比发现,其实两个框架都提供了相似的功能,方法名称上会有一些细微的差别。

Gson 基本上可以覆盖到 Fastjson 中的功能,虽然 Fastjson 在性能上要强于 Gson,但是在大多数情况下,只要处理的对象不大,性能的差别也不会很大。

而且需要说一下,Fastjson 真的需要把文档好好整理一下了。

© 2020 Rayjun    PowerBy Hexo