OkHttp源码解读总结(十三)--->CallServerInterceptor拦截器

本文解析了OkHttp中CallServerInterceptor的工作原理,包括如何发起网络请求、处理请求头及请求体、读取响应头及响应体等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OkHttp源码解读总结(十三)—>CallServerInterceptor拦截器

标签(空格分隔): OkHttp源码 学习笔记


前言
  • 以下的相关知识总结是通过慕课网的相关学习和自己的相关看法,如果有需要的可以去查看一下慕课网的相关教学,感觉还可以。

官网介绍

/** This is the last interceptor in the chain. It makes a network call to the server. */

1、发起真正的网络请求
2、返回服务器返回的数据

主要源码

@Override public Response intercept(Chain chain) throws IOException {
    //拦截器链
    RealInterceptorChain realChain = (RealInterceptorChain) chain;
    //HttpCodec对象  source  sink  两个对象 输入和输出  //用于编码request  解码response 
    HttpCodec httpCodec = realChain.httpStream();
    //用于建立网络请求的其他网络组件  
    StreamAllocation streamAllocation = realChain.streamAllocation();
    //
    RealConnection connection = (RealConnection) realChain.connection();
    //网络请求
    Request request = realChain.request();

    long sentRequestMillis = System.currentTimeMillis();

    realChain.eventListener().requestHeadersStart(realChain.call());
    //向socket中写入请求的头部信息
    httpCodec.writeRequestHeaders(request);
    realChain.eventListener().requestHeadersEnd(realChain.call(), request);

    Response.Builder responseBuilder = null;
    if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) {
      // If there's a "Expect: 100-continue" header on the request, wait for a "HTTP/1.1 100
      // Continue" response before transmitting the request body. If we don't get that, return
      // what we did get (such as a 4xx response) without ever transmitting the request body.
      //询问服务是否可以发送带有请求体的信息
      if ("100-continue".equalsIgnoreCase(request.header("Expect"))) {
        httpCodec.flushRequest();
        realChain.eventListener().responseHeadersStart(realChain.call());
        responseBuilder = httpCodec.readResponseHeaders(true);
      }

      if (responseBuilder == null) {
        // Write the request body if the "Expect: 100-continue" expectation was met.
        realChain.eventListener().requestBodyStart(realChain.call());
        long contentLength = request.body().contentLength();
        CountingSink requestBodyOut =
            new CountingSink(httpCodec.createRequestBody(request, contentLength));
        BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut);
        //调用request.body().writeTo()方法向socket中写入body信息
        request.body().writeTo(bufferedRequestBody);
        //关闭
        bufferedRequestBody.close();
        realChain.eventListener()
            .requestBodyEnd(realChain.call(), requestBodyOut.successfulCount);
      } else if (!connection.isMultiplexed()) {
        // If the "Expect: 100-continue" expectation wasn't met, prevent the HTTP/1 connection
        // from being reused. Otherwise we're still obligated to transmit the request body to
        // leave the connection in a consistent state.
        streamAllocation.noNewStreams();
      }
    }
    //完成了网络请求的写入操作
    httpCodec.finishRequest();

    if (responseBuilder == null) {
      realChain.eventListener().responseHeadersStart(realChain.call());
      //通过httpCodec的readResponseHeaders  读取response
      responseBuilder = httpCodec.readResponseHeaders(false);
    }
   //通过streamAllocation  request   创建response对象
    Response response = responseBuilder
        .request(request)
        .handshake(streamAllocation.connection().handshake())
        .sentRequestAtMillis(sentRequestMillis)
        .receivedResponseAtMillis(System.currentTimeMillis())
        .build();

    realChain.eventListener()
        .responseHeadersEnd(realChain.call(), response);
    //获取到响应吗
    int code = response.code();
    if (forWebSocket && code == 101) {
      // Connection is upgrading, but we need to ensure interceptors see a non-null response body.
      response = response.newBuilder()
          .body(Util.EMPTY_RESPONSE)
          .build();
    } else {
      //调用httpCodec.openResponseBody(response)创建response
      response = response.newBuilder()
          .body(httpCodec.openResponseBody(response))
          .build();
    }

    if ("close".equalsIgnoreCase(response.request().header("Connection"))
        || "close".equalsIgnoreCase(response.header("Connection"))) {
      //禁止新的流创建  关闭流和关闭connection    
      streamAllocation.noNewStreams();
    }
    //如果code为204  或者205  就抛出异常
    if ((code == 204 || code == 205) && response.body().contentLength() > 0) {
      throw new ProtocolException(
          "HTTP " + code + " had non-zero Content-Length: " + response.body().contentLength());
    }
    //最后返回得到的response
    return response;
  }
  • 1、调用 httpCodec.writeRequestHeaders(request)向socket对象中写入header信息
  • 2、 request.body().writeTo(bufferedRequestBody)向socket当中写入body信息
  • 3、 httpCodec.finishRequest()表示网络请求的写入工作完成
  • 4、 responseBuilder = httpCodec.readResponseHeaders(false)读取网络请求的头部信息
  • 5、通过以下代码逻辑,读取网络请求中的body信息

    if (forWebSocket && code == 101) {
      // Connection is upgrading, but we need to ensure interceptors see a non-null response body.
      response = response.newBuilder()
          .body(Util.EMPTY_RESPONSE)
          .build();
    } else {
      response = response.newBuilder()
          .body(httpCodec.openResponseBody(response))
          .build();
    }

OkHttp中的一次网络请求的大致情况

  • 1、call对象对请求的封装
  • 2、dispatcher分发器对请求进行分发
  • 3、getResponseWithInterceptors()方法
    • RetryAndFollowUpInterceptor(重试重定向/失败重连)
    • CacheInterceptor(缓存)
    • BridgeInterceptor(处理请求和响应对象于实际的请求和响应转换/cookie)
    • ConnectInterceptor(负责建立拦截和流对象)
    • CallServerInterceptor(完成最终的网络请求和读取响应)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值