JSON 库在日常的开发中使用很普遍,序列化数据,服务之间交换数据。
常用的 JSON 库很多,比如
阿里巴巴的 Fastjson(3,540 usages),
谷歌的 Gson(13,795 usages),
以及 Jackson(16,902 usages)。
好像还有个ProtoBuf 。。。
这里就不比较谁好谁坏了,看自己的取舍。
因为Jackson主要在SpringBoot项目中用的多(内置),这里先不分析。
一般来说,我们使用这个JSON库无非就是以下几个操作:
- 将对象转成 JSON
- 将 JSON 转成对象
- 解析 JSON 字符串(没有对应的Bean类型)
- 处理 JSON 数组
- 处理 泛型对象
-最佳实践-
一般操作是存储的是JSON字符串,代码中序列化为JavaBean处理,再序列化为JSON字符串通过网络传输。
注:本文代码使用 Fastjson-1.2.60,Gson-2.8.6
Fastjson
优点:速度快、使用广泛、使用简单、功能完备、测试完备【好像确实爆出不少问题】
不过谁让我使用简单呢?
String text = JSON.toJSONString(obj); //序列化
VO vo = JSON.parseObject("{…}", VO.class); //反序列化
Fastjson的使用主要是三个对象:
JSON
public abstract class JSON implements JSONStreamAware, JSONAware
JSONArray和JSONObject继承JSON
JSON有三个方法我们用得特别多:
parseObject(String text, Classclazz) :JSONObject
parseArray(String text, Classclazz) : JSONArray
toJSONString(Object object) : String
JSONObject 实现了Map接口 ,跟使用Map就没多大的区别
public class JSONObject extends JSON implements Map<String, Object>, Cloneable, Serializable, InvocationHandler
getString(String key) :String
remove(Object key) // 其实就是调 map.remove(key)
getJSONArray(“data”): JSONArray
JSONArray 实现List接口
public class JSONArray extends JSON implements List<Object>, Cloneable, RandomAccess, Serializable
getJSONObject(int index):JSONObject
Gson
package cn.how2s.etlspark;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
/**
* Description:
*
* @Author: 留歌36
* @Date: 2020/12/2 8:27
*/
public class LiugeJson {
public static void main(String[] args) {
Gson gson = new Gson();
// 对象转 JSON
Score score1 = new Score(1, "语文",100);
String jsonString = JSON.toJSONString(score1); //fastJson
System.out.println(jsonString);
String jsonStringG =gson.toJson(score1); //gson
System.out.println(jsonStringG);
// JSON 转对象 [有对应的Bean]
String json = "{\"id\":1,\"courseName\":\"语文\",\"score\":100}";
Score score2 = JSON.parseObject(json, Score.class); //fastJson
System.out.println(score2.getCourseName());
Score score3 = gson.fromJson(json, Score.class);
System.out.println(score3.getCourseName());
System.out.println("----------嵌套的对象------------");
// 对于有嵌套的对象
Score scoreA = new Score(1, "语文",100);
Score scoreB = new Score(2, "数学",145);
Score scoreC = new Score(3, "外语",136);
List<Score> scoreList = Arrays.asList(scoreA, scoreB, scoreC);
Student liuge36 = new Student(1,"留歌",23,scoreList);
// 嵌套对象转 JSon
String jsonStringPlus = JSON.toJSONString(liuge36);
System.out.println(jsonStringPlus);
String jsonStringPlusG =gson.toJson(liuge36);
System.out.println(jsonStringPlusG);
// 将Json转为嵌套对象
String jsonPlus = "{\"id\":1,\"name\":\"留歌\",\"scoreList\":[{\"id\":1,\"courseName\":\"语文\",\"score\":100},{\"id\":2,\"courseName\":\"数学\",\"score\":145},{\"id\":3,\"courseName\":\"外语\",\"score\":136}]}";
Student liugea = JSON.parseObject(jsonPlus, Student.class);
System.out.println(liugea.getScoreList().get(1).getCourseName());
Student liugeaG = gson.fromJson(jsonPlus, Student.class);
System.out.println(liugeaG.getScoreList().get(1).getCourseName());
System.out.println("---------JSON 字符串解析 有些情况下,JSON 没有对应的 Java 类型------------");
// JSON 字符串解析 有些情况下,JSON 没有对应的 Java 类型 , 即纯粹的JSON 字符串
String jsonNoBean = "{\"age\":18, \"grade\": \"高三年级\", \"name\": \"呱呱酱\", \"score\": 99}";
JSONObject jsonObject = JSON.parseObject(jsonNoBean);
String grade = jsonObject.getString("grade");
Integer age = jsonObject.getInteger("age");
System.out.println(grade + " " + age);
JSONObject jsonObjectG = gson.fromJson(jsonNoBean, JSONObject.class);
String grade1 = jsonObjectG.getString("grade");
Integer age1 = jsonObjectG.getInteger("age");
System.out.println(grade1 + " " + age1);
//JSON 数组处理
System.out.println("---------JSON 数组处理 ------------");
String jsonArrayString = "[{\"id\":1,\"courseName\":\"语文\",\"score\":100},{\"id\":2,\"courseName\":\"数学\",\"score\":145},{\"id\":3,\"courseName\":\"外语\",\"score\":136}]";
JSONArray jsonArray = JSON.parseArray(jsonArrayString);
String courseNameA = jsonArray.getJSONObject(0).getString("courseName");
String courseNameB = jsonArray.getJSONObject(1).getString("courseName");
System.out.println(courseNameA + " " +courseNameB);
JsonArray jsonArrayG = gson.fromJson(jsonArrayString, JsonArray.class);
String courseNameC = jsonArrayG.get(0).getAsJsonObject().get("courseName").getAsString();
String courseNameD = jsonArrayG.get(1).getAsJsonObject().get("courseName").getAsString();
System.out.println(courseNameC + " " +courseNameD);
System.out.println("===============泛型对象处理================");
// 泛型对象处理 泛型对象在日常开发中用的也挺多的,比如 List 和 Map,这两个类库也都提供了相应的方法
// 对于有嵌套的对象
Score scoreA1 = new Score(1, "语文",100);
Score scoreB1 = new Score(2, "数学",145);
Score scoreC1 = new Score(3, "外语",136);
List<Score> scoreList1 = Arrays.asList(scoreA1, scoreB1, scoreC1);
String liuge36Json = JSON.toJSONString(scoreList1); // 序列化
Type type = new TypeReference<List<Score>>(){}.getType(); // fastJson获取泛型类型
scoreList1 = JSON.parseObject(liuge36Json, type); // 反序列化
String liuge36JsonG = gson.toJson(scoreList1); // 序列化
Type typeG = new TypeToken<List<Score>>() {}.getType(); // gson获取泛型类型
scoreList1 = gson.fromJson(liuge36JsonG, typeG);// 反序列化
//通过上面的对比发现,其实两个框架都提供了相似的功能,方法名称上会有一些细微的差别。
//
//Gson 基本上可以覆盖到 Fastjson 中的功能,虽然 Fastjson 在性能上要强于 Gson,
// 但是在大多数情况下,只要处理的对象不大,性能的差别也不会很大。
}
}