Java物件的序列化與反序列化-Json篇

bruce.yao發表於2019-01-04

https://jisonami.iteye.com/blog/2299952

https://www.jianshu.com/p/a03bc97875b8

 

說到Java物件的序列化與反序列化,我們首先想到的應該是Java的Serializable介面,這玩意在兩個系統之間的DTO物件裡面可能會用到,用於系統之間的資料傳輸。或者在RPC(遠端方法呼叫)時可能會用到。 

但其實若是用於資料傳輸,xml和json兩種資料格式用得更多一些。我在第一家公司上班是也曾經自己封裝過Java物件與xml相互轉換的工具,你可能會說為什麼不用XStream呢,XStream確實好用,但是在Applet環境下可以使用的xml類庫也就只有jdom了,連dom4j在Applet環境下都沒有許可權使用(Java反射的某些特性是需要許可權的,Applet的安全機制不允許)。 

扯遠了,本文要說的是Java物件與Json的相互轉換。目前Java常用的Json類庫有3種,即fastjson、jackson和gson,分別介紹如何將一個Java物件轉換成Json和將一個Json字串轉換成Java物件,其實它們的用法大同小異。 

一、首先看Maven依賴 
二、需要序列化的POJO和初始化程式碼 
三、fastjson的使用 
四、jackson的使用 
五、gson的使用 

一、首先看Maven依賴 

若不會maven,請參考Maven的基本用法:http://jisonami.iteye.com/blog/2300036 
 

Xml程式碼 

 收藏程式碼

  1. <!-- json -->  
  2. <!-- 引入fastjson依賴 -->  
  3. <dependency>  
  4.     <groupId>com.alibaba</groupId>  
  5.     <artifactId>fastjson</artifactId>  
  6.     <version>1.2.12</version>  
  7. </dependency>  
  8. <!-- 引jackson依賴 -->  
  9. <!-- jackson核心包,必選,提供基於“流模式”解析的API -->  
  10. <dependency>  
  11.     <groupId>com.fasterxml.jackson.core</groupId>  
  12.     <artifactId>jackson-core</artifactId>  
  13.     <version>2.7.4</version>  
  14. </dependency>  
  15. <!-- jackson註解包,可選,提供註解功能 -->  
  16. <dependency>  
  17.     <groupId>com.fasterxml.jackson.core</groupId>  
  18.     <artifactId>jackson-annotations</artifactId>  
  19.     <version>2.7.4</version>  
  20. </dependency>  
  21. <!-- jackson資料繫結包,可選,提供基於“物件繫結”和“樹模型”相關API -->  
  22. <dependency>  
  23.     <groupId>com.fasterxml.jackson.core</groupId>  
  24.     <artifactId>jackson-databind</artifactId>  
  25.     <version>2.7.4</version>  
  26. </dependency>  
  27. <!-- 引入gson依賴 -->  
  28. <dependency>  
  29.     <groupId>com.google.code.gson</groupId>  
  30.     <artifactId>gson</artifactId>  
  31.     <version>2.6.2</version>  
  32. </dependency>  



二、需要序列化的POJO和初始化程式碼 
以下3種類庫的使用均使用下面這個POJO 

Java程式碼 

 收藏程式碼

  1. public class User {  
  2.     public User(){}  
  3.     private String id;  
  4.     private String name;  
  5.     private String password;  
  6.     public String getId() {  
  7.         return id;  
  8.     }  
  9.     public void setId(String id) {  
  10.         this.id = id;  
  11.     }  
  12.     public String getName() {  
  13.         return name;  
  14.     }  
  15.     public void setName(String name) {  
  16.         this.name = name;  
  17.     }  
  18.     public String getPassword() {  
  19.         return password;  
  20.     }  
  21.     public void setPassword(String password) {  
  22.         this.password = password;  
  23.     }  
  24.     @Override  
  25.     public String toString() {  
  26.         return "User [id=" + id + ", name=" + name + ", password=" + password  
  27.                 + "]";  
  28.     }     
  29. }  


 

