2017-01-24 36 views
2

我剛開始使用Retrofit2,並且我正在使用的API在「響應」對象中包含所有有效的響應,如下所示。我需要告訴Retrofit只解析響應中的值,而不實際將它們嵌套到另一個對象中。對於登錄代碼,我也遇到了獲取我想要轉換爲實際時間戳的字符串的問題。Retrofit2指定根元素並轉換數據類型

這是從登錄請求的響應示例:

{ 
    "status":"success", 
    "response":{ 
     "token":"test_token", 
     "expires":"1485217863" 
    } 
} 

在上面僅有的兩個實際值是:

token 
expires 

我希望喜歡的東西是什麼落得如下所示。

public class Token { 

    @SerializedName("token") 
    String token; 

    @SerializedName("expires") 
    Timestamp expires; 

    public User(String token, String expires) { 
    this.token 
    this.expires = //conversion code omitted. 
    } 
} 

回答

2

這裏有幾個選項。您可以使用自定義串行器/反串行器,類型適配器,或者您可以簡單地使用pojos並自行解包結果。

讓我從我能想到的最簡單的解決方案開始。你有這些類的圖片:

public class ResponseData<T> { 
    @SerializedName("status") 
    @Expose 
    String status; 
    @SerializedName("response") 
    @Expose 
    T response; 

    public T getResponse() { 
     return response; 
    } 
    // getters and setters and friends 
} 

public class Token { 
    @SerializedName("token") 
    @Expose 
    String token; 

    @SerializedName("expires") 
    @Expose 
    Timestamp expires; 

    public Token(String token, String expires) { 
     this.token = token; 
     this.expires = expires; 
    } 
} 

所以首先要注意的是使用@Expose。這是一件好事,但不是非常必要的。當你有自定義的序列號時,它可以幫助你。

我認爲你可以有多個端點API返回的同類機構,其中JSON是:

{ 
"status":"success", 
"response":{ 
    // Can be anything 
} 
} 

正如你所看到的反應可以是任何東西。

然後,您可以讓您的翻新電話返回ResponseData<Token>,並且在您的回調中,您可以檢查status的值並查看是否可以使用getResponse解包結果。這種方法的優點是可以很容易地重複使用ResponseData

另一種方法是使用自定義串行器或類型適配器。這在我看來更加費力,但仍然是一種有效的方法。我認爲這裏的answer是相當廣泛的,並解釋瞭如何做到這一點,以獲得response中的嵌套對象。

要準備改裝以使用類型適配器,您需要向其中注入配置的Gson實例。具體方法如下:

Gson gson = new GsonBuilder() 
    .registerTypeAdapter(Token.class, new YourTypeAdapter()) 
    .create(); 

Retrofit retrofit = new Retrofit.Builder() 
    .addConverterFactory(GsonConverterFactory.create(gson)) 
    // .... 

正如你所看到的,我們通過創建GSON與類型的適配器通過改造使用的GsonConverterFactory。這爲使用給定類型適配器的對象序列化和反序列化做好了改進。

我認爲這種方法的主要缺點是,如果你想寫一個通用的反序列化器/ serialiser/typeadapter它可以變得很複雜(假設你不會只有一個Token對象)。