如何从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 方法):
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:
Student s1 = new Student(1, "小明", "男", 12);
String studentJson = JSON.toJSONString(s1);
gson:
Student s1 = new Student(1, "小明", "男", 12);
Gson gson = new Gson();
String studentJson = gson.toJson(s1);
JSON 转对象
fastjson:
String json = "{\"age\":12,\"gender\":\"男\",\"id\":1,\"name\":\"小明\"}";
Student student = JSON.parseObject(json, Student.class);
gson:
String json = "{\"age\":12,\"gender\":\"男\",\"id\":1,\"name\":\"小明\"}";
Gson gson = new Gson();
Student student = gson.fromJson(json, Student.class);
上面处理的时简单的对象,对于有嵌套的对象,处理起来同样简单:
fastjson:
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:
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:
String json = "{\"age\":18, \"grade\": \"六年级\", \"name\": \"小明\", \"score\": 99}";
JSONObject jsonObject = JSON.parseObject(json);
jsonObject.getString("name"); // 小明
jsonObject.getInteger("score"); // 99
gson:
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:
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:
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:
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:
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 真的需要把文档好好整理一下了。