2015-09-16 117 views
10

我正在嘗試配置緩存,其中包含Retrofit 1.9.0OkHtttp 2.5.0Retrofit + RxJava無法緩存響應,疑似響應標頭

這裏是我爲我的RestAdapter提供OkHttpClient

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

我沒有忘記setClientRestAdapter.Builder。還確定,我實際上使用RestAdapter的實例與此客戶端集合。

甚至檢查文件是否在「http」文件夾下創建。他們是。

但是經過我打開WIFI和重裝我的屏幕我結束了OnError回調Observable端點此消息:

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

免責聲明:我也許應該提及的是,最終Observable從5人組合,與flatMapzip在途中。

+0

[可以使用OKHttp改造時使用緩存數據可能的重複](http://stackoverflow.com/questions/23429046/can-retrofit-with-okhttp-use-cache-data-when-offline) – njzk2

回答

3

我想我有一個答案。簡短的一個是:「如果服務器發送無緩存頭作爲響應,則無法完成」。

如果你想要更長的一個,細節如下。

我做了一個比較2後端的示例應用程序。讓我們稱之爲後端A和B.後端一個是給我的麻煩,所以我已經決定去檢查B.

A返回CacheControl = "no-cache, no-transform, max-age=0"

乙返回Cache-Control = „public"響應頭

我也做了同樣的設置對於後端,只是不同的網址。

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

這兩個電話,然後禁用wifi。 緩存工作正常B,但拋出504 Unsatisfiable Request (only-if-cached)

看來,覆蓋頭將無法幫助在這種情況下。

2

您應該重寫您的Request而不是Response。作爲參考,請參閱rewriting requests上的文檔。請注意,如果需要,也可以使用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); 
    } 
}); 
+0

不幸的是,那不起作用 –

+0

是的,這不起作用。 – amj