2017-01-24 6 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 используемой модификации. Это готовит модификацию для сериализации и десериализации объектов Token с использованием адаптера заданного типа.

Я думаю, что основным недостатком этого подхода является то, что если вы хотите написать общий десериализатор/serialiser/typeadapter, он может стать довольно сложным (предполагая, что у вас не будет только объект Token).

 Смежные вопросы

  • Нет связанных вопросов^_^