2015-09-16 11 views
10

Retrofit 1.9.0OkHtttp 2.5.0でキャッシュを設定しようとしています。ここでRetrofit + 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; 
} 

私はRestAdapter.BuildersetClientに忘れませんでした。また、実際にはこのクライアントセットでRestAdapterのインスタンスを使用していることを確認しました。

ファイルが "http"フォルダの下に作成されているかどうかを確認します。彼らです。

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

免責事項:私はWIFIの電源を入れて、私の画面をリロードした後

は、しかし、私はこのメッセージでObservableエンドポイントのOnErrorコールバックで終わる私はおそらく、最終Observableは5人の他人から結合されていることを言及する必要があります途中でflatMapzipがあります。

+0

[可能であれば、OKHttpでキャッシュデータを使用するとオフラインでキャッシュデータを使用できる]の複製(http://stackoverflow.com/questions/23429046/can-retrofit-with-okhttp-use-cache-data-when-offline) – njzk2

答えて

3

のように見えるはずです。短いものは、「サーバーがレスポンスでno-cacheヘッダーを送信した場合は実行できません」。

もっと長いものをご希望の場合は、以下のとおりです。

私は2つのバックエンドを比較するサンプルアプリケーションを作った。バックエンドAそれらを呼び出すことができますし、バックエンドB. Aが私に与えていたことは、私はA

B.

にチェックすることを決定しましたので、トラブルB CacheControl = "no-cache, no-transform, max-age=0"

を返すことは、私は同じ設定をした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)

この場合、ヘッダーを上書きしても役立たないようです。

2

Responseの代わりにRequestを書き換える必要があります。参考までに、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

関連する問題