我正在使用Retrofit,配置为使用OkHttp和缓存。
我称之为api:https://api.github.com/users/bod/repos,它会返回Etag
和Cache-Control: public, max-age=60, s-maxage=60
标题。
我在不到60秒的时间内发出两个请求,所以我希望第二个请求根本不执行任何网络,并根据Cache-Control
指令使用缓存。但那不是我所看到的。
我猜这是因为Etag
指令优先?
这是正确/正常/预期的行为吗?
答案 0 :(得分:2)
RFC2068 Hypertext Transfer Protocol -- HTTP/1.1详细介绍了ETag
和Cache-Control
标题。以后的文档RFC2616和RFC7232都会展开ETag
标题以及如何与If-None-Match
一起使用。
RFC2616, 13.3 Validation Model包含您问题的答案:
当缓存有一个陈旧的条目,它想用作一个 响应客户的请求,它首先必须检查原点 服务器(或可能是具有新响应的中间缓存) 看看它的缓存条目是否仍然可用。我们称之为“验证” 缓存条目。
然后继续列出验证模型,包括实体标签(ETag)缓存验证器以及最后修改日期。过时的缓存条目是指该资源发生maxage
或其他到期机制的条目。
因此系统的行为是出乎意料的。使用和不使用ETag标头测试内容可能值得验证本地缓存是否正常工作。
答案 1 :(得分:0)
您是否在改造中正确设置了缓存?类似的东西:
// create the cache
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.cache(new Cache(new File(context.getCacheDir(), "ok-http-cache"),
1024 * 1024 * 5)); // 5 MB cache
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(builder.build()) // set the cache created above
.build();
api = retrofit.create(Api.class); // Api is the interface with the @GET, @POST annotations
如果您知道这一点,这是微不足道的,但您没有提及您的实施