最近由於FastJson
最近幾年的安全漏洞頻發,因此後續的項目準備切換到Gson
中,而前面的項目也開始準備逐步切換到Gson
。java
而本文就是所以而產生,本文將會圍繞一系列實際的需求來展現如何使用Gson
解決實際開發上遇到的問題。git
如同前言所說的,如下的章節都是本人遇到的實際場景後如何使用Gson
的記錄。github
Gson
是一個Google
開源出來針在Java
對象和JSON
數據之間進行相互映射的Java
類庫。並且使用方式很簡單。以maven
項目爲例,只須要添加如下配置便可使用。json
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> <scope>provided</scope> </dependency>
並且Gson
的API
使用起來也很簡單,例如Java對象轉成JSON字符串,只須要調用Gson
的toJson
方法便可,示例以下數組
Gson gson = new Gson(); Student student = new Student(); student.setId(1L); student.setName("測試用戶"); student.setSex(false); System.out.println(gson.toJson(student));
輸出結果安全
{"id":1,"name":"測試用戶","sex":false}
而將JSON字符串轉成Java對象也很簡單,只須要調用Gson
的fromJson
方法便可,示例以下框架
Gson gson = new Gson(); String jsonStr ="{'id':1,'name':'測試用戶','sex':false}"; Student student = gson.fromJson(jsonStr,Student.class);
輸出結果maven
Student(id=1, name=測試用戶, sex=false, birthday=null)
這裏須要注意如下兩點ide
fromJson
方法須要傳入的是==JSON格式的字符串==和對應==Java對象的類型==才行。Gson
是能夠識別使用==單引號==的JSON
字符串,而實際上==JSON格式規範裏面是須要使用雙引號==。@Data
是lombok
框架的註解,能夠自動生成對應的getter/setter
和toString
方法。測試
@Data public class Student implements Serializable { /** * 學生ID */ private Long id; /** * 學生名稱 */ private String name; /** * 學生性別 */ private Boolean sex; /** * 出生年月日 */ private Date birthday; }
因而就開始了Gson
的使用,很快我就遇到第一個問題了。使用Gson
處理第三方接口傳過來的JSON
字符串時,能夠正確將yyyy-MM-dd HH:mm:ss
格式(例如2020-01-30 11:30:00
)的值轉爲對應的Date
對象。
但是Java對象轉爲JSON時卻發現Date
對象的值轉爲Thu Jan 30 11:30:00 CST 2020
,也就是直接調用了Date
的toString
方法。而我期待的值則是2020-01-30 11:30:00
。經過查閱用戶手冊得知,可使用GsonBuilder
來構建一個自定義日期格式化的Gson
實例,以下所示
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create(); Student student = new Student(); student.setName("測試用戶"); student.setId(1L); student.setSex(false); student.setBirthday(new Date()); String jsonStr = gson.toJson(student); System.out.println(gson.toJson(student));
輸出結果
{"id":1,"name":"測試用戶","sex":false,"birthday":"2020-06-07 18:45:10"}
而針對JSON轉Java對象,常規的日期格式字符(如yyyy-MM-dd
和yyyy-MM-dd HH:mm:ss
),GSON均可以正常識別。
Gson
在將Java對象轉爲JSON時,會隱藏爲值爲null
的屬性,可是其實顯示全部值爲null
的屬性更加便於咱們進行調試,並且只要簡單地設置一下便可。
Gson gson = new GsonBuilder().serializeNulls().create(); Student student = new Student(); student.setId(1L); System.out.println(gson.toJson(student));
輸出結果
{"id":1,"name":null,"sex":null,"birthday":null}
Gson
在將Java對象轉成JSON時,默認會進行壓縮處理,例如這樣
{"id":1,"name":"測試用戶","sex":false}
而這個時候只須要簡單地設置一下便可讓Gson
輸出一個展開的JSON
Gson gson = new GsonBuilder().setPrettyPrinting().create(); Student student = new Student(); student.setId(1L); student.setName("測試用戶"); student.setSex(false); System.out.println(gson.toJson(student));
輸出結果
{ "id": 1, "name": "測試用戶", "sex": false }
有些時候和第三方系統進行對接時,對方的提供的JSON部分屬性是某些單詞的縮寫或者很難理解(遇過有拼音縮寫,英語縮寫,單詞拼寫錯誤),這個時候若是但願本身這邊的Java對象的屬性更好理解,能夠選擇使用Gson
的別名功能,示例以下:
@Data public class Teacher implements Serializable { /** * 教師姓名 */ @SerializedName("name") private String teacherName; /** * 教師性別 */ @SerializedName("sex") private Boolean teacherSex; }
@SerializedName
註解能夠的value
屬性能夠設置單個別名,而alternate
則是用於設置多個別名。
有時候咱們會遇到接收一個JSON數組的狀況,並且此時若是將其轉爲一個List
對象時,就會遇到類型轉換的問題,以上面Student
類爲例,下面將演示如何將JSON數組轉成List<Student>
Gson gson = new Gson(); String jsonStr = "[{'name':'測試用戶'},{'id':2}]"; // 獲取實際要轉的類型 Type type =new TypeToken<List<Student>>(){}.getType(); List<Student> list = gson.fromJson(jsonStr,type); System.out.println(list);
輸出結果
[Student(id=null, name=測試用戶, sex=null, birthday=null), Student(id=2, name=null, sex=null, birthday=null)]
須要注意這裏的Type
是java.lang.reflect.Type
Gson
使用toJson
來說Java對象轉爲JSON,而fromJson
則是將JSON轉爲Java對象GsonBuilder
來構建一個自定義的Gson
對象來進行JSON和Java對象的互相轉換。