If-None-Match未在我的请求中传递

use*_*176 6 android caching retrofit2 okhttp3

我已经看到了关于这个主题的长期讨论,并声称在2.3.0中已经修复.这是我正在使用的组合

compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'

compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'

compile 'com.squareup.okhttp3:logging-interceptor:3.0.1'

compile 'com.squareup.okhttp3:okhttp:3.2.0'
Run Code Online (Sandbox Code Playgroud)

日志我看到反对收到的回复,有Etag; 但我后来的请求没有在其标题中传递If-None-Match.我通过我的代码显式插入If-None-Match来测试它,缓存工作和响应是预期的.所以我正在使用的库版本或者我的代码不太好的东西肯定有问题.

我在这里设置okClient.

HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);

        okhttp3.OkHttpClient okClient = new okhttp3.OkHttpClient.Builder()
                .addInterceptor(new HeaderInterceptor())
                .addInterceptor(httpLoggingInterceptor)
                .cache(createCacheForOkHTTP())
                .connectTimeout(5, TimeUnit.MINUTES)
                .readTimeout(5, TimeUnit.MINUTES)
                .build();

        retrofit = new Retrofit.Builder()
                .baseUrl(AppConfig.API_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(okClient)
                .build();
Run Code Online (Sandbox Code Playgroud)

我的标头拦截器包含了几乎专注于我自己的API的逻辑.这里是

private class HeaderInterceptor
            implements Interceptor {


        private String generateAuthHeader(AuthResponse accessToken) {
            if (accessToken == null) {
                return "";
            }
            return String.format("Bearer %s", accessToken.getAccessToken());
        }

        @Override
        public okhttp3.Response intercept(Chain chain)
                throws IOException {
            Request request = chain.request();
            final String authorizationValue = generateAuthHeader(runtime.getPrefAccessToken());
            if (!TextUtils.isEmpty(authorizationValue)) {
                request = request.newBuilder()
                        .addHeader(AppConfig.API_KEY_AUTHORIZATION, authorizationValue)
                        .addHeader(AppConfig.API_KEY_ACCEPT, AppConfig.API_ACCEPT)
                        .build();
                //.addHeader("If-None-Match", "a69385c6d34596e48cdddd3ce475d290")
            } else {
                request = request.newBuilder()
                        .addHeader(AppConfig.API_KEY_CONTENT_TYPE, AppConfig.API_CONTENT_TYPE)
                        .addHeader(AppConfig.API_KEY_ACCEPT, AppConfig.API_ACCEPT)
                        .build();
            }
            okhttp3.Response response = chain.proceed(request);
            return response;
        }

    }
Run Code Online (Sandbox Code Playgroud)

这是我设置缓存的方法.

 private Cache createCacheForOkHTTP() {
        Cache cache = null;
        cache = new Cache(App.getInstance().getBaseContext().getCacheDir(), 1024 * 1024 * 10);
        return cache;
    }
Run Code Online (Sandbox Code Playgroud)

寻找一些快速有效的回应,因为我已经花了合理的时间找到解决方案,但没有运气.

谢谢

小智 0

您的代码似乎有效,我还没有尝试过,但几周前我遇到了同样的问题。原来是因为retrofit的日志没有显示if-none-match header。但是当我尝试使用代理拦截请求并首先将请求重定向到我的笔记本电脑(我正在使用mitmproxy应用程序)时,出现了 if-none-match 标头。

无论如何,如果你查看/okhttp3/internal/http/CacheStrategy.java这个方法的内部private CacheStrategy getCandidate(),你会发现 OkHttp3 实际上正确地使用了 etag 和 if-none-match 标头。

希望这能澄清。