網(wǎng)絡(luò)訪問組件六- 讓 okhttp 支持 post緩存

參考:

  1. http://www.reibang.com/p/2710ed1e6b48

整體代碼與示例故响,請參考:

https://github.com/zhaoyubetter/basenet
至此網(wǎng)絡(luò)模塊的封裝告一段落肮帐;

為什么需要POST緩存

大環(huán)境所致龄毡,在servlet中,有2個方法悼潭,分別是 doGet, doPost潮酒,要么在 doGet中,轉(zhuǎn)發(fā)到了doPost磨镶,要么反之溃蔫,springMVC,已記不清了。
所以這就造成了琳猫,有時候伟叛,我們真的需要 為 post添加緩存;

為post請求添加緩存原理

參考圖片:
在 application 級別攔截請求脐嫂,因為:應(yīng)用攔截器允許短路而不調(diào)用 Chain.proceed(),即中止調(diào)用
判斷如果是 post统刮,如果緩存有效,直接返回response账千,讓后續(xù)的攔截器無法執(zhí)行侥蒙;
其他緩存的內(nèi)容,幾乎都是 Cache.java那套匀奏;少量修改鞭衩;


圖片來自網(wǎng)絡(luò)

具體實現(xiàn):

  1. 為 OkhttpClient添加應(yīng)用攔截器:

     final OkHttpClient.Builder builder = new OkHttpClient.Builder();
     builder.connectTimeout(NetConfig.getInstance().getTimeOut(), TimeUnit.MILLISECONDS);
     builder.readTimeout(NetConfig.getInstance().getTimeOut(), TimeUnit.MILLISECONDS);
     builder.writeTimeout(NetConfig.getInstance().getTimeOut(), TimeUnit.MILLISECONDS);
    
     /* ==設(shè)置攔截器== */
     // 設(shè)置緩存
     File cacheDir = new File(NetConfig.getInstance().getCacheDir());
     // GET 形式緩存設(shè)置
     Cache cache = new Cache(cacheDir, NetConfig.getInstance().getCacheSize());
     builder.cache(cache).addNetworkInterceptor(new NetCacheInterceptor());        // 設(shè)置緩存攔截器
     // 日志攔截
     if (NetConfig.getInstance().isDebug()) {
         builder.addInterceptor(new LoggerInterceptor());
     }
     // 是否允許POST 形式緩存設(shè)置
     if (NetConfig.getInstance().isEnablePostCache()) {
         builder.addInterceptor(new PostCacheInterceptor());
     }
    
  2. 新增類 NetPostCache.java, 此類,就是 copy 了 Cache類攒射,然后修改
    其put方法醋旦,讓其支持post,與 獲取key方法会放,如下:

public static String key(Request request) {
        String cUrl = request.url().toString();
        if (request.body() != null) {
            Buffer buffer = new Buffer();
            try {
                // 避免post重復(fù)饲齐,這里采用value來憑借,因key不好獲取
                // 如果有上傳下載文件咧最,此處為 ProgressRequestBody
                if (request.body() instanceof MultipartBody) {
                    final List<MultipartBody.Part> parts = ((MultipartBody) request.body()).parts();
                    /**
                     * 接受字符串格式的參數(shù)捂人,其他忽略
                     * @see lib.basenet.okhttp.OkHttpRequest#getRequestBody mParams
                     */
                    for (MultipartBody.Part p : parts) {
                        if (null == p.body().contentType()) {
                            p.body().writeTo(buffer);
                        }
                    }
                }
                String params = buffer.readString(Charset.forName("UTF-8")); //獲取請求參數(shù)
                cUrl += params;
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                Util.closeQuietly(buffer);
            }

        }
        return ByteString.encodeUtf8(cUrl).md5().hex();
    }
  1. 應(yīng)用級攔截器:PostCacheInterceptor.java 代碼片段
/**
 * post緩存御雕,從應(yīng)用攔截器層,攔截
 * Created by zhaoyu on 2017/4/26.
 */
public class PostCacheInterceptor implements Interceptor {

    /**
     * 緩存Post請求
     */
    final NetPostCache mPostCache;

