“嗨,阿米戈!”

“嗨,艾莉!”

“既然你已經了解了 JSON,那麼今天我們就來詳細談談它。”

“好的,一般用在什麼地方?”

“它通常是這樣工作的。某人(客戶端)從 Java 程序(服務器)請求數據。該程序創建 Java 對象並用數據庫中的信息填充它們。然後將它們轉換為請求者(客戶端)可以使用的格式) 可以理解,例如 JSON,並將它們發回。”

“讓我告訴你如何在 Java 中使用 JSON。本質上,我們只需要做兩件事:將 Java 對象序列化為 JSON 格式,以及將 Java 對像從 JSON 格式反序列化。”

“換句話說,JSON 是一種將消息/數據從一個程序發送到另一個程序的標準。有很多這樣的標準。但如果程序是用 JavaScript 編寫的,它通常會嘗試使用 JSON。”

“我準備好了。”

“太好了,那我們開始吧。”

序列化為 JSON - 1

“如您所知,Java 具有內置的標準序列化工具。但它們不支持 JSON。因此,如果您需要將對象序列化為 JSON,您可以使用一種流行的框架(庫),它知道如何做這個。”

“這些不同的框架有什麼區別?”

“它們的複雜程度通常不同:有些框架只能做最基本的事情,但它們又小又簡單。還有一些大型複雜框架可以做更多的事情。”

“Jackson 是最流行的框架之一。我們將以它為例來了解如何使用 JSON。”

“首先,您需要下載此框架並將其添加到您的項目中。您需要直接在 IntelliJ IDEA 中執行此操作。您可以使用此鏈接下載該框架。”

“完畢。”

“太好了,那我們繼續吧。”

“將 Java 對象轉換為 JSON 與序列化它一樣簡單。為此,有一個特殊的 ObjectMapper 類 (com.fasterxml.jackson.databind.ObjectMapper)。”

“讓我給你看一個工作示例,然後我們將對其進行分析:”

將對象轉換為 JSON"
public static void main(String[] args) throws IOException
{
 // Create an object to be serialized into JSON
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;
 cat.weight = 4;

 // Write the result of the serialization to a StringWriter
 StringWriter writer = new StringWriter();

 // This is the Jackson object that performs the serialization
 ObjectMapper mapper = new ObjectMapper();

 // And here's the serialization itself: the first argument is where, and the second is what
 mapper.writeValue(writer, cat);

 // Convert everything written to the StringWriter into a String
 String result = writer.toString();
 System.out.println(result);
}
對象轉換為 JSON 的 Cat 類
@JsonAutoDetect
class Cat
{
 public String name;
 public int age;
 public int weight;
Cat(){}
}
序列化結果和屏幕輸出:
{"name":"Missy", "age":5, "weight":4}

“這是它的工作原理:”

“在第 4-7 行中,我們創建了一個Cat對象並用數據填充它。”

“在第 10 行,我們創建了一個 Writer 對象,我們將在其中寫入該對象的 JSON 字符串表示形式。”

“在第 13 行,我們創建了一個將執行所有序列化的ObjectMapper對象。”

“在第 16 行,我們將cat對象的 JSON 表示寫入writer。”

“在第 19-20 行,我們將結果顯示在屏幕上。”

“一切看起來都很簡單。不比 Java 中的本機序列化更難。”

“反序列化會是什麼樣子?”

“幾乎一樣,只是更短:”

從 JSON 轉換對象
public static void main(String[] args) throws IOException
{
 String jsonString = "{ \"name\":\"Missy\", \"age\":5, \"weight\":4}";
 StringReader reader = new StringReader(jsonString);

 ObjectMapper mapper = new ObjectMapper();

 Cat cat = mapper.readValue(reader, Cat.class);
}
其對像從 JSON 格式反序列化的類
@JsonAutoDetect
class Cat
{
 public String name;
 public int age;
 public int weight;

 Cat() { }
}

“這更容易。我們採用ObjectMapper並向其傳遞一個字符串或一個帶有 JSON 的 StringReader,以及要反序列化的對象的類。然後我們調用readValue方法,作為輸出,我們得到一個現成的 Java 對象所有的數據。”

“嗯,這與 Java 中的反序列化完全一樣。”

“差不多。對序列化為 JSON 或從 JSON 反序列化的對像有幾個要求:”

1) 字段必須可見:它們必須是公開的或具有 getter 和 setter”

2) 必須有一個默認構造函數(一個沒有參數的)”

“我明白了。這並不奇怪。但是 Java 序列化了所有內容,甚至是私有字段。”

“嗯,那是 Java。它可以訪問隱藏數據。你無法躲避自己。”

“這裡還有第三個方面。我希望你注意到 Cat 類上的 @JsonAutoDetect 註釋?”

“是啊。我正想問問那是什麼。”

“這是一個註解:Jackson 框架的內部管理信息。通過使用正確的註解,您可以非常靈活地控制序列化為 JSON 的結果。”

“酷!有什麼註解?”

“這裡有一些例子:”

註解 描述
@JsonAutoDetect 放在課前。
將類標記為準備好序列化為 JSON。
@Json忽略 放置在屬性之前。
該屬性在序列化期間將被忽略。
@JsonProperty 放置在屬性或 getter 或 setter 之前。允許您在序列化期間指定不同的字段名稱。
@JsonWriteNullProperties 放在課前。
不會忽略為空的對象字段。
@JsonPropertyOrder 放在課前。
允許您在序列化期間指定字段順序。

“真有意思!還有嗎?”

“有很多。但我們現在不會介紹它們。現在讓我們稍微修改一下我們的第一個例子:”

將對象轉換為 JSON
public static void main(String[] args) throws IOException
{
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;
 cat.weight = 4;

 StringWriter writer = new StringWriter();

 ObjectMapper mapper = new ObjectMapper();

 mapper.writeValue(writer, cat);

 String result = writer.toString();
 System.out.println(result);
}
對象轉換為 JSON 的類
@JsonAutoDetect
class Cat
{
 @JsonProperty("alias")
 public String name;
 public int age;
 @JsonIgnore
 public int weight;

 Cat() {
 }
}
序列化結果和屏幕輸出:
{"age":5, "alias":"Missy"}

“代碼保持不變,但我更改了註釋:我為名稱字段指定了另一個名稱:別名。我還將權重字段標記為忽略,這導致 JSON 對象發生了變化。”

“你可以像這樣定制一切,這很好。我想我肯定會覺得這很有用。”

“反序列化會理解如何使用它嗎?當從 JSON 反序列化為 Java 對象時,別名字段的值將寫入 Cat 對象的名稱字段?”

“是的,反序列化會正常工作。這很聰明。”

“那有什麼不高興的。”

“謝謝你上了這堂有趣的課,艾莉。”