Gson 的使用(一)

一葵诈、前言:

下一篇:Gson 的封裝使用(二): http://www.reibang.com/p/9f37bcb2274d

GSON是Google提供的用來(lái)在Java對(duì)象和JSON數(shù)據(jù)之間進(jìn)行映射的Java類庫(kù)”优洌可以將一個(gè)Json字符轉(zhuǎn)成一個(gè)Java對(duì)象,或者將一個(gè)Java轉(zhuǎn)化為Json字符串糊肠。
JSON 是一種文本形式的數(shù)據(jù)交換格式擂啥,它比XML更輕量扳还、比二進(jìn)制容易閱讀和編寫,調(diào)式也更加方便;解析和生成的方式很多橱夭。
Java中最常用的類庫(kù)有:JSON-Java氨距、Gson、Jackson棘劣、FastJson等
特點(diǎn):

  1. 快速俏让、高效
  2. 代碼量少、簡(jiǎn)潔
  3. 面向?qū)ο?/li>
  4. 數(shù)據(jù)傳遞和解析方便

二茬暇、使用

1.Gson 的依賴

implementation 'com.google.code.gson:gson:2.8.4'

2.Gson的創(chuàng)建方式:

方式一:

Gson gson = new Gson();

方式二:通過(guò)GsonBuilder()首昔,可以配置多種配置

Gson gson = new GsonBuilder()
   .setLenient()// json寬松  
   .enableComplexMapKeySerialization()//支持Map的key為復(fù)雜對(duì)象的形式  
   .serializeNulls() //智能null  
   .setPrettyPrinting()// 調(diào)教格式  
   .disableHtmlEscaping() //默認(rèn)是GSON把HTML 轉(zhuǎn)義的
   .create();  

3. Gson的基本用法

Gson提供了fromJson() 和toJson() 兩個(gè)直接用于解析和生成的方法,前者實(shí)現(xiàn)反序列化糙俗,后者實(shí)現(xiàn)了序列化勒奇;同時(shí)每個(gè)方法都提供了重載方法

(1)基本數(shù)據(jù)類型的解析

Gson gson = new Gson();
int i = gson.fromJson("100", int.class); //100
double d = gson.fromJson("\"99.99\"", double.class);  //99.99
boolean b = gson.fromJson("true", boolean.class);     // true
String str = gson.fromJson("String", String.class);   // String

(2)基本數(shù)據(jù)類型的生成

Gson gson = new Gson();
String jsonNumber = gson.toJson(100);       // 100
String jsonBoolean = gson.toJson(false);    // false
String jsonString = gson.toJson("String"); //"String"

4. 簡(jiǎn)單的 Java Object 序列化

假如有一個(gè)User類,擁有 name, email, age, isDeveloper 四個(gè)屬性巧骚,如下:

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

使用Gson將它序列化:

Gson gson = new Gson();
String userJson = gson.toJson(userObject);

得到的結(jié)果如下:

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

5. 簡(jiǎn)單的 Java Object 反序列化

先定義一段JSON字符串

String userJson = "{'isDeveloper':false,'name':'xiaoqiang','age':26,'email':'578570174@qq.com'}";

Gson反序列化

User user = gson.fromJson(userJson, User.class);

debug一下赊颠,查看結(jié)果

image.png

6. 嵌套 Java Object 的序列化/反序列化

也就是說(shuō),一個(gè)類里面還包含有其它類劈彪。比如User類里面還有個(gè)用戶地址UserAddress類竣蹦,JSON結(jié)構(gòu)如下:

{
    "age": 26,
    "email": "578570174@qq.com",
    "isDeveloper": true,
    "name": "chenrenxiang",

    "userAddress": {
        "city": "Magdeburg",
        "country": "Germany",
        "houseNumber": "42A",
        "street": "Main Street"
    }
}

那么這種Java Object該如何序列化/反序列化呢?和上面一樣沧奴。

7. Array 和 List 的序列化/反序列化

序列化
序列化和前面介紹的方法是一樣的

反序列化
那就有些不同了痘括,不然也不用分開寫。

1. Array的反序列化
先假設(shè)有一個(gè)name數(shù)組扼仲,定義JSON格式如下:

String namesJson = "['xiaoqiang','chenrenxiang','hahaha']";

然后使用Gson去反序列化它:

Gson gson = new Gson();
String[] nameArray = gson.fromJson(namesJson, String[].class);

得到的nameArray如下:

image.png

其實(shí)這和 2 里面介紹的反序列化方法仍然是一樣的远寸。可以看到屠凶,Gson的反序列化都是調(diào)用 Gson.fromJson(...)方法驰后,傳入JSON字符串,以及這段JSON字符串對(duì)應(yīng)的Object類型矗愧。

2 . List的反序列化

String userJson = "[{'isDeveloper':false,'name':'xiaoqiang','age':26,'email':'578570174@qq.com'},{'isDeveloper':true,'name':'xiaoqiang123','age':27,'email':'578570174@gmail.com'}]";

