前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >源码系列--CallServerInterceptor

源码系列--CallServerInterceptor

作者头像
用户3112896
发布2020-05-12 15:21:16
5910
发布2020-05-12 15:21:16
举报
文章被收录于专栏:安卓圈安卓圈

Github下载源码地址https://github.com/square/okhttp

我们今天来看看OkHttp拦截器里的CallServerInterceptor

来看CallServerInterceptor类的intercept方法

1)源码:

代码语言:javascript
复制
Exchange exchange = realChain.exchange();
Request request = realChain.request();

RealInterceptorChain类分别返回Exchange和Request对象

2)源码

代码语言:javascript
复制
exchange.writeRequestHeaders(request)

进到Exchange类

代码语言:javascript
复制
public void writeRequestHeaders(Request request) throws IOException {
  try {
    eventListener.requestHeadersStart(call);
    codec.writeRequestHeaders(request);
    eventListener.requestHeadersEnd(call, request);
  } catch (IOException e) {
    eventListener.requestFailed(call, e);
    trackFailure(e);
    throw e;
  }
}

进到ExchangeCodec的实现类Http1ExchangeCodec(Http1.1版本)的writeRequestHeaders方法

代码语言:javascript
复制
@Override public void writeRequestHeaders(Request request) throws IOException {
  String requestLine = RequestLine.get(
      request, realConnection.route().proxy().type());
  writeRequest(request.headers(), requestLine);
}

进到RequestLine的get方法

代码语言:javascript
复制
public static String get(Request request, Proxy.Type proxyType) {
  StringBuilder result = new StringBuilder();
  result.append(request.method());
  result.append(' ');

  if (includeAuthorityInRequestLine(request, proxyType)) {
    result.append(request.url());
  } else {
    result.append(requestPath(request.url()));
  }

  result.append(" HTTP/1.1");
  return result.toString();
}

这里是一些字符串的拼接和请求的判断

紧接着是Http1ExchangeCodec的writeRequest方法

代码语言:javascript
复制
public void writeRequest(Headers headers, String requestLine) throws IOException {
  if (state != STATE_IDLE) throw new IllegalStateException("state: " + state);
  sink.writeUtf8(requestLine).writeUtf8("\r\n");
  for (int i = 0, size = headers.size(); i < size; i++) {
    sink.writeUtf8(headers.name(i))
        .writeUtf8(": ")
        .writeUtf8(headers.value(i))
        .writeUtf8("\r\n");
  }
  sink.writeUtf8("\r\n");
  state = STATE_OPEN_REQUEST_BODY;
}

可以看到是通过Okio的BufferedSink实现的

Exchange类的writeRequestHeaders方法的catch中的trackFailure会走失败流程,输出ErrorCode

3)源码

代码语言:javascript
复制
responseBuilder = exchange.readResponseHeaders(true);

进到Exchange类的readResponseHeaders方法,然后再进到Http1ExchangeCodec类的readResponseHeaders方法

看名字都知道是读响应头信息,进到StatusLine的parse方法里

4)源码

代码语言:javascript
复制
BufferedSink bufferedRequestBody = Okio.buffer(
    exchange.createRequestBody(request, true));

最终进到Http1ExchangeCodec类的createRequestBody方法中

5)CallServerInterceptor类的intercept方法最后是生成response

源码:

代码语言:javascript
复制
Response response = responseBuilder
    .request(request)
    .handshake(exchange.connection().handshake())
    .sentRequestAtMillis(sentRequestMillis)
    .receivedResponseAtMillis(System.currentTimeMillis())
    .build();

int code = response.code();
if (code == 100) {
  // server sent a 100-continue even though we did not request one.
  // try again to read the actual response
  response = exchange.readResponseHeaders(false)
      .request(request)
      .handshake(exchange.connection().handshake())
      .sentRequestAtMillis(sentRequestMillis)
      .receivedResponseAtMillis(System.currentTimeMillis())
      .build();

  code = response.code();
}

exchange.responseHeadersEnd(response);

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(exchange.openResponseBody(response))
      .build();
}

总的来说,还是比较简单的,150行左右的代码。先写请求头,然后发送请求,最后得到响应

而且有两个类Http1ExchangeCodec和Http2ExchangeCodec,很好的适配了不同的http版本

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 安卓圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档