Java程式碼 

 收藏程式碼

  1. /** 
  2.  * 初始化User物件 
  3.  * @return user 
  4.  */  
  5. private static User initUser(){  
  6.     User user = new User();  
  7.     user.setId("1");  
  8.     user.setName("jison");  
  9.     user.setPassword("jison");  
  10.     return user;  
  11. }  



三、fastjson的使用 
fastjson的主要工具類是JSON,以下程式碼實現Java物件的序列化與反序列化 

Java程式碼 

 收藏程式碼

  1. // 將Java物件序列化為Json字串  
  2.     String objectToJson = JSON.toJSONString(initUser());  
  3.     System.out.println(objectToJson);  
  4.     // 將Json字串反序列化為Java物件  
  5.     User user = JSON.parseObject(objectToJson, User.class);  
  6.     System.out.println(user);  



四、jackson的使用 
jackson我們經常用到的是它的資料繫結包下的ObjectMapper類,以下程式碼實現Java物件的序列化與反序列化 

Java程式碼 

 收藏程式碼

  1. ObjectMapper objectMapper = new ObjectMapper();  
  2.     // 將Java物件序列化為Json字串  
  3.     String objectToJson = objectMapper.writeValueAsString(initUser());  
  4.     System.out.println(objectToJson);  
  5.     // 將Json字串反序列化為Java物件  
  6.     User user = objectMapper.readValue(objectToJson, User.class);  
  7.     System.out.println(user);  



五、gson的使用 
gson的主要工具類是Gson,使用GsonBuilder構造,以下程式碼實現Java物件的序列化與反序列化 

Java程式碼 

 收藏程式碼

  1. Gson gson = new GsonBuilder().create();  
  2.     // 將Java物件序列化為Json字串  
  3.     String objectToJson = gson.toJson(initUser());  
  4.     System.out.println(objectToJson);  
  5.     // 將Json字串反序列化為Java物件  
  6.     User user = gson.fromJson(objectToJson, User.class);  
  7.     System.out.println(user);  



以上3種json類庫的完整程式碼如下: 

Java程式碼 

 收藏程式碼

  1. public class JsonUtils {  
  2.   
  3.     /** 
  4.      * 初始化User物件 
  5.      * @return user 
  6.      */  
  7.     private static User initUser(){  
  8.         User user = new User();  
  9.         user.setId("1");  
  10.         user.setName("jison");  
  11.         user.setPassword("jison");  
  12.         return user;  
  13.     }  
  14.       
  15.     public static void main(String[] args) throws Exception {  
  16.         // fastjson用法  
  17.         fastjson();  
  18.         // jackson用法  
  19.         jackson();  
  20.         // gson用法  
  21.         gson();  
  22.     }  
  23.       
  24.     private static void fastjson(){  
  25.         // 將Java物件序列化為Json字串  
  26.         String objectToJson = JSON.toJSONString(initUser());  
  27.         System.out.println(objectToJson);  
  28.         // 將Json字串反序列化為Java物件  
  29.         User user = JSON.parseObject(objectToJson, User.class);  
  30.         System.out.println(user);  
  31.     }  
  32.       
  33.     private static void jackson() throws Exception{  
  34.         ObjectMapper objectMapper = new ObjectMapper();  
  35.         // 將Java物件序列化為Json字串  
  36.         String objectToJson = objectMapper.writeValueAsString(initUser());  
  37.         System.out.println(objectToJson);  
  38.         // 將Json字串反序列化為Java物件  
  39.         User user = objectMapper.readValue(objectToJson, User.class);  
  40.         System.out.println(user);  
  41.     }  
  42.       
  43.     private static void gson(){  
  44.         Gson gson = new GsonBuilder().create();  
  45.         // 將Java物件序列化為Json字串  
  46.         String objectToJson = gson.toJson(initUser());  
  47.         System.out.println(objectToJson);  
  48.         // 將Json字串反序列化為Java物件  
  49.         User user = gson.fromJson(objectToJson, User.class);  
  50.         System.out.println(user);  
  51.     }  
  52. }  

0 

原文連結:Gson - Getting Started with Java-JSON Serialization & Deserialization
原文出自:Norman Peitek
譯者:無名無

