android - Retrofit + RxJava 缓存响应失败,疑似响应头

标签 android caching retrofit okhttp rx-android

我正在尝试使用 Retrofit 1.9.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;
}

我没忘记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正在路上。

最佳答案

我想我有答案了。简短的一个是:“如果服务器发送无缓存 header 作为响应,则无法完成”。

如果你想要更长的,详情如下。

我制作了一个比较 2 个后端的示例应用。我们称它们为后端 A 和后端 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);
    }

打了两个电话,然后禁用了 wifi。 B 的缓存工作正常,但 A 抛出 504 Unsatisfiable Request (only-if-cached)

在这种情况下,覆盖 header 似乎无济于事。

关于android - Retrofit + RxJava 缓存响应失败,疑似响应头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32608446/

相关文章:

android - java.lang.IndexOutOfBoundsException : setSpan (2 . .. 2) 超出长度 1

android - list 合并因多个错误而失败,请参阅日志(PayUMoney 集成)

c# - 在 Windows 计算机上的 .Net 中跨应用程序进行缓存

javascript - 如何在dexie中读取当前的数据库版本号?

android - 将模拟 Retrofit API 服务实例注入(inject) ActivityInstrumentTestCase2

android - 改造 1.6 : Call RestService with different (TCP)-Ports

Android Retrofit 错误 - 尝试在空对象引用上调用接口(interface)方法 'int java.util.List.size()'

android - 提交后禁用 fragment 过渡动画

android - 使用 FileProvider 通过 Intent 发送多个不同类型的文件

javascript - 存储随机句子生成器的结果