Gson教程七(譯):@SerializedName和@Expose

該文章翻譯自Gson Tutorial Series系列教程。該篇探究的是如何使用如何使用@Expose忽略某些域以及使用@SerializedName改變域名。

使用@Expose忽略某些域

@Expose注解模型

在閱讀了之前關(guān)于處理空值的教程后,你可能會(huì)想,你能夠?qū)⒁粋€(gè)Java對(duì)象設(shè)置為空值,但如何才能夠使之不出現(xiàn)在JSON中呢?這在你不想傳送你的私有或者敏感數(shù)據(jù)到網(wǎng)絡(luò)上時(shí)是必要的。不用擔(dān)心,Gson提供的@Expose注解能輕松解決這個(gè)問題。

@Expose注解是可選擇的并且提供了兩個(gè)配置參數(shù):serializedeserialize。默認(rèn)情況下,它們都設(shè)置為true。因此,你不用強(qiáng)制給每個(gè)成員變量添加@Expose注解,就像我們之前做的,所有成員變量會(huì)默認(rèn)添加。如果你添加了@Expose注解,而沒有設(shè)置任何值為false,該成員變量也會(huì)默認(rèn)包含的。

讓我們重新看一下UserSimple類,然后添加@Expose注解:

public class UserSimple {  
    @Expose()
    String name; // equals serialize & deserialize

    @Expose(serialize = false, deserialize = false)
    String email; // equals neither serialize nor deserialize

    @Expose(serialize = false)
    int age; // equals only deserialize

    @Expose(deserialize = false)
    boolean isDeveloper; // equals only serialize
}

上例中,序列化的結(jié)果將只有nameisDeveloper會(huì)出現(xiàn)在JSON中。其他兩個(gè)域,即使它們設(shè)置了,也不會(huì)轉(zhuǎn)換。

在反序列化過程中,Java對(duì)象將只會(huì)擁有JSON中的nameage域,emailisDeveloper將會(huì)被忽略。

默認(rèn)情況下,Gson實(shí)例會(huì)忽略掉@Expose注解。為了使用它,你需要自定義Gson實(shí)例:

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

遵循此用法的gson才會(huì)注重Expose注解。

@Expose注解使得你可以輕松的空值哪些值可以被序列化和反序列化。建議在需要轉(zhuǎn)換所有值得情況下不要使用@Expose標(biāo)簽。它僅僅會(huì)毀掉你的模型類。

Transient

@Expose的替代方法是在定義成員變量時(shí)添加transient關(guān)鍵字。添加了該關(guān)鍵字的成員變量將不會(huì)被轉(zhuǎn)換。然而,你并不能像@Expose那樣完全掌控。你不能使一個(gè)方向運(yùn)行而反方向又不能運(yùn)行,transient將使得該域既不能序列化也不能反序列化。

public class UserSimple {  
    String name;
    String email;
    int age;
    boolean transient isDeveloper; // will not be serialized or deserialized
}

使用@SerializedName注解改變域名

@SerializedName注解模型

@SerializedName是一個(gè)非常有用的注解。它改變了Java-JSON序列化和反序列化過程中的自動(dòng)匹配。到目前為止,我們經(jīng)常假設(shè)Java模型類和JSON有相同的“名”。然而,并不總是如此??赡苁悄銢]有獲得繼承Java模型類的允許,也可能是你必須遵循公司的命名規(guī)則,無論哪種情況,你都可以使用@SerializedName以使得Gson能夠正確的匹配。

讓我們看個(gè)例子。我們的UserSimple類已經(jīng)去掉了@Expose,它可以映射所有域了。

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

然而,讓我們花點(diǎn)時(shí)間想象一下,API實(shí)現(xiàn)以及它所返回的JSON已經(jīng)改變了。我們的API不再會(huì)返回name而是返回了fullName:

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

不用擔(dān)心,我們并不需要改變我們的基礎(chǔ)代碼,我們僅僅需要在我們的模型中添加一個(gè)簡單的注解:

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

在該注解的幫助下,Gson又可以映射良好了,我們又可以享受自動(dòng)化帶來的好處了。

當(dāng)然,你可以使用@SerializedName去遵從你們公司的命名規(guī)則,但是依然可以正確匹配任何API。這在命名規(guī)則非常不同時(shí)是有用的。

使用@SerializedName反序列化多個(gè)名稱

在之前的博客中,我們已經(jīng)介紹了如何在序列化和反序列化過程中改變一個(gè)模型的屬性名。如果你的服務(wù)器希望接收或者發(fā)送的屬性名是不一樣的,那么你可以使用@SerializedName

