Дооснащение + RxJava не кэширует ответы, подозрительные заголовки ответов

Я пытаюсь настроить кеш с Retrofit 1.9.0 OkHtttp 2.5.0 и OkHtttp 2.5.0 .

Вот как я предоставляю OkHttpClient для моего RestAdapter :

 @Provides @Singleton public OkHttpClient provideOkHttpClient() { OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setConnectTimeout(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); okHttpClient.setReadTimeout(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); okHttpClient.setWriteTimeout(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); File cacheDir = new File(context.getCacheDir(), "http"); final Cache cache = new Cache(cacheDir, DISK_CACHE_SIZE_IN_BYTES); okHttpClient.setCache(cache); okHttpClient.interceptors().add(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Response response = chain.proceed(request); Response finalResponse = response.newBuilder() .header("Cache-Control", String.format("public, max-stale=%d", 604800)) .build(); Log.d("OkHttp", finalResponse.toString()); Log.d("OkHttp Headers", finalResponse.headers().toString()); return finalResponse; } }); return okHttpClient; } 

Я не забыл setClient на RestAdapter.Builder . Также убедитесь, что я фактически использую экземпляр RestAdapter с этим набором клиентов.

Даже проверено, созданы ли файлы в папке «http». Они есть.

Однако после того, как я OnError к WIFI и перезагрузите свой экран, я OnError обратный вызов OnError Observable конечной точки с этим сообщением:

 retrofit.RetrofitError: failed to connect to /10.40.31.12 (port 8888) after 10000ms: connect failed: ENETUNREACH (Network is unreachable) 

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я должен, вероятно, упомянуть, что окончательный Observable объединяется с 5 другими, с flatMap и zip в пути.

Solutions Collecting From Web of "Дооснащение + RxJava не кэширует ответы, подозрительные заголовки ответов"

Думаю, у меня есть ответ. Коротким является: «Не может быть сделано, если сервер отправляет заголовок без кэша в ответ».

Если вы хотите более длинный, детали ниже.

Я сделал пример приложения, сравнивающего 2 бэкэнда. Позволяет называть их Backend A и Backend B. A давал мне проблемы, поэтому я решил проверить B.

A возвращает CacheControl = "no-cache, no-transform, max-age=0"

B возвращает заголовок ответа Cache-Control = „public"

Я сделал ту же настройку для обоих бэкэндов, просто для разных URL-адресов.

  private void buildApi() { Gson gson = new GsonBuilder().create(); OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setConnectTimeout(10, TimeUnit.SECONDS); File cacheDir = new File(getCacheDir(), "http"); final Cache cache = new Cache(cacheDir, 1000000 * 10); okHttpClient.setCache(cache); okHttpClient.interceptors().add(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Log.d("OkHttp REQUEST", request.toString()); Log.d("OkHttp REQUEST Headers", request.headers().toString()); Response response = chain.proceed(request); response = response.newBuilder() .header("Cache-Control", String.format("public, max-age=%d, max-stale=%d", 60, RESPONSE_CACHE_LIFESPAN_IN_SECONDS)) .build(); Log.d("OkHttp RESPONSE", response.toString()); Log.d("OkHttp RESPONSE Headers", response.headers().toString()); return response; } }); RestAdapter.Builder builder = new RestAdapter.Builder() .setConverter(new StringGsonConverter(gson)) .setClient(new OkClient(okHttpClient)) .setRequestInterceptor(new RequestInterceptor() { @Override public void intercept(RequestFacade request) { if (isNetworkAvailable()) { request.addHeader("Cache-Control", "public, max-age=" + 60); } else { request.addHeader("Cache-Control", "public, only-if-cached, max-stale=" + RESPONSE_CACHE_LIFESPAN_IN_SECONDS); } } }); builder.setEndpoint("http://this.is.under.vpn.so.wont.work.anyway/api"); A_API = builder.build().create(AApi.class); builder.setEndpoint("http://collector-prod-server.elasticbeanstalk.com/api"); B_API = builder.build().create(BApi.class); } 

Оба вызова, а затем отключил Wi-Fi. Кэш работал отлично для B, но A бросил 504 Unsatisfiable Request (only-if-cached)

Похоже, что в этом случае сглаживание заголовков не поможет.

Вы должны переписать свой Request вместо Response . Для справки см. Документы по переписыванию запросов . Обратите внимание, что вы также можете использовать класс CacheControl вместо создания собственного заголовка, если хотите. Ваш перехватчик должен выглядеть примерно так:

 okHttpClient.interceptors().add(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Request cachedRequest = request.newBuilder() .cacheControl(new CacheControl.Builder() .maxStale(7, TimeUnit.DAYS) .build()) .build(); return chain.proceed(cachedRequest); } });