今天開始學習 Google 的 Gson 庫,Gson 是一個非常強大的庫,可以將 JSON 格式的資料轉化成 Java 物件,也支援將 Java 物件轉成 JSON 資料格式。

Gson 依賴

本文將會快速開始使用 Gson 進行序列化操作。由於很多讀者都是 Android 開發人員,我們會提供 Java 環境中的 Gson。在開始之前,我們需要引入 Gson 庫到自己的專案中,最新的版本是 2.8.0.

Gradle 專案新增

compile 'com.google.code.gson:gson:2.8.0'

Maven 專案新增

<dependencies>
    <dependency>
       <groupId>com.google.code.gson</groupId>
       <artifactId>gson</artifactId>
      <version>2.8.0</version>
       <scope>compile</scope>
    </dependency>
</dependencies>

使用 JAR

也支援匯入 JAR 包使用(Eclipse、AS都可以),下載匯入即可,地址: the official GitHub repository

Java-JSON 序列化基礎

先來看一些序列化例子,Gson 中的序列化意味著將 Java 物件對映成 JSON 資料格式,在接下來的教程中,我們會逐步介紹一些更復雜的情況,首先來看一個簡單的例子:

public class UserSimple {
    String name;
    String email;
    int age;
    boolean isDeveloper;
}

UserSimple 物件有四個變數:

  • 字串型別的 name
  • 字串型別的 email
  • 整型的 age(例如:26)
  • 布林型別的 isDeveloper(true or false)

Android 或 Java 應用程式需要將 UserSimple 物件轉換為 JSON 表示,我們期望是這樣的格式:

{
    "name": "Norman",
    "email": "norman@futurestud.io",
    "age": 26,
    "isDeveloper": true
}

來看下我們是如何用 Gson 轉化的,首先要建立一個物件:

UserSimple userObject = new UserSimple(
    "Norman",
    "norman@futurestud.io",
    26,
    true
);

需要用到 Gson 物件,使用以下建構函式來生成 Gson 物件:

Gson gson = new Gson();

使用 Gson 的 torsion() 方法並傳入 UserSimple 物件作為引數:

String userJson = gson.toJson(userObject); 

輸出JSON格式資料

{
    "age": 26,
    "email": "norman@futurestud.io",
    "isDeveloper": true,
    "name": "Norman"
}

可以看到,Gson 改變了變數的順序(按字母順序),但是內容沒變。Gson 中字串被包裝成"",整型沒有被包裝,我們沒有必要弄亂 JSON 物件或者複製單個成員,對於單個物件對映使用 Gson 已經足夠了。也能滿足一些複雜的資料結構。在深入瞭解之前,我們先看一下另一個案例,我們是否可以將 JSON 格式對映成 Java 物件?

Java-JSON 反序列化基礎

String userJson = "{'age':26,'email':'norman@futurestud.io','isDeveloper':true,'name':'Norman'}";

記住在使用的時候將 '替換成",並且建立一個Gson物件:

Gson gson = new Gson();

最後,我們通過 fromJson() 方法將JSON對映成一個 Java 物件:

UserSimple userObject = gson.fromJson(userJson, UserSimple.class);

注意第二個引數的傳遞,否則,Gson 不知道將 JSON 轉換成什麼型別。

Debug:

User Object

下一步 & 目標

本文介紹了 Gson 的基本用法,展示了序列化和反序列化的基本用法和示例,以下是一些可能的問題:

  • Java model 類是否需要一個建構函式/ getter / setter?
  • Java model 欄位是否可以私有的?
  • 如何處理null值?
  • 如果 Java 類和 JSON 資料數量不一致,該怎麼辦?
  • 如何序列化和反序列化陣列和List
  • 如何序列化和反序列化巢狀的物件
  • Gson 在執行.fromJson() 時是否為類屬性保留了一個定義的預設值,如果 JSON 中沒有該欄位的值,將怎麼處理?

不用擔心,接下來我們會解決這些問題,你可以通過評論或 twitter @futurestud_io 反饋你的問題。

練習程式碼已上傳 Github https://github.com/whiskeyfei/Gson-Review 可自行檢視。

相關文章