Retrofit 2 RxJava – Gson – Deserializzazione "globale", modifica il tipo di risposta

Sto utilizzando un'API che restituisce sempre l'object JSON che sembra questo:

public class ApiResponse<T> { public boolean success; public T data; } 

field dati è un object JSON che contiene tutte le informazioni preziose. Naturalmente è diverso per diverse richieste. Così la mia interface retrofit sembra così:

  • Come eseguire l'authentication a Google Talk con il token di authentication di AccountManager utilizzando l'API Smack?
  • get l'image di ImageView e inviarla ad un'attività con Intent
  • camera e galleria android non funzionante in nexus 5
  • Occorre il context quando non è in esecuzione alcuna attività
  • Comportmento LVL sulla validità della licenza di lato client per applicazioni gratuite
  • Impostare una voce di menu come selezionata dal codice
  •  @GET(...) Observable<ApiResponse<User>> getUser(); 

    E quando voglio gestire la risposta ho bisogno per esempio:

     response.getData().getUserId(); 

    Non ho veramente bisogno di quel field di successo boolean e vorrei ignorarlo, in modo che la mia interface retrofit potrebbe essere simile a questa:

     @GET(...) Observable<User> getUser(); 

    È ansible farlo a Gson? O forse una function Rx ordinata che trasformsrà automaticamente questo?

    EDIT: esempio json:

     { "success": true, "data": { "id": 22, "firstname": "Jon", "lastname": "Snow" } } 

    EDIT 2: Ho manged per farlo con l'interceptor retrofit where modifico manualmente il corpo di risposta. Funziona ma se hai altri suggerimenti, ti preghiamo di inviarli 🙂

  • perdita di memory con immagini
  • Terminare un'attività di un'altra attività
  • Lo background del cerchio Android diventa ovale
  • Differenza tra? SelectableItemBackground,? Android: selezionabileItemBackground e? Android: attr / selectableItemBackground in Android?
  • Devo utilizzare sempre l'ultimo targetSdkVersion?
  • Come scherzare il metodo e nel log
  • 2 Solutions collect form web for “Retrofit 2 RxJava – Gson – Deserializzazione "globale", modifica il tipo di risposta”

    Come detto, la soluzione con l'intercettore non è così grande. Sono riuscito a risolvere questo problema con un trasformatore Rx. Ho anche aggiunto l'exception api personalizzata che posso lanciare quando qualcosa è andato storto e facile gestirlo in onError. Penso che sia più robusto.

    Wrapper di risposta:

     public class ApiResponse<T> { private boolean success; private T data; private ApiError error; } 

    Oggetto di errore restituito quando il successo è falso:

     public class ApiError { private int code; } 

    Getta questa exception quando il successo è falso:

     public class ApiException extends RuntimeException { private final ApiError apiError; private final transient ApiResponse<?> response; public ApiException(ApiResponse<?> response) { this.apiError = response.getError(); this.response = response; } public ApiError getApiError() { return apiError; } public ApiResponse<?> getResponse() { return response; } } 

    E un trasformatore:

     protected <T> Observable.Transformsr<ApiResponse<T>, T> applySchedulersAndExtractData() { return observable -> observable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .map(tApiResponse -> { if (!tApiResponse.isSuccess()) throw new ApiException(tApiResponse); else return tApiResponse.getData(); }); } 

    Per quanto lo so, non esiste una soluzione facile per raggiungere ciò che vuoi. Con una soluzione facile intendo qualcosa di più ragionevole di quello che hai adesso. Puoi deserializzare tutti i dati da soli, puoi estrarre i dati utilizzando interceptori, ma è molto più sforzo che usi semplicemente l'API come è ora.

    Inoltre, pensa a cosa succede se cambia e che alcune patch appaiono proprio accanto a quell'elemento e boolean (ad esempio l'ultimo aggiornamento dell'ora), devi cambiare tutto.

    L'unica ragionevole idea che ho è quella di avvolgere l'interface Api con un'altra class e dentro di essa call .map sul tuo Observable per trasformare ApiResponse<T> in T

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.