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