Gson教程十(譯):Exclusion Strategies

該文章翻譯自Gson Tutorial Series系列教程。該篇主要闡述如何自定義Gson的排除策略(Exclusion Strategies)。

在之前發(fā)表的博客中,你已經(jīng)學(xué)習(xí)了一些關(guān)于控制某些屬性是否會(huì)被序列化和反序列化的技術(shù)。到目前為止,這還處于屬性層級(jí)。你可以在同一時(shí)間改變序列化和反序列化的某一要素。在本篇博客,我們將探討一種如何設(shè)置更多普遍規(guī)則的方式來空值屬性的轉(zhuǎn)換。

transient@Expose更牛逼的排除策略

你已經(jīng)學(xué)習(xí)了transient以及@Expose了,它們可以改變序列化和反序列化過程中的單個(gè)屬性。下面我們將探討更加普遍的方法。Gson稱它為ExclusionStrategies。當(dāng)然,你需要通過GsonBuilder設(shè)置它。

在我們開始特定的實(shí)現(xiàn)之前,先創(chuàng)建一個(gè)測(cè)試模型。我們使用一個(gè)新的UserDate模型,它擁有一些屬性:

public class UserDate {  
    private String _name;
    private String email;
    private boolean isDeveloper;
    private int age;
    private Date registerDate = new Date();
}

請(qǐng)注意屬性的類型和名稱。這將是非常重要的。假設(shè)我們需要排除所有類型為Date以及boolean的屬性,使用ExclusionStrategies很容易做到。你可以通過GsonBuilder實(shí)現(xiàn):

GsonBuilder gsonBuilder = new GsonBuilder();  
gsonBuilder.setExclusionStrategies(new ExclusionStrategy() {  
    @Override
    public boolean shouldSkipField(FieldAttributes f) {
        return false;
    }

    @Override
    public boolean shouldSkipClass(Class<?> incomingClass) {
        return incomingClass == Date.class || incomingClass == boolean.class;
    }
});
Gson gson = gsonBuilder.create();

UserDate user = new UserDate("Norman", "norman@futurestud.io", 26, true);  
String usersJson = gson.toJson(user); 

ExclusionStrategies類提供了兩個(gè)重寫方法。上面的例子我們使用了第二個(gè)方法。我們檢查該類是否是Date或者boolean之一。如果該屬性是其中之一的類型,那么該方法就會(huì)返回true,Gson將會(huì)忽略該屬性。你可以在該方法中檢查任意類。JSON結(jié)果將只包含字符串型和整型:

{
  "age": 26,
  "email": "norman@futurestud.io",
  "_name": "Norman"
}

另一個(gè)方法的排除功能基于屬性的聲明。例如,如果我們還想排除所有包含下劃線_的屬性,那么可以按如下代碼:

GsonBuilder gsonBuilder = new GsonBuilder();  
gsonBuilder.setExclusionStrategies(new ExclusionStrategy() {  
    @Override
    public boolean shouldSkipField(FieldAttributes f) {
        return f.getName().contains("_");
    }

    @Override
    public boolean shouldSkipClass(Class<?> incomingClass) {
        return incomingClass == Date.class || incomingClass == boolean.class;
    }
});
Gson gson = gsonBuilder.create();

UserDate user = new UserDate("Norman", "norman@futurestud.io", 26, true);  
String usersJson = gson.toJson(user);  

JSON結(jié)果更短了:

{
  "age": 26,
  "email": "norman@futurestud.io"
}

你可以在各種各樣不同的場(chǎng)景中運(yùn)用排除策略。如果你擁有一些具有特殊序列化和反序列化排除的普遍的機(jī)制,這將會(huì)非常容易。請(qǐng)注意,你可以傳遞多鐘排除策略到一個(gè)參數(shù)中。

如果你此刻還看不出來排除策略的重要之處,那也沒關(guān)系!伴隨著更加復(fù)雜的類型,我們的內(nèi)容將會(huì)更加深入。一旦我們開始書寫我們的自定義適配器,那么你將會(huì)看到確定值。非常幸運(yùn),通過排除策略你可以使Gson忽略任何類型

排除策略僅作用于序列化或者反序列化

在之前的篇幅中,我們?yōu)樾蛄谢头葱蛄谢忌暾?qǐng)了排除策略。如果你僅僅需要應(yīng)用于二者之一,你可以使用下面的方法:

  • addSerializationExclusionStrategy()
  • addDeserializationExclusionStrategy().

這二者的效果和之前的setExclusionStrategies()是相同的。你同樣可以傳遞和實(shí)現(xiàn)ExclusionStrategy對(duì)象給它們。

基于修飾詞排除成員變量

正如我們之前解釋的,所有使用transient修飾的成員變量在序列化和反序列化過程中都會(huì)被忽略。

GsonBuilder允許你改變這一行為。使用excludeFieldsWithModifiers()可以選擇在序列化和反序列化過程中排除哪些被特定修飾詞修飾的成員變量。該方法需要傳遞java.lang.reflect.Modifier類中的修飾詞。

例如,你有下面的模型:

public class UserModifier {  
    private String name;
    private transient String email;
    private static boolean isDeveloper;
    private final int age;
}

如果你想排除所有finalstatic類型,但包括field,你需要按如下代碼配置Gson:

GsonBuilder gsonBuilder = new GsonBuilder();  
gsonBuilder.excludeFieldsWithModifiers(Modifier.STATIC, Modifier.FINAL);  
Gson gson = gsonBuilder.create();

UserModifier user = new UserModifier("Norman", "norman@fs.io", 26, true);  
String usersJson = gson.toJson(user);

上面的代碼將會(huì)創(chuàng)建如下JSON:

{
  "email": "norman@fs.io",
  "name": "Norman"
}

注意,Gson實(shí)例也會(huì)包含email域的,即使它被設(shè)置為transient。調(diào)用excludeFieldsWithModifiers()方法重寫它的默認(rèn)設(shè)置。我們僅僅傳遞了staticfinal,因此transient修飾詞將不會(huì)被忽略。如果你想要包含所有域而不管修飾詞,僅需要傳遞空列表參數(shù)給excludeFieldsWithModifiers()

排除沒有被@Expose注解的域

最后,有一個(gè)選擇我們沒有多大興趣,但會(huì)提示你所有的選項(xiàng):excludeFieldsWithoutExposeAnnotation。正如它的名字所暗示的,它將會(huì)排除所有沒有被@Expose注解的成員變量。

你可以強(qiáng)制你的應(yīng)用程序模型必須每處都用@Expose注解了,這樣可以使得開發(fā)者思考哪些域需要序列化和反序列化。

前瞻

在這篇博客,你已經(jīng)學(xué)會(huì)了在更普遍的層面上排除屬性。ExclusionStrategies提供了兩種排除屬性的選擇。你可以通過類類型和屬性名進(jìn)行過濾。還有更多專業(yè)的排除策略。

在下一篇博客,我們將會(huì)探究如果JSON的結(jié)構(gòu)沒有遵循標(biāo)準(zhǔn),Gson將會(huì)有多靈活。

最后編輯于
?著作權(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),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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