Gson gson = new Gson();
Type userListType = new TypeToken<ArrayList<User>>(){}.getType();

List<User> userList = gson.fromJson(userJson, userListType); 

對(duì)于List灶芝,反序列化時(shí)必須提供它的Type,通過(guò)Gson提供的TypeToken<T>.getType()方法可以定義當(dāng)前List的Type唉韭。反序列化后結(jié)果如下:

image.png

那么夜涕,如果一個(gè)Java Object里包含List類型的變量,該如何反序列化這個(gè)Object呢属愤?答案是女器,和 2 一樣就行了,無(wú)需為其內(nèi)部的List提供Type住诸。

8. Map 和 Set 的序列化/反序列化

Map我平時(shí)用的較多驾胆,Set用的就很少了涣澡,它們的序列化/反序列化方法和List都是一樣的,反序列化的時(shí)候需要提供Type

9.變量值為null時(shí)的序列化/反序列化

仍然以User類為例丧诺,如果一個(gè)User對(duì)象入桂,里面的某個(gè)值為null,那么其序列化出來(lái)后的結(jié)果會(huì)是什么樣的呢驳阎?

先看序列化抗愁,我們先初始化一個(gè)User對(duì)象,并把其中的email變量賦值為null呵晚,再用Gson來(lái)序列化它蜘腌,如下:

 User user = new User(true, "chenrenxiang", 27, null);
 Gson gson = new Gson();
 String userJson = gson.toJson(user);

debug一下,得到結(jié)果如下:

image.png

可見饵隙,當(dāng)某個(gè)變量值為null時(shí)逢捺,Gson在序列化的時(shí)候直接把這個(gè)變量忽略了。

再來(lái)看下反序列化癞季, 先定義一段JSON字符串,只給它一個(gè)變量值name倘潜,用User類來(lái)反序列化它绷柒,看得到的結(jié)果會(huì)是什么。

String userJson = "{'name':'xiaoqiang'}";
   Gson gson = new Gson();
   User user = gson.fromJson(userJson, User.class);
image.png

對(duì)于JSON字符串里沒有的變量涮因,Gson在反序列化時(shí)會(huì)給它一個(gè)默認(rèn)值废睦,int類型默認(rèn)為0,bool類型默認(rèn)為false养泡,String類型默認(rèn)為null嗜湃。

有人不禁要問(wèn)了,如果JSON字符串里某個(gè)變量的值為null澜掩,反序列化后的結(jié)果會(huì)是什么呢购披?我測(cè)試過(guò)了,和沒有的結(jié)果是一樣的肩榕。

9. 控制序列化/反序列化 的變量名稱

仍然以User對(duì)象為例刚陡,目前User對(duì)象里有四個(gè)變量name, age株汉, email筐乳, isDeveloper。假如乔妈,某一天蝙云,JSON字符串的變量名name變成了fullName,無(wú)需緊張路召,我們不用把User類里的變量name改為fullName勃刨,然后把它的get和set方法都改了波材,然后把用到get/set方法的地方全改過(guò)來(lái)。只需要用Gson提供的注解方法@SerializedName就行了朵你,如下:

public class User {
    private boolean isDeveloper;
    @SerializedName("fullName")
    private String name;
    private int age;
    private String email;
    ...
}

這樣雖然JSON字符串里的變量名為fullName各聘,但是反序列化后fullName的值會(huì)映射給name。同樣抡医,把一個(gè)User對(duì)象序列化躲因,變量name會(huì)自動(dòng)轉(zhuǎn)換為fullName。

然而現(xiàn)實(shí)遠(yuǎn)比想象中復(fù)雜忌傻,這個(gè)JSON有時(shí)候傳的是fullName大脉,有時(shí)候傳的是name,這時(shí)該怎么辦呢水孩? 不用擔(dān)心镰矿,@SerializedName 接受兩個(gè)參數(shù),value 和 alternate 俘种,顧名思義秤标,alternate 是備選變量名,比如下面這段代碼:

public class User {
    private boolean isDeveloper;
    @SerializedName(value = "name", alternate = "fullName")
    private String name;
    private int age;
    private String email;
    ...
}

如果JSON傳的是name宙刘,那么就用name的值苍姜,如果傳的是fullName,那么就用fullName的值悬包。需要注意的是衙猪,alternate只是反序列化JSON的一個(gè)備選變量名,它不會(huì)影響序列化布近,User對(duì)象序列化后垫释,會(huì)使用value定義的名稱為變量名。

又想到有一個(gè)問(wèn)題撑瞧,在定義了value和alternate的情況下棵譬,假如JSON同時(shí)傳來(lái)了name和fullName,User的name變量會(huì)接受哪個(gè)值呢季蚂? 經(jīng)過(guò)測(cè)試茫船,它會(huì)都接受。這樣也是很合理的扭屁,因?yàn)镚son會(huì)對(duì)JSON中的變量一個(gè)一個(gè)地去解析算谈,既然它可以接受name,也可以接受fullName料滥,那么當(dāng)同時(shí)傳來(lái)這兩個(gè)變量時(shí)然眼,它就會(huì)分別把它們解析出來(lái),并把值賦給User對(duì)象中的name變量葵腹。那么高每,name變量的值就會(huì)是后解析的那個(gè)JSON變量的值屿岂,因?yàn)樗鼤?huì)把前一個(gè)值覆蓋掉。

