重温一遍OkHttp

* 版本 3.4.1

为什么使用OkHttp

  • 支持SPDY(基于TCP的协议,多路复用、请求优先级、报头压缩、单个socket处理并发以减少握手)
  • 支持Https,包括自签名请求链接(如支付请求)。
  • 取消请求。

基本请求

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


保存Cookie

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

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


打印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
    }
    ...
}


上传文件(文件流方式)

客户端代码

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!"})


角色分析

  • OkHttpClient:设置拦截器、cookie、ssl认证、缓存、超时、代理
  • Request:设置url、请求方式(默认get)、cacheControl
  • RealCall:
  • Interceptor:
  • Dispatcher:
  • AsycCall:

责任链模式

  1. 实现(任何一种设计模式都没有固定的写法,只有合适的写法 )
  2. 特点
    - 以U型轨道顺序执行
    - 从“原料”到“成品”,我们既可以对“原料”进行“加工”,还可以对“成品”进行“加工”
    - 对修改关闭,对拓展开放

源码解析

  1. 网络请求

你可能感兴趣的:(重温一遍OkHttp)