2016-09-12 2 views
0

Мне нужно реализовать базовое кэширование ответов API. Я сделал небольшой проект игровой площадки, который вызывает API GitHub, и кеширование было успешным (я использовал Чарльз, чтобы проверить это). Однако, когда я передал это решение в мой целевой проект, кэширование больше не работало. Может быть причиной нескольких перехватчиков в цепочке?Кэширование дооснащения 2 - цепь перехватчиков

Код с детской площадкой проекта (работа):

Interceptor (то же самое для целевого проекта):

public class CacheControlInterceptor implements Interceptor { 
    @Override 
    public Response intercept(Chain chain) throws IOException { 
     Response response = chain.proceed(chain.request()); 
     return response.newBuilder() 
       .header("Cache-Control", "only-if-cached") 
       .build(); 
    } 
} 

Cache и клиент декларации:

long SIZE_OF_CACHE = 10 * 1024 * 1024; // 10 MB 
final Cache cache = new Cache(new File(getCacheDir(), "retrofit_cache"), SIZE_OF_CACHE); 

OkHttpClient.Builder client = new OkHttpClient.Builder().cache(cache); 
client.networkInterceptors().add(new CacheControlInterceptor()); 

Retrofit retrofit = new Retrofit.Builder() 
     .baseUrl("https://api.github.com/users/") 
     .addConverterFactory(GsonConverterFactory.create()) 
     .client(client.build()) 
     .build(); 

экрана от отладки CacheControlInterceptor : screen


код из целевого проекта (работы):

Cache и клиент декларации:

private OkHttpClient provideOkHttpClient() { 
    HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); 
    loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); 

    OkHttpClient.Builder okhttpClientBuilder = new OkHttpClient.Builder(); 
    okhttpClientBuilder.connectTimeout(30, TimeUnit.SECONDS); 
    okhttpClientBuilder.readTimeout(30, TimeUnit.SECONDS); 
    okhttpClientBuilder.writeTimeout(30, TimeUnit.SECONDS); 

    okhttpClientBuilder.addInterceptor(loggingInterceptor); 
    okhttpClientBuilder.addInterceptor(new JwtRenewInterceptor(getUserSession())); 
    okhttpClientBuilder.addInterceptor(new AutoLoginInterceptor(getUserSession())); 
    okhttpClientBuilder.addNetworkInterceptor(new CacheControlInterceptor()); 

    long SIZE_OF_CACHE = 10 * 1024 * 1024; // 10 MB 
    final Cache cache = new Cache(new File(getCacheDir(), "retrofit_cache"), SIZE_OF_CACHE); 
    okhttpClientBuilder.cache(cache); 

    return okhttpClientBuilder.build(); 
} 

экрана от отладки CacheControlInterceptor: screen

ответ

0

На самом деле ошибка была вызвана моим бедным рассуждением о HTTP заголовках. Я думал, что метод addHeader или header просто добавит ключ Cache-Control, а затем значение only-if-cached. Однако он добавляет только ценность! И поскольку в API моего целевого проекта не было ни одного ключа заголовка Cache-Control (в отличие от API GitHub) не было места для значения only-if-cached для хранения.

1

Если вы хотите применить некоторые заголовки все запросы, использующие кеш OkHttp, должны использовать перехватчик приложений, а не сетевой перехватчик. В противном случае вы не даете кеш-механизму возможность возвращать кешированные ответы. Это хорошо иллюстрируется на OkHttp вики enter image description here

Так, скорее всего, что происходит в вашем коде, что вы позволяете Cache для хранения ответов, но вы никогда не использовать их, так как запросы, идущие от кэша отсутствуют only-if-cached заголовок.

Попробуйте okhttpClientBuilder.addInterceptor(new CacheControlInterceptor());

Смежные вопросы