10. 序列化/反序列化過(guò)程中忽略某些變量

也許會(huì)出現(xiàn)這樣的需求鲸匿,在將某個(gè)對(duì)象序列化時(shí)爷怀,對(duì)象中的某些變量是不需要的。有可能在反序列化某個(gè)JSON字符串時(shí)带欢,某些變量的值也是不需要的运授。這時(shí)就可以使用Gson提供的@Expose注解方法。使用方法如下:

public class User {  
    @Expose()
    String name; // 參與序列化/反序列化

    @Expose(serialize = false, deserialize = false)
    String email; // 不參與序列化,也不參與反序列化

    @Expose(serialize = false)
    int age; // 只參與反序列化

    @Expose(deserialize = false)
    boolean isDeveloper; // 只參與序列化
}

使用這個(gè)方法,可以非常靈活地控制對(duì)象的某個(gè)/某些變量參不參與序列化/反序列化宁炫。

然而! 要使用這個(gè)注解來(lái)控制序列化/反序列化祟印,就不能使用默認(rèn)的Gson對(duì)象,新建Gson對(duì)象的方法如下:

GsonBuilder builder = new GsonBuilder();  
builder.excludeFieldsWithoutExposeAnnotation();  
Gson gson = builder.create(); 

另一個(gè)選擇,transient關(guān)鍵字 ,使用這個(gè)關(guān)鍵字纺讲,可以直接讓變量不參與序列化/反序列化,如下:

public class User {  
    String name;
    String email;
    int age;
    boolean transient isDeveloper; //不參與序列化/反序列化
}

當(dāng)然囤屹,使用默認(rèn)的Gson對(duì)象就可以刻诊。

官網(wǎng)地址:https://futurestud.io/tutorials/gson-builder-basics-naming-policies

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市牺丙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌复局,老刑警劉巖冲簿,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異亿昏,居然都是意外死亡峦剔,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門角钩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)吝沫,“玉大人,你說(shuō)我怎么就攤上這事递礼〔蚁眨” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵脊髓,是天一觀的道長(zhǎng)辫愉。 經(jīng)常有香客問(wèn)我,道長(zhǎng)将硝,這世上最難降的妖魔是什么恭朗? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任屏镊,我火速辦了婚禮,結(jié)果婚禮上痰腮,老公的妹妹穿的比我還像新娘而芥。我一直安慰自己,他們只是感情好膀值,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布棍丐。 她就那樣靜靜地躺著,像睡著了一般虫腋。 火紅的嫁衣襯著肌膚如雪骄酗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天悦冀,我揣著相機(jī)與錄音趋翻,去河邊找鬼。 笑死盒蟆,一個(gè)胖子當(dāng)著我的面吹牛踏烙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播历等,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼讨惩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了寒屯?” 一聲冷哼從身側(cè)響起荐捻,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎寡夹,沒想到半個(gè)月后处面,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡菩掏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年魂角,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片智绸。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡野揪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瞧栗,到底是詐尸還是另有隱情斯稳,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布迹恐,位于F島的核電站平挑,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜通熄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一唆涝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧唇辨,春花似錦廊酣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至饿幅,卻和暖如春凡辱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背栗恩。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工透乾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人磕秤。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓乳乌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親市咆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子汉操,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • Android中Gson的使用 1 簡(jiǎn)介 Gson是一個(gè)Java庫(kù),作用是將Java對(duì)象轉(zhuǎn)換成它對(duì)應(yīng)的JSON表示...
    LuckyXiang閱讀 19,890評(píng)論 2 3
  • 關(guān)于json蒙兰,gson是最常用到的一個(gè)庫(kù)磷瘤。平常使用時(shí)我通常使用Gson gson = new Gson();的方式...
    黑泥卡閱讀 10,071評(píng)論 1 14
  • 序列化對(duì)象: Gson gson = new Gson();String json = gson.toJson(o...
    胖胖胖胖胖胖胖胖胖閱讀 1,130評(píng)論 0 0
  • 翻譯自JavaCreed首先看一個(gè)Json字符串 如果我們不使用Gson注解@SerializeName,那怎么來(lái)...
    董成鵬閱讀 3,090評(píng)論 0 1
  • 【前言】最近項(xiàng)目中對(duì)數(shù)據(jù)的解析都使用了Gson搜变,艸蛋的是每次都要手寫JavaBean對(duì)象很麻煩膀斋。抱著能否簡(jiǎn)化的心態(tài)...
    erki_stwee閱讀 1,041評(píng)論 0 0