2014-11-10 18 views
18

Sto provando a convertire la mia app che attualmente utilizza Retrofit, per utilizzare RX Java. Per gestire Pagination, tradizionalmente stavo afferrando l'URL nextPage dalle intestazioni di risposta.Ottenere informazioni di intestazione con RXJava e Retrofit

@Override 
    public void success(Assignment assignment, Response response) { 
     response.getHeaders(); // Do stuff with header info 
} 

Tuttavia, dato che il passaggio a RX Java, io non sono sicuro di come ottenere le informazioni di risposta dalla mia chiamata retrofit.

@GET("/{item_id}/users") 
    Observable<List<Objects>> getObjects(@Path("object_id") long object_id); 

    @GET("/{next}") 
    Observable<List<Objects>> getNextPageObjects(@Path("next") String nextURL); 

C'è un modo per fare in modo che le mie chiamate di retrofit restituiscano le mie informazioni di intestazione insieme ai miei oggetti tipizzati?

risposta

3

Lasciami spoilerare questo. È possibile intercettare la richiesta e la risposta a partire da OkHttp-2.2. Come in OkHttp wiki, gli intercettori non funzionano in Retrofit con OkUrlFactory. È necessario fornire la vostra Client implementazione per eseguire Retrofit richieste su questo custom Client e direttamente sul OkHttp

Purtroppo, non è ancora uscito (a breve).

public class ResponseHeaderInterceptor implements Interceptor { 
    public interface ResponseHeaderListener{ 
    public void onHeadersIntercepted(Headers headers); 
    } 
    private ResponseHeaderListener mListener; 
    public ResponseHeaderInterceptor(){}; 
    public ResponseHeaderInterceptor(ResponseHeaderListener listener){ 
    mListener = listener; 
    } 
    @Override public Response intercept(Chain chain) throws IOException { 
    Response response = chain.proceed(chain.request()); 
    if(mListener != null){ 
     mListener.onHeadersIntercepted(response.headers()); 
    } 
    return response; 
    } 

Usage:

ResponseHeaderListener headerListener = new ResponseHeaderListener(){ 
@Override 
public void onHeadersIntercepted(Headers headers){ 
    //do stuff with headers 
} 
}; 
OkHttpClient okHttpClient = new OkHttpClient(); 
okHttpClient.interceptors().add(new ResponseHeaderInterceptor(headerListener)); 
RestAdapter.Builder restAdapterBuilder = new RestAdapter.Builder(); 
restAdapterBuilder.setClient(new OkHttpClient22(okHttpClient)); 

Questa è l'applicazione di intercettazione e verrà chiamato solo una volta.

Si prega di notare che ho fatto tutto questo per logica, non ho ancora OkHttp-2.2. Basta leggere su di esso here. Rimuoverò parte di questo testo quando 2.2 è l'ultimo jar.

In alternativa, si può provare a creare client personalizzato e con una sola interfaccia di fornire la risposta:

public class InterceptableClient extends OkClient { 
    private ResponseListener mListener; 
    public interface ResponseListener{ 
     public void onResponseIntercepted(Response response); 
    } 
    public InterceptableClient(){}; 
    public InterceptableClient(ResponseListener listener){ 
     mListener = listener; 
    } 
    @Override 
    public retrofit.client.Response execute(Request request) throws IOException { 
     Response response = super.execute(request); 
     if(mListener != null) //runs on the executor you have provided for http execution 
      mListener.onResponseIntercepted(response); 
     return response; 
    } 
} 

Edit: OkHttp 2.2 è stato released.

13

È possibile utilizzare

Observable<Response> 

come tipo di ritorno per ottenere i dettagli di risposta

@GET("/{item_id}/users") 
Observable<Response> getObjects(@Path("object_id") long object_id); 

@GET("/{next}") 
Observable<Response>getNextPageObjects(@Path("next") String nextURL); 

Questo è come l'oggetto Response sarebbe simile

enter image description here

Avreste per poi analizzare le intestazioni e il corpo dall'osservabile

serviceClass.getNextPageObjects("next").flatMap(new Func1<Response, Observable<List<Objects>>() { 
    @Override 
    public Observable<AuthState> call(Response response) { 
     List<Header> headers = response.getHeaders(); 
     GsonConverter converter = new GsonConverter(new Gson()); 
     // you would have to change this to convert the objects to list 
     List<Objects> list = converter.fromBody(response.getBody(), 
          YourClass.class); 

     return Observable.from(list); 
    } 

} 
+0

L'utilizzo di questo tipo di osservabile rende difficile effettuare due chiamate in fila insieme, almeno da quello che posso dire. C'è un altro modo? – Brandon

+0

come controllare se la risposta è riuscita? – orium

Problemi correlati