OkHttp3源码解析--拦截器BridgeInterceptor

桥拦截器的作用有:

  • 负责把用户构造的请求转换为发送给服务器的请求,把服务器返回的响应转换为对用户友好的响应;

  • 转换的过程就是添加一些服务端需要的header信息;

  • 在Request阶段配置用户信息,并添加一些请求头。在Response阶段,进行gzip解压。

  • 将我们创建的请求对象转成网络访问需要的请求对象,其实就是添加一些头部;

  • 然后,将网络访问对象传递出去;

  • 最后,将网络请求回复对象,转成对用户友好的回复对象。

看一下源码:

public final class BridgeInterceptor implements Interceptor {
  
  ... ...//这里的Chain对象依旧是创建的下一个拦截器链,
  @Override public Response intercept(Chain chain) throws IOException {
    Request userRequest = chain.request();                    //获取之前我们创建的Request对象
    Request.Builder requestBuilder = userRequest.newBuilder();//再次获取Request.Builder对象,准备添加需要的字段
    
    //**********************开始添加需要的头部字段***********************************
    RequestBody body = userRequest.body();                    //从userRequest中获取body
    if (body != null) {
      MediaType contentType = body.contentType();             //看body内容格式类型
      if (contentType != null) {
        requestBuilder.header("Content-Type", contentType.toString());//向requestBuilder中添加同样的类型
      }long contentLength = body.contentLength();//body内容长度
      if (contentLength != -1) {
        requestBuilder.header("Content-Length", Long.toString(contentLength));
        requestBuilder.removeHeader("Transfer-Encoding");
      } else {
        requestBuilder.header("Transfer-Encoding", "chunked");
        requestBuilder.removeHeader("Content-Length");
      }
    }if (userRequest.header("Host") == null) {//主机
      requestBuilder.header("Host", hostHeader(userRequest.url(), false));
    }if (userRequest.header("Connection") == null) {//连接保活
      requestBuilder.header("Connection", "Keep-Alive");
    }// If we add an "Accept-Encoding: gzip" header field we're responsible for also decompressing
    // the transfer stream.
    boolean transparentGzip = false;
    if (userRequest.header("Accept-Encoding") == null && userRequest.header("Range") == null) {
      transparentGzip = true;
      requestBuilder.header("Accept-Encoding", "gzip");//gzip
    }
​
    List<Cookie> cookies = cookieJar.loadForRequest(userRequest.url());//加载cookie信息
    if (!cookies.isEmpty()) {
      requestBuilder.header("Cookie", cookieHeader(cookies));
    }if (userRequest.header("User-Agent") == null) {
      requestBuilder.header("User-Agent", Version.userAgent());//userAgent
    }
    
    //*********************************Request对象拼接完成,开始后续的处理,调用后续的拦截器*****************************
    //再次调用下一个拦截器链chain的proceed的方法,传入我们创建好的添加好头部信息的Request。和之前的相似,依旧会唤起下一个拦截器的执行,即CacheInterceptor
    Response networkResponse = chain.proceed(requestBuilder.build());
    
    //*********************************开始解析Response对象,将它转成用户友好的Response*****************************
    //收到回复networkResponse,开始将它转化为用户友好的Response
    HttpHeaders.receiveHeaders(cookieJar, userRequest.url(), networkResponse.headers());
    //和上面Request类似,依旧是创建一个新的Response对象,从networkResponse中copy所需要的信息。
    Response.Builder responseBuilder = networkResponse.newBuilder()
        .request(userRequest);if (transparentGzip
        && "gzip".equalsIgnoreCase(networkResponse.header("Content-Encoding"))
        && HttpHeaders.hasBody(networkResponse)) {
      GzipSource responseBody = new GzipSource(networkResponse.body().source());
      Headers strippedHeaders = networkResponse.headers().newBuilder()
          .removeAll("Content-Encoding")
          .removeAll("Content-Length")
          .build();
      responseBuilder.headers(strippedHeaders);
      String contentType = networkResponse.header("Content-Type");
      responseBuilder.body(new RealResponseBody(contentType, -1L, Okio.buffer(responseBody)));
    }
    //返回Response给上一个拦截器,即RetryAndFollowUpInterceptor
    return responseBuilder.build();
  }
  ... ...
}

简单总结一下处理流程:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值