在這篇博客中,我們將想你展示,如何實(shí)現(xiàn)一個(gè)屬性對(duì)應(yīng)多個(gè)名稱的映射。這在你的應(yīng)用需要與多個(gè)API通信時(shí)是非常有用的。盡管這些API使用不同的名稱描述了相同的事情,你依然可以只使用一個(gè)Java模型類。

擴(kuò)展@SerializedName注解模型

在介紹@SerializedName的第一篇博客中,我們向你介紹了如下用法:

public class UserSimple {  
    @SerializedName("fullName")
    String name;

    String email;
    boolean isDeveloper;
    int age;
}

你為該模型的一個(gè)屬性添加了一個(gè)注解,并且向序列化和反序列化傳遞了一個(gè)字符串名。

但這并不是全部!SerializeName接收兩個(gè)參數(shù):valuealternate。前者使用了默認(rèn)的參數(shù)。如果你僅僅傳入了一個(gè)字符串,那么將該字符串設(shè)置給valuealternate設(shè)置為空值。但是你可以給這兩個(gè)參數(shù)傳遞值:

public class UserSimpleSerializedName {  
    @SerializedName(value = "fullName", alternate = "username")
    private String name;

    private String email;
    private boolean isDeveloper;
    private int age;
} 

強(qiáng)調(diào)一遍,value改變了序列化和反序列化的默認(rèn)情況!因此,如果Gson根據(jù)你的Java模型類創(chuàng)建了一個(gè)JSON,它將會(huì)使用value作為該屬性的名。

alternate僅僅是作為反序列化中的代選項(xiàng)。Gson將會(huì)JSON中的所有名稱并且嘗試映射到被注解了的屬性中的某一個(gè)。在上面的模型類中,Gson將會(huì)檢查到來的JSON中是否含有fullName或者username。無論是哪一個(gè),都會(huì)映射到name屬性:

{
    'fullName': 'Norman',
    'email': 'norman@futurestud.io'
} 

以及

{
    'username': 'Norman',
    'email': 'norman@futurestud.io'
}

上面兩個(gè)JSON會(huì)映射到相同的Java對(duì)象。

如果有多個(gè)域匹配一個(gè)屬性,Gson會(huì)使用最后一個(gè)遇到的域。例如,在下面的JSON中,name屬性的值將會(huì)設(shè)置為Marcus,因?yàn)樵撝祦淼淖钔恚?/p>

{
    'username': 'Norman',
    'fullName': 'Marcus',
    'email': 'norman@futurestud.io'
}

如果你的服務(wù)器創(chuàng)建了自相矛盾的JSON,你將不會(huì)知道哪個(gè)屬性會(huì)被匹配。

前瞻

在這篇博客中,我們學(xué)習(xí)了使用@SerializedName去處理多個(gè)名稱對(duì)應(yīng)單個(gè)屬性的情況。

記住,這僅僅限于反序列化。Gson會(huì)從多個(gè)JSON值映射到你的Java對(duì)象,但往往會(huì)創(chuàng)建在序列化過程中創(chuàng)建相同的JSON。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.概述2.Gson的目標(biāo)3.Gson的性能和擴(kuò)展性4.Gson的使用者5.如何使用Gson 通過Maven來使用...
    人失格閱讀 14,562評(píng)論 2 18
  • 為了更好的學(xué)習(xí)Gson,特將Gson User Guide翻譯如下。由于本人英文水平有限,如有錯(cuò)誤,還請(qǐng)指正,謝謝...
    WeberLisper閱讀 7,073評(píng)論 0 6
  • 下午舉行了全鎮(zhèn)第九屆曹彥獎(jiǎng)學(xué)金評(píng)選,語文試卷是筆者所出。考慮是五年級(jí)競賽試題,筆者從兩個(gè)維度選取題型,一類課內(nèi)外結(jié)...
    紅魚兒1閱讀 1,137評(píng)論 0 2
  • 人的記憶真是一個(gè)奇怪的東西。在每一天,甚至每一個(gè)瞬間,遇到的大大小小的事情,零零碎碎的感悟,在如潮水般的記憶中涌動(dòng)...
    瀞知閱讀 823評(píng)論 4 2
  • 走過了童年的懵懂,經(jīng)歷著青春的迷茫,我們常常思考未來應(yīng)該怎么走,對(duì)未來給予了很多的幻想,然而當(dāng)走過了眼前的這條路,...
    永遠(yuǎn)不說再見好嗎閱讀 417評(píng)論 0 0

友情鏈接更多精彩內(nèi)容