    public PostCacheInterceptor() {
        File cacheDir = new File(NetConfig.getInstance().getCacheDir() + "/post");
        mPostCache = new NetPostCache(cacheDir, NetConfig.getInstance().getCacheSize());
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        final Request request = chain.request();

        // 如果是post請求滥搭,并且設(shè)置了緩存酸纲,則在這里進(jìn)行攔截,如果緩存有效瑟匆,后續(xù)的攔截器將不執(zhí)行
        if ("POST".equalsIgnoreCase(request.method()) && (null != request.cacheControl() && !request.cacheControl().noStore())) {
            // 強制刷新闽坡,刪除舊有post緩存
            checkForceRefresh(request);

            // 以下代碼邏輯來家:okhttp3 源碼中的 CacheInterceptor.java,模擬其運行
            Response cacheCandidate = mPostCache != null ? mPostCache.get(request) : null;
            long now = System.currentTimeMillis();
            CacheStrategy strategy = new CacheStrategy.Factory(now, chain.request(), cacheCandidate).get();
            Request networkRequest = strategy.networkRequest;
            Response cacheResponse = strategy.cacheResponse;

            if (mPostCache != null) {
                mPostCache.trackResponse(strategy);
            }

            if (cacheCandidate != null && cacheResponse == null) {
                closeQuietly(cacheCandidate.body()); // The mPostCache candidate wasn't applicable. Close it.
            }

            // 有則從緩存中返回愁溜,直接跳過后面的攔截器疾嗅,不訪問網(wǎng)絡(luò)了
            // If we don't need the network, we're done.
            if (networkRequest == null) {
                return cacheResponse.newBuilder()
                        .cacheResponse(stripBody(cacheResponse))
                        .build();
            }

            Response networkResponse = null;
            try {
                // 執(zhí)行網(wǎng)絡(luò)請求,并包裝一下
                networkResponse = chain.proceed(request);
            } finally {
                // If we're crashing on I/O or otherwise, don't leak the mPostCache body.
                if (networkResponse == null && cacheCandidate != null) {
                    closeQuietly(cacheCandidate.body());
                }
            }

            if (HttpHeaders.hasBody(networkResponse)) {
                CacheRequest cacheRequest = mPostCache.put(networkResponse);
                networkResponse = cacheWritingResponse(cacheRequest, networkResponse);
            }

            // 當(dāng) onSuccess調(diào)用時冕象,會寫入緩存
            return networkResponse;
        }

        return chain.proceed(request);
    }

注意事項:

post 緩存時代承,因 唯一key,不好定位渐扮,只支持 請求參數(shù)為 鍵值對(key-value)form 表單形式论悴,對于上傳文件,下載文件形式的post墓律,請求膀估,一律無效;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末只锻,一起剝皮案震驚了整個濱河市玖像,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌齐饮,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笤昨,死亡現(xiàn)場離奇詭異祖驱,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)瞒窒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門捺僻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人崇裁,你說我怎么就攤上這事匕坯。” “怎么了拔稳?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵葛峻,是天一觀的道長。 經(jīng)常有香客問我巴比,道長术奖,這世上最難降的妖魔是什么礁遵? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮采记,結(jié)果婚禮上佣耐,老公的妹妹穿的比我還像新娘。我一直安慰自己唧龄,他們只是感情好叭莫,可當(dāng)我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著制肮,像睡著了一般抽碌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上援制,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天戏挡,我揣著相機(jī)與錄音,去河邊找鬼晨仑。 笑死褐墅,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的洪己。 我是一名探鬼主播妥凳,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼答捕!你這毒婦竟也來了逝钥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤拱镐,失蹤者是張志新(化名)和其女友劉穎艘款,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沃琅,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡哗咆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了益眉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晌柬。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖郭脂,靈堂內(nèi)的尸體忽然破棺而出年碘,到底是詐尸還是另有隱情,我是刑警寧澤展鸡,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布屿衅,位于F島的核電站,受9級特大地震影響娱颊,放射性物質(zhì)發(fā)生泄漏傲诵。R本人自食惡果不足惜凯砍,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拴竹。 院中可真熱鬧悟衩,春花似錦、人聲如沸栓拜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽幕与。三九已至挑势,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間啦鸣,已是汗流浹背潮饱。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留诫给,地道東北人香拉。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像中狂,于是被迫代替她去往敵國和親凫碌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理胃榕,服務(wù)發(fā)現(xiàn)盛险,斷路器,智...
    卡卡羅2017閱讀 134,715評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法勋又,類相關(guān)的語法苦掘,內(nèi)部類的語法,繼承相關(guān)的語法楔壤,異常的語法鸟蜡,線程的語...
    子非魚_t_閱讀 31,665評論 18 399
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 3,815評論 0 11
  • 緩存分類 http請求有服務(wù)端和客戶端之分。因此緩存也可以分為兩個類型服務(wù)端側(cè)和客戶端側(cè)挺邀。 緩存——服務(wù)端常見的服...
    安仔夏天勤奮閱讀 600評論 1 0
  • 東南賽區(qū) 順著美國東海岸的海岸線往南走,伴隨著美麗的沙灘跳座,我們來到擁有著美國最溫暖濕潤空氣端铛,也最適宜居住的地方,N...
    紙鳶江南閱讀 400評論 0 0