7

私はこのトピックについて長い議論を見てきましたが、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'

受信した応答に対して表示されるログには、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();

ヘッダー インターセプターには、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;
        }

    }

そして、これがキャッシュを設定する方法です。

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

解決策を見つけるのにかなりの時間を費やしましたが、運がなかったので、迅速で効果的な応答を探しています。

ありがとう

4

1 に答える 1

0

あなたのコードは機能しているようです。私は試していませんが、数週間前に同じ問題に直面しました。レトロフィットのログに if-none-match ヘッダーが表示されなかったことが原因であることが判明しました。しかし、プロキシを使用してリクエストをインターセプトし、最初にラップトップにリクエストをリダイレクトしようとすると (mitmproxyアプリを使用していました)、if-none-match ヘッダーが表示されました。

とにかく、/okhttp3/internal/http/CacheStrategy.javaこのメソッドprivate CacheStrategy getCandidate()の内部を調べると、OkHttp3 が実際に etag & if-none-match ヘッダーを適切に使用していることがわかります。

これが明確になることを願っています。

于 2016-09-06T18:03:44.107 に答える