Получение заголовка ответа («Дооснащение / OkHttp-клиент»)

Я использую Retrofit с OkHttp Client и Jackson для Json Serialization и хочу получить заголовок ответа.

Я знаю, что я могу расширить OkClient и перехватить его. Но это происходит до начала процесса десериализации.

В основном я хочу получить заголовок вместе с десериализованным Json Object.

Solutions Collecting From Web of "Получение заголовка ответа («Дооснащение / OkHttp-клиент»)"

С Retrofit 1.9.0, если вы используете асинхронную версию интерфейса Callback,

@GET("/user") void getUser(Callback<User> 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> .

Для поддержки Rx Retrofit 2.0 вы можете сделать это с помощью 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. Требуется некоторое ретро-foo, но вы можете это сделать. Вот что я сделал. Это грязный образец, поэтому не принимайте это как образец лучших практик.

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