Gson實戰之旅

前言

最近由於FastJson最近幾年的安全漏洞頻發,因此後續的項目準備切換到Gson中,而前面的項目也開始準備逐步切換到Gsonjava

而本文就是所以而產生,本文將會圍繞一系列實際的需求來展現如何使用Gson解決實際開發上遇到的問題。git

Gson之旅

如同前言所說的,如下的章節都是本人遇到的實際場景後如何使用Gson的記錄。github

初識Gson

Gson是一個Google開源出來針在Java對象和JSON數據之間進行相互映射的Java類庫。並且使用方式很簡單。以maven項目爲例,只須要添加如下配置便可使用。json

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
    <scope>provided</scope>
</dependency>

Java對象轉JSON

並且GsonAPI使用起來也很簡單,例如Java對象轉成JSON字符串,只須要調用GsontoJson方法便可,示例以下數組

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對象

而將JSON字符串轉成Java對象也很簡單,只須要調用GsonfromJson方法便可,示例以下框架

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

  1. fromJson方法須要傳入的是==JSON格式的字符串==和對應==Java對象的類型==才行。
  2. Gson是能夠識別使用==單引號==的JSON字符串,而實際上==JSON格式規範裏面是須要使用雙引號==。

演示的Student類源碼

@Datalombok框架的註解,能夠自動生成對應的getter/settertoString方法。測試

@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,也就是直接調用了DatetoString方法。而我期待的值則是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-ddyyyy-MM-dd HH:mm:ss),GSON均可以正常識別。

顯示null值

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)]

須要注意這裏的Typejava.lang.reflect.Type

總結

  1. Gson使用toJson來說Java對象轉爲JSON,而fromJson則是將JSON轉爲Java對象
  2. 若是默認設置不能知足你的需求,能夠選擇使用GsonBuilder來構建一個自定義的Gson對象來進行JSON和Java對象的互相轉換。
相關文章
相關標籤/搜索