0、http基礎(chǔ)
這部分內(nèi)容我也是網(wǎng)上搜索到的,看到和緩存有關(guān)的幾個(gè)關(guān)鍵詞:
** private、no-cache、max-age、must- revalidate 、Expires、Cache-Control、ETag、Last-Modified-Date**
等,具體含義可以http 緩存的基礎(chǔ)知識(shí),但是以上關(guān)鍵字都是Get請(qǐng)求有關(guān)的,Post請(qǐng)求一般是沒法緩存的。
為什么沒法緩存呢? 因?yàn)閔ttp請(qǐng)求只是緩存 請(qǐng)求查詢操作,更新服務(wù)器數(shù)據(jù)是沒有緩存的,為什么沒有緩存呢,因?yàn)橐话闱闆rhttp緩存都是把請(qǐng)求的url作為key,相應(yīng)內(nèi)容作為value 來(lái)進(jìn)行緩存的,大家也知道post請(qǐng)求中的url是一樣的,變化的是請(qǐng)求體,所以一般http不緩存post請(qǐng)求。
但是既然我們知道了問(wèn)題,肯定有人能想到辦法來(lái)通過(guò)添加請(qǐng)求頭來(lái)緩存post請(qǐng)求 這篇文章說(shuō)明了 post請(qǐng)求也可以緩存,但是文章也說(shuō)了 需要服務(wù)器配合,如果服務(wù)器不配合那么只能手工存儲(chǔ)數(shù)據(jù)來(lái)實(shí)現(xiàn)緩存了!
1、Okhttp緩存數(shù)據(jù)
首先如果是get請(qǐng)求,那么就用網(wǎng)上各種文章中的方法,就是添加okhttp攔截器,添加請(qǐng)求頭的方式來(lái)緩存
private final Interceptor mRewriteCacheControlInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
String cacheControl = request.cacheControl().toString();
if (!NetWorkUtils.isNetConnected(BaseApplication.getContext())) {
request = request.newBuilder()
.cacheControl(TextUtils.isEmpty(cacheControl)? CacheControl.FORCE_CACHE:CacheControl.FORCE_NETWORK)
.build();
}
Response originalResponse = chain.proceed(request);
if (NetWorkUtils.isNetConnected(BaseApplication.getContext())) {
//有網(wǎng)的時(shí)候連接服務(wù)器請(qǐng)求,緩存一天
return originalResponse.newBuilder()
.header("Cache-Control", "public, max-age=" + MAX_AGE)
.removeHeader("Pragma")
.build();
} else {
//網(wǎng)絡(luò)斷開時(shí)讀取緩存
return originalResponse.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + CACHE_STALE_SEC)
.removeHeader("Pragma")
.build();
}
}
};
但是如果是post請(qǐng)求,那就只能用下面方式了
- 數(shù)據(jù)庫(kù)緩存 Sqlite 這篇文章有說(shuō)明 數(shù)據(jù)庫(kù)緩存
- 文件緩存 DiskLruCache 這篇文章有說(shuō)明 文件緩存
3、Okhttp是不支持post緩存的
通過(guò)看okhttp源碼知道 okhttp3 -> Cache -> put方法
CacheRequest put(Response response) {
String requestMethod = response.request().method();
if (HttpMethod.invalidatesCache(response.request().method())) {
try {
remove(response.request());
} catch (IOException ignored) {
// The cache cannot be written.
}
return null;
}
if (!requestMethod.equals("GET")) {
// Don't cache non-GET responses. We're technically allowed to cache
// HEAD requests and some POST requests, but the complexity of doing
// so is high and the benefit is low.
return null;
}
...
}
從源碼中知道,okhttp會(huì)首先判斷請(qǐng)求方式,如果不是GET請(qǐng)求就直接返回了,不做任何緩存操作