原文鏈接:Getting Started with Java-JSON Serialization & Deserialization
翻譯:簽到錢就到
在發(fā)布了50多篇Retrofit的文章之后,收到很多讀者的反饋,要求我們對(duì)Google的Gson做一個(gè)擴(kuò)展介紹。Gson是一個(gè)將JSON格式的數(shù)據(jù)結(jié)構(gòu)映射成java對(duì)象的非常強(qiáng)大的庫(kù)。當(dāng)然,它也支持其他組織的方式,并且也能為你的java對(duì)象創(chuàng)建合適的JSON表示形式。
如果你對(duì)我們正在進(jìn)行的這個(gè)系列感興趣,請(qǐng)瀏覽一下下面的大綱。
Gson系列概覽
- Gson——用java-JSON實(shí)現(xiàn)序列化和反序列化
- Mapping of Nested Objects
- Mapping of Arrays and Lists of Objects
- Mapping of Maps
- Mapping of Sets
- Mapping of Null Values
- Gson Model Annotations — How to Ignore Fields with @Expose
- Gson Model Annotations — How to Change the Naming of Fields with @SerializedName
- Gson Builder — Basics & Naming Policies
- Gson Builder — Force Serialization of null Values
- Gson Builder — Exclusion Strategies
- Gson Builder — Relax Gson with Lenient
- Gson Builder — Special Values of Floats & Doubles
- Gson Builder — Model Versioning
- Gson Builder — Formatting of Dates & Custom Date/Time Mapping
- Gson Builder — Pretty Printing
- Gson Builder — HTML Escaping
Gson 依賴
本指南將要著手,首先在一分鐘內(nèi)完成一些序列化的準(zhǔn)備工作。
由于大多數(shù)讀者都是Android開發(fā)者,我們會(huì)為你量身定制,但是Gson也能被用在任何Java環(huán)境中。在我們開始之前,我們需要將Gson庫(kù)拖到我們的項(xiàng)目工程中。截止到寫作時(shí)間,最新的版本是2.6.2。如果你正在使用Gradle,添加下面的代碼:
compile 'com.google.code.gson:gson:2.6.2'
如果你正在使用Maven,你可以添加下面的依賴:
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
<scope>compile</scope>
</dependency>
</dependencies>
對(duì)于那些都沒有使用依賴環(huán)境系統(tǒng)的可憐家伙,你可以從官方的Github倉(cāng)庫(kù)里下載jar包。
Java-JSON序列化基礎(chǔ)
讓我們做一些系列化!在Gson中序列化是指映射一個(gè)java對(duì)象到它的JSON表達(dá)。在后續(xù)的教程中,我們的數(shù)據(jù)將會(huì)變得更復(fù)雜,但是我們現(xiàn)在只要從一些非常簡(jiǎn)單的UserSimple開始:
public class UserSimple {
String name;
String email;
int age;
boolean isDeveloper;
}
user對(duì)象有四個(gè)屬性:
- user的
name是一個(gè) String 對(duì)象 - user的
email是一個(gè) String 對(duì)象 - user的
age是一個(gè) integer, 表明是按年來表示的(例如26,并非準(zhǔn)確的生日!) - 一個(gè) boolean 標(biāo)簽
isDeveloper
我們的Android或java應(yīng)用需要轉(zhuǎn)換一個(gè)UserSimple對(duì)象到它的JSON表示。假設(shè)我們保持成員變量名字一致,我們會(huì)為Norman(這篇文章的作者)準(zhǔn)備這樣的JSON表示:
{
"name": "Norman",
"email": "norman@futurestud.io",
"age": 26,
"isDeveloper": true
}
讓我們研究怎么用Gson完成轉(zhuǎn)換。首先,我們需要為Norman創(chuàng)建一個(gè)Java對(duì)象。
UserSimple userObject = new UserSimple(
"Norman",
"norman@futurestud.io",
26,
true
);
譯者注:如果沒有在UserSimple類里添加對(duì)應(yīng)的構(gòu)造函數(shù),上面會(huì)報(bào)錯(cuò)。添加也很簡(jiǎn)單,UserSimple類內(nèi)部編輯界面,右鍵—>Generate->Constructor->全部選中 ,點(diǎn)擊ok。自動(dòng)生成如下代碼:
public UserSimple(String name, String email, int age, boolean isDeveloper) {
this.name = name;
this.email = email;
this.age = age;
this.isDeveloper = isDeveloper;
}
為了完成序列化,我們需要一個(gè)Gson對(duì)象來操作轉(zhuǎn)換。我們可以簡(jiǎn)單的使用下面的創(chuàng)建:
Gson gson = new Gson();
為了開始序列化,我們需要調(diào)用toJson()方法,然后傳遞UserSimple對(duì)象:
String userJson = gson.toJson(userObject);
userJson對(duì)象包含了下面的值:
{
"age": 26,
"email": "norman@futurestud.io",
"isDeveloper": true,
"name": "Norman"
}
Gson改變了屬性的順序(按字母順序),但是內(nèi)容是一樣的!注意Gson是如何表示這些類型的。String值用“”包裹,但integer值卻沒有包裹。我們不需要在JSON對(duì)象或復(fù)制單個(gè)成員上浪費(fèi)時(shí)間。一個(gè)Gson的簡(jiǎn)單調(diào)用足以映射整個(gè)對(duì)象。當(dāng)我們處理非常復(fù)雜的數(shù)據(jù)結(jié)構(gòu)時(shí),這是非常方便的。但在我們進(jìn)一步深入之前,我們測(cè)試另一個(gè)方向。Gson可以從上面的JSON數(shù)據(jù)中創(chuàng)建一個(gè)java對(duì)象么?
java-JSON 反序列化基礎(chǔ)
首先,我們需要?jiǎng)?chuàng)建一個(gè)字符串,包含上面提到的JSON:
String userJson = "{'age':26,'email':'norman@futurestud.io','isDeveloper':true,'name':'Norman'}";
我們將 "變?yōu)?' ,是為了避免大量的\"轉(zhuǎn)義。它就是這樣工作的。下一步,可能你已經(jīng)猜到了,創(chuàng)建一個(gè)Gson實(shí)例:
Gson gson = new Gson();
最后,我們必須用fromJson()映射一個(gè)JSON到一個(gè)Java對(duì)象:
UserSimple userObject = gson.fromJson(userJson, UserSimple.class);
注意我們是怎樣將Java對(duì)象作為第二個(gè)參數(shù)進(jìn)行傳遞。否則Gson不知道應(yīng)該將JSON映射。它不是一個(gè)魔術(shù)師!
如果我們添加了一個(gè)debugger并且檢查了user對(duì)象的結(jié)果,它會(huì)展示Gson成功地準(zhǔn)確映射了所有屬性:
計(jì)劃 與 展望
看完這篇引導(dǎo)文章后,你應(yīng)該已經(jīng)了解了Gson的基本使用。我們已經(jīng)展示了如何簡(jiǎn)單地完成JSON數(shù)據(jù)與Java的映射。我們也知道你此刻肯定有大量的問題要問:
- Java模型類需要一個(gè)constructor/getter/setter么?
- Java模型字段可以是私有(private)的么?
- 怎樣處理空值(null values)?
- 對(duì)于JSON數(shù)據(jù),如果Java類有不同的變量命名怎么辦?
- 如何序列化(反序列化)對(duì)象數(shù)組/列表?
- 如何序列化(反序列化)嵌套對(duì)象?
- 當(dāng)執(zhí)行
.fromJson()時(shí),JSON數(shù)據(jù)中獲取不到某個(gè)屬性的值,Gson會(huì)為其保留一個(gè)默認(rèn)的值么?
沒必要擔(dān)心,我們會(huì)在后續(xù)的文章中一一解答。如果你有特別的主題,在下面的評(píng)論中或twitter@futurestud_io讓我們知道。