2015-06-11 5 views
22

Ich verwende Retrofit mit dem OkHttp Client und Jackson für Json Serialisierung und möchte den Header der Antwort erhalten. Ich weiß, dass ich den OkClient erweitern und abfangen kann. Aber das kommt bevor der Deserialisierungsprozess beginnt.Header von Response (Retrofit/OkHttp Client)

Was ich im Grunde benötigt ist, um die Kopfzeile neben dem deserialized Json Object zu erhalten.

Antwort

23

Mit Retrofit 1.9.0, wenn Sie die Callback asynchrone Version der Schnittstelle verwenden,

@GET("/user") 
void getUser(Callback<User> callback) 

Dann wird Ihr Rückruf erhalten ein Response Objekt

Callback<User> user = new Callback<User>() { 
     @Override 
     public void success(User user, Response response) { 

     } 

     @Override 
     public void failure(RetrofitError error) { 

     } 
    } 

, die ein Verfahren getHeaders() genannt hat

Callback<User> user = new Callback<User>() { 
     @Override 
     public void success(User user, Response response) { 
      List<Header> headerList = response.getHeaders(); 
      for(Header header : headerList) { 
       Log.d(TAG, header.getName() + " " + header.getValue()); 
      } 
     } 

Für Retrofit 2.0's inte rface, können Sie dies mit Call<T> tun.

Für Retrofit 2.0 des Rx-Unterstützung, können Sie dies mit Observable<Result<T>>

+0

Gibt es eine Möglichkeit, es synchron zu bekommen? – Sakiboy

+1

In Retrofit 1.9.0 nein, in Retrofit 2.0+ ja (mit 'Call .execute()') – EpicPandaForce

+0

Wie kann ich das mit Observablen? – Lester

20

In Retrofit 2.0.0 können Sie Header wie diese:

public interface Api { 
    @GET("user") 
    Call<User> getUser(); 
} 

Call<User> call = api.getUser(); 
call.enqueue(new Callback<User>() { 
    @Override 
    public void onResponse(Call<User> call, Response<User> response) { 
     // get headers 
     Headers headers = response.headers(); 
     // get header value 
     String cookie = response.headers().get("Set-Cookie"); 
     // TODO 
    } 

    @Override 
    public void onFailure(Call<User> call, Throwable t) { 
     // TODO 
    } 
}); 
+0

Wie schleife ich durch alle Header? Ich habe 4-5 Header mit "set-cookie" als Schlüssel – Prabs

+1

'Liste cookieList = headers.toMultimap(). Get (" set-cookie ");' mit 'foreach' iterieren durch die Liste – Prabs

+0

Oder so: headers.values ​​(" Set-Cookie "). – Edi

1

wie Sie viel wollte ich die Header entlang Seite der Nutzlast. Ich brauchte Zugang zum Etag. Es braucht etwas Retro-Foo, aber Sie können es tun. hier ist was ich getan habe. Es ist eine schmutzige Probe, also nehmen Sie das nicht als Best-Practice-Beispiel.

public static RestAdapter.Builder getRestBuilder(Context context) { 
    GsonBuilder gsonBuilder = GsonBuilderUtils.getBuilder(); 
    Gson gson = gsonBuilder.create(); 
    // ** 
    // 1. create our own custom deserializer here 
    // ** 
    final MyGsonConverter gsonConverter = new MyGsonConverter(gson); 
    OkHttpClient httpClient = MyPersonalOkHttpFactory.getInstance().getAuthHttpClient(context); 
    httpClient.networkInterceptors().add(new Interceptor() { 
     @Override 
     public Response intercept(Chain chain) throws IOException { 
      Request originalRequest = chain.request(); 
      Response response = chain.proceed(originalRequest); 
      // ** 
      // 2. add the headers from the Interceptor to our deserializer instance 
      // ** 
      gsonConverter.headers = response.headers(); 
      return response; 
     } 
    }); 
    RestAdapter.Builder builder = new RestAdapter.Builder() 
      .setClient(new OkClient(httpClient)) 
      .setEndpoint(Common.getApiOriginUrl()) 
      .setConverter(gsonConverter); 
    return builder; 
} 

private static class MyGsonConverter extends GsonConverter { 

    private Headers headers; 

    public MyGsonConverter(Gson gson) { 
     super(gson); 
    } 

    @Override 
    public Object fromBody(TypedInput body, Type type) throws ConversionException { 
     Object obj = super.fromBody(body, type); 
     // ** 
     // 3. at this point, gson is called and you have access to headers 
     // do whatever you want here. I just set it on the return object. 
     // ** 
     if (obj instanceof HeadersArrayList) { 
      ((HeadersArrayList)obj).setHeaders(headers); 
     } 
     return obj; 
    } 
} 

public class HeadersArrayList<K> extends ArrayList<K>{ 

    private Headers headers; 

    public Headers getHeaders() { 
     return headers; 
    } 

    public void setHeaders(Headers headers) { 
     this.headers = headers; 
    } 
} 

// the retrofit api for reference 
@GET("/api/of/my/backend/{stuff}") 
HeadersArrayList<String> getSomething(@Path("stuff") String stuff); 
Verwandte Themen