Getting Header from Response (Retrofit / OkHttp Client) Getting Header from Response (Retrofit / OkHttp Client) json json

Getting Header from Response (Retrofit / OkHttp Client)


With Retrofit 1.9.0, if you use the Callback asynchronous version of the interface,

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

Then your callback will receive a Response object

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

Which has a method called getHeaders()

    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());            }        }

For Retrofit 2.0's interface, you can do this with Call<T>.

For Retrofit 2.0's Rx support, you can do this with Observable<Result<T>>


In Retrofit 2.0.0, you can get header like this:

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    }});


Much like you I wanted the headers along side of the payload. I needed access to the Etag. It takes some retro-foo, but you can do it. here's what I did. It's a dirty sample so dont take this as a best practices sample.

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);