从响应中获取标题(Retrofit / OkHttp客户端)

我正在使用OkHttp Client和Jackson for Json序列化进行Retrofit,希望得到响应头。

我知道我可以扩展OkClient并拦截它。 但是,这是在反序列化过程开始之前。

我基本上需要的是与反序列化的Json对象一起获得标题。

Solutions Collecting From Web of "从响应中获取标题(Retrofit / OkHttp客户端)"

使用Retrofit 1.9.0,如果使用Callbackasynchronous版本的界面,

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

然后你的callback会收到一个Response对象

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

其中有一个名为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()); } } 

对于Retrofit 2.0的界面,你可以通过Call<T>

对于Retrofit 2.0的Rx支持,可以使用Observable<Result<T>>

在Retrofit 2.0.0中,你可以得到这样的头文件:

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

就像你我想要的有效载荷一边的标题。 我需要访问Etag。 这需要一些复古,但你可以做到。 这是我做的。 这是一个肮脏的样本,所以不要把这作为一个最佳实践的样本。

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