完全理解Gson(1):简单入门
GSON是Google開發的Java API,用于轉換Java對象和Json對象。本文討論并提供了使用API的簡單代碼示例。更多關于GSON的API可以訪問:http://sites.google.com/site/gson/.
本文是GSON系列文章的第一篇。本文是其他文章的基礎,因此不需要任何GSON或JSON經驗。第二篇文章提供了關于GSON反序列化(從JSON到Java)的示例,第三篇文章提供了關于GSON序列化(從Java到JSON)的示例。
下面列出的所有代碼都可以在https://java-creed-examples.googlecode.com/svn/gson/Simple%20Gson%20Example. 找到。絕大部分示例都不會包含全部的代碼,可能會忽略一些片段,這些片段都與討論的示例無關。讀者可以從上面的鏈接下載或查閱所有代碼。
讀者需要有基礎的Java(教程)知識和很基礎的Maven(首頁)知識。這里展示的代碼使用maven來下載GSON庫。把項目導入到Springsource Tool Suite(推薦的IDE),無需任何配置。
下載與安裝
在使用GSON API工作之前,你需要下載庫(jar文件),并將其包含到類路徑中。庫,連同源代碼和Java文檔,都可以從http://code.google.com/p/google-gson/downloads/list下載。下載完畢后,添加gson-<version>.jar到類路徑。對于那些偏好使用Maven管理依賴(JAR文件)的讀者,添加如下依賴到pom.xml。
| 1 2 3 4 5 | <dependency> ????<groupId>com.google.code.gson</groupId> ????<artifactId>gson</artifactId> ????<version>2.2.4</version> </dependency> |
需要修改?<version>2.2.4</version>。本文所有代碼示例使用上面列出的版本。pom.xml文件拷貝可以在這里找到。
如果這個庫用于web應用,請確保在WEB-INF/lib文件夾中保持一份拷貝?;蛘?#xff0c;GSON庫可以放到應用服務器提供給web應用。
一個簡單示例
GSON API提供一個類文件,Gson(Java文檔),它被用來處理Java和JSON對象的轉換??梢哉{用默認構造器,或如下代碼的形式,使用GsonBuilder(Java文檔)類創建這個類的實例。GsonBuilder類是可定制化的,并且允許開發者按需實例化Gson。
| 1 2 3 4 5 6 7 8 9 10 11 12 | package com.javacreed.examples.gson.part1; import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class SimpleExample1 { ????public static void main(String[] args) { ????????Gson gson = new GsonBuilder().create(); ????????gson.toJson("Hello", System.out); ????????gson.toJson(123, System.out); ????} } |
在上面的例子中,我們創建了一個Gson實例,并把Java String和int轉化為JSON對象。以上代碼命令行里的輸出結果如下:
| 1 | "Hello"123 |
這不是火箭科學,但它是一個開始。注意,上述的結果都將輸入到命令行。該toJason()方法有兩個參數,Java對象轉換為JSON和可追加(Java的文檔)的一個實例。我們可以很容易地改變了一個文件或網絡流。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package com.javacreed.examples.gson.part1; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class SimpleExample2 { ????public static void main(String[] args) throws IOException { ????????Writer writer = new FileWriter("Output.json"); ????????Gson gson = new GsonBuilder().create(); ????????gson.toJson("Hello", writer); ????????gson.toJson(123, writer); ????????writer.close(); ????} } |
注意
為什么變量聲明為Writer類型,而實際類型是FileWriter?
盡量使用泛型是一個很好的方法。在上例中,我們只使用了Appendable和Writer接口定義的方法。使用泛型使代碼更易于移植和維護,下面是個不好的例子。
注意,上面例子中,我們沒有正確處理流(Writer)。理想情況下,資源在finaly塊 (教程)?中關閉或者用在try-with-resource(教程)中。我們忽略了這個是為了保持代碼簡潔。
| 1 2 3 4 5 6 7 | public static void main(String[] args) throws IOException { ????try (Writer writer = new FileWriter("Output.json")) { ????????Gson gson = new GsonBuilder().create(); ????????gson.toJson("Hello", writer); ????????gson.toJson(123, writer); ????} } |
以上代碼生成文件:包含JSON對象的Output.json。注意,這里我們使用了字符流而不是字節流。因為toJson()方法需要一個Appendanble實例,而字節流不能實現Appendable接口,所以我們使用了字符流。Appendable接口處理字符而不是字節。Java提供了InputStreanReader(Java文檔)和OutputStreamWriter(Java文檔)類進行字節流與字符流的轉換,如下面的例子。
注意
注意,使用InputStreamREader和OutputStreamWriter類時,如果不提供編碼或者字符集,轉換將使用平臺默認字符集。這將降低代碼的可移植性,且在其他平臺上運行將可能產生錯誤行為。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package com.javacreed.examples.gson.part1; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class SimpleExample3 { ????public static void main(String[] args) throws IOException { ????????try(Writer writer = new OutputStreamWriter(new FileOutputStream("Output.json") , "UTF-8")){ ????????????Gson gson = new GsonBuilder().create(); ????????????gson.toJson("Hello", writer); ????????????gson.toJson(123, writer); ????????} ????} } |
如你所見,我們只需要改變實例的一部分。代碼的剩余部分沒有任何變化。這就是使用接口代替類作為變量類型的好處之一。
使用JSON對象
比方說,我們需要使用JSON對象并加載他們為Java對象。假設web服務器查詢時產生如下JSON對象:
| 1 2 3 4 5 | { ??NAME:"Albert Attard", ??P_LANGUAGE:"Java", ??LOCATION:"Malta" } |
此JSON對象包含3個不同值的域。比如我們需要使用JSON對象并創建一個Java對象來展示它。為了使這個例子更有趣,假設我們只關心name和location域。
首先創建一個Java類來表示name和location。類命名為Person。類的名字無關緊要,但域的名字必須一致。域名必須匹配(大小寫敏感)JSON對象中的名字。更進一步,類必須包含一個默認構造函數(即使它被設置為private)。如下所示,name和location域在JSON中是大寫的。JSON中域P_LANGUAGE被忽略了,因為Java對象中不包括該名稱的域。請理解域名不遵守Java命名規范,暫時只是為了簡化。更多內容將在第2部分中討論。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package com.javacreed.examples.gson.part2; public class Person { ????private String NAME; ????private String LOCATION; ????// Getters and setters are not required for this example. ????// GSON sets the fields directly using reflection. ????@Override ????public String toString() { ????????return NAME + " - " + LOCATION; ????} } |
準備好Java對象后,我們可以讀取JSON對象并加載為Java對象,如下代碼所示。為了模擬真實情況,我們使用了字節流作為輸入。還要注意,JSON內容保存在resource文件夾的文件里(這不是常規做法)。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package com.javacreed.examples.gson.part2; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class JsonToJava { ????public static void main(String[] args) throws IOException { ????????try(Reader reader = new InputStreamReader(JsonToJava.class.getResourceAsStream("/Server1.json"), "UTF-8")){ ????????????Gson gson = new GsonBuilder().create(); ????????????Person p = gson.fromJson(reader, Person.class); ????????????System.out.println(p); ????????} ????} } |
輸出如下:
| 1 | Albert Attard - Malta |
Gson解析JSON對象并創建了一個Person類的實例,并打印到命令行中。
嵌套JSON對象
讓我們對上面的例子更進一步,以下所示JSON代碼段包含了一個嵌套對象。
| 1 2 3 4 5 6 7 8 9 | { ??NAME:"Albert Attard", ??P_LANGUAGE:"Java", ??LOCATION:"Malta", ??EXAM: { ????SUBJECT:"Programming", ????GRADE:4.5 ??} } |
EXAM域由兩個域組成,分別是SUBJECT和GRADE。我們需要修改Person類的定義來包含EXAM域,并創建一個新的Java類來表示EXAM,該類包含SUBJECT和GRADE域。
我們首先創建新的類來表示嵌套對象。就像之前討論那樣,類名無關緊要,但是域名必須與JSON中的域名匹配。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package com.javacreed.examples.gson.part3; public class Exam { ????private String SUBJECT; ????private double GRADE; ????// Getters and setters are not required for this example. ????// GSON sets the fields directly using reflection. ????@Override ????public String toString() { ????????return SUBJECT + " - " + GRADE; ????} } |
現在我們可以修改Person類,引入一個與JSON中EXAM同名的域,類型為Exam。注意,下面的Person類與前一個<span style=”color: #ff0000;”>位于</span>不同的包。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | package com.javacreed.examples.gson.part3; public class Person { ????private String NAME; ????private String LOCATION; ????private Exam EXAM; ????@Override ????public String toString() { ????????return NAME + " - " + LOCATION + " (" + EXAM + ")"; ????} } |
注意,所需的變化是最小的,因為Gson動態發現(使用反射)類和它的域。本文不包含反射,對于更多關于反射的信息,請參考:Reflection in Action.
最后,讓我們嘗試新的變化。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package com.javacreed.examples.gson.part3; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class JsonToJava { ????public static void main(String[] args) throws IOException { ????????try(Reader reader = new InputStreamReader(JsonToJava.class.getResourceAsStream("/Server2.json"), "UTF-8")){ ????????????Gson gson = new GsonBuilder().create(); ????????????Person p = gson.fromJson(reader, Person.class); ????????????System.out.println(p); ????????} ????} } |
JsonToJava類沒有做任何改變,因為Gson使用了模型(Person和Exam類)將Json映射成Java。
結論
即使JSON可能是一個新概念,但它十分簡單與直接。此外,相比于需要增加標簽進行消息/數據轉換而不斷膨脹的笨重的XML,它因為簡單更加流行。需要指出JSON是JavaScript的一個子集,JavaScript將它作為一個完美的方案來進行數據交換,例如網頁。GSON API使它更便于使用,即使在這里沒有討論的部分,它也提供了強大的靈活性。
欲了解更多GSON的例子,請移步第2部分,我們會探索更復雜的例子,并討論如何使用GSON解串器來完全控制反序列化過程。
相關文章
- GSON Annotations Example
- Gson TypeAdapter Example Serialise Large Objects
- GSON Serialiser Example
- Gson TypeAdapter Example
- GSON Deserialiser Example
原文鏈接:?javacreed?翻譯:?ImportNew.com?-?liken
譯文鏈接:?http://www.importnew.com/16630.html
?
from:?http://www.importnew.com/16630.html
轉載于:https://www.cnblogs.com/GarfieldEr007/p/6821667.html
總結
以上是生活随笔為你收集整理的完全理解Gson(1):简单入门的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第二十九节 MT-iBeacon基站关
- 下一篇: 如何去除微信小程序 wxParse 解析