重溫一遍OkHttp

* 版本 3.4.1

為什么使用OkHttp

  • 支持SPDY(基于TCP的協議,多路復用、請求優先級、報頭壓縮、單個socket處理并發以減少握手)
  • 支持Https,包括自簽名請求鏈接(如支付請求)。
  • 取消請求。
    </br>

基本請求

// client和request都使用builder模式實例化
client.newCall(request).excute() or .enqueue(callback)

</br>

保存Cookie

clientBuilder.cookieJar(new CookieJar(){
    @Override
    public synchronized void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
        // 存(key = url, value = cookies)
    }

    @Override
    public synchronized List<Cookie> loadForRequest(HttpUrl url) {
        // 取(key = url),返回(value = cookies)
    }
});

</br>

打印Log

public class LoggerInterceptor implements Interceptor {
    ...
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        logForRequest(request); // 打印request
        Response response = chain.proceed(request); // 責任鏈模式,調用proceed處理下一個攔截器
        return logForResponse(response); // 打印response
    }
    ...
}

</br>

上傳文件(文件流方式)

客戶端代碼

RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addPart(Headers.of(
                        "Content-Disposition",
                        "form-data;name=\"myfile\";filename =\"lgt.jpeg\""), fileBody) // 服務端可以通過name值獲取到該請求表單,通過filename獲取到上傳的文件
                .build();
final Request request = new Request.Builder()
                .url(BASE_HOST + url)
                .post(requestBody)
                .build();
Call call = mClient.newCall(request);
call.enqueue(callback);

服務端Python代碼(Flask實現)

// 所允許上傳的文件類型
@app.route('/api/upload', methods=['POST'], strict_slashes=False)
def api_upload():
    file_dir = os.path.join(basedir, app.config['UPLOAD_FOLDER'])
    if not os.path.exists(file_dir):
        os.makedirs(file_dir)
    f = request.files['myfile']  # 從表單的file字段獲取文件,myfile為該表單的name值
    if f and allowed_file(f.filename):  # 判斷是否是允許上傳的文件類型
        fname = secure_filename(f.filename)
        print(fname)
        ext = fname.rsplit('.', 1)[1]  # 獲取文件后綴
        unix_time = int(time.time())
        new_filename = str(unix_time) + '.' + ext  # 修改了上傳的文件名
        f.save(os.path.join(file_dir, new_filename))  # 保存文件到upload目錄
        return jsonify({"CODE": 200, "MSG": "Upload succeed!"})
    else:
        return jsonify({"CODE": 1001, "MSG": "Your selected upload file type is not allowed!"})

</br>

角色分析

  • OkHttpClient:設置攔截器、cookie、ssl認證、緩存、超時、代理
  • Request:設置url、請求方式(默認get)、cacheControl
  • RealCall:
  • Interceptor:
  • Dispatcher:
  • AsycCall:
    </br>

責任鏈模式

  1. 實現(任何一種設計模式都沒有固定的寫法,只有合適的寫法 )
  2. 特點
    - 以U型軌道順序執行
    - 從“原料”到“成品”,我們既可以對“原料”進行“加工”,還可以對“成品”進行“加工”
    - 對修改關閉,對拓展開放
    </br>

源碼解析

  1. 網絡請求
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容