美文网首页
OkHttp3 快速入门(一)

OkHttp3 快速入门(一)

作者: coding400 | 来源:发表于2020-05-10 16:24 被阅读0次
okhttp.png

OkHttp 是什么

OkHttp 是一个 Http 客户端, 和 Apache Httpclient 类似, 但底层网络连接封装不一样, OkHttp 使用的是 okio, Httpclient 直接使用底层 Socket 来封装网络连接, 更多细节后面再研究, 这里主要记录 OkHttp 的使用方法

提供了什么功能

这里直接截取了官网的介绍

  1. HTTP/2 support allows all requests to the same host to share a socket.
  2. Connection pooling reduces request latency (if HTTP/2 isn’t available).
  3. Transparent GZIP shrinks download sizes.
  4. Response caching avoids the network completely for repeat requests.

当然这里并非全部, 个人理解的是 连接池、异步、重试、异常处理等重要功能都有

核心对象介绍

Call

该接口代表一个可向发起请求的对象(使用内部持有的 OkHttpClient 发送请求),包含了 request/response 流,可以被 canceled,只能被执行一次

Request

代表 http 请求中的 request 对象,通过该对象封装请求数据,如:method、request header、url、request body 等

使用 Builder 建造者模式来封装请求

    Request request = new Request.Builder()
        .get()
        .url("http://www.baidu.com")
        .header("Accept", "application/json")
        .build();
  1. get() 使用 GET 方法,同样的还有 post()、head()、put() 等
  2. url() 请求路径
  3. header() 添加请求头

OkHttpClient

创建 Call 对象的工厂,可以被用来发送 http 请求并解析返回的 response。
该对象应该在所有 http 调用者中共享,因为 OkHttpClient 对连接进行了缓存和复用,当所有 http 调用端共享该对象时,意味着同时共享了所有的 connection pool , 并且降低了延迟和内存开销。异步调用时,由于使用内部线程池来发送 http 请求,因此在异步调用过程中,共享 OkHttpClient 还共享了线程池

创建方式
  1. 使用默认配置
OkHttpClient okHttpClient = new OkHttpClient();
  1. 使用自定义配置
   OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .readTimeout(500, TimeUnit.MILLISECONDS)
        .build();
  1. 使用 execute 同步发送 GET 请求
    Request request = new Request.Builder()
        .get()
        .url("http://www.baidu.com")
        .header("Accept", "application/json")
        .build();
    try {
      Response response = okHttpClient.newCall(request).execute();
      System.out.println(response.body().string());
    } catch (IOException e) {
      e.printStackTrace();
    }
  1. 使用 execute 同步发送 POST 请求
    Request request = new Builder()
        .url("")
        // 设置 request header 或 response body 的 Content-Type 类型
        .post(RequestBody.create(MediaType.parse("application/json;charset=utf-8"), json))
        .build();
    try {
      Response response = okHttpClient.newCall(request).execute();
      System.out.println(response.body().string());
    } catch (IOException e) {
      e.printStackTrace();
    }
  1. 使用 enqueue 异步发送 GET 请求
    CountDownLatch latch = new CountDownLatch(1);
    okHttpClient.newCall(request).enqueue(new Callback() {
      @Override
      public void onFailure(Call call, IOException e) {
        System.out.println(e);
      }

      @Override
      public void onResponse(Call call, Response response) throws IOException {
        System.out.println(response.body().string());
        latch.countDown();
      }
    });
    latch.await();

Interceptor

Interceptor 为实现拦截器的标准接口,实现该接口之后,在 intercept(Chain chain) 中必须调用 chain.proceed(request) 方法,通过拦截器链模式来观察整个网络请求

如:用该拦截器来记录每次请求时间,并将超过 500 毫秒的请求记录下来

@Component
@Slf4j
public class TimeLogInterceptor implements Interceptor {

  @Override
  public Response intercept(Chain chain) throws IOException {
    Response response;
    Request rq = chain.request();
    long start = System.currentTimeMillis();
    try {
      response = chain.proceed(rq);
    } catch (Exception e) {
      log.error("error call request,cost>{},uri>{},e->{}", System.currentTimeMillis() - start,
          rq.url(), e);
      throw e;
    } finally {
      long end = System.currentTimeMillis();
      long cost = end - start;
      if (cost > 500) {
        log.warn("RestTemplate cost time exceed={} ms,uri={}", cost, rq.url());
      }
    }
return response;
}

可通过 addInterceptor 或者 addNetworkInterceptor 添加,addInterceptor 添加的为全局拦截器,addNetworkInterceptor 添加的为网络拦截器,区别是:addInterceptor 只会调用一次,addNetworkInterceptor 随着网络请求的次数变化,如:当发生请求重试时,此时内部的拦截器将对 addNetworkInterceptor 中添加的拦截器进行多次调用

   OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .readTimeout(500, TimeUnit.MILLISECONDS)
        .addInterceptor(xxx)
        .addNetworkInterceptor(xx)
        .build();

ConnectionPool

该类用来管理 HTTP 和 HTTP/2 复用的连接,以便降低网络延迟。HTTP 请求通过同一请求地址来共用连接

   ConnectionPool connectionPool = new ConnectionPool(100, 1, TimeUnit.MINUTES);
   OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .readTimeout(500, TimeUnit.MILLISECONDS)
         .connectionPool(connectionPool)
        .build();

构造方法接受 3 个参数,分别代表,最大闲置连接、最长闲置时间、闲置时间单位,默认的是最多 5 个连接,最长保持 5 分钟,关于如何设置闲置时间,需要根据被调用端的 KeepAlive 的时间

相关文章

网友评论

      本文标题:OkHttp3 快速入门(一)

      本文链接:https://www.haomeiwen.com/subject/lzmzwhtx.html