OKHttp原碼分析(五)之Interceptor

一,概述

在上篇blog中可知:在RealCall的getResponseWithInterceptorChain方法中創建了許多不同類型的Interceptor對象。然後在RealInterceptorChain對象的proceed方法中有調用了Interceptor對象的intercept方法,最終返回Response對象。

Interceptor稱爲攔截器,這是OKHttp中的一個機制,它的作用是:可以對請求進行轉換,重試,重寫等操作。

Interceptor是一個接口,它的實現類有:
1. ConnectInterceptor:連接攔截器。
2. CallServerInterceptor:請求服務器攔截器
3. CacheInterceptor:緩存攔截器
4. BridgeInterceptor:橋樑攔截器。
Interceptor是一個接口,可以根據需要自定義攔截器。

下面看幾個重要的攔截器。

二ConnectInterceptor類分析

這個類的源碼不多,重要的是intercept方法,intercept方法的源碼是:

public Response intercept(Chain chain) throws IOException {
    RealInterceptorChain realChain = (RealInterceptorChain) chain;
    Request request = realChain.request();
    StreamAllocation streamAllocation = realChain.streamAllocation();

    boolean doExtensiveHealthChecks = !request.method().equals("GET");
    HttpStream httpStream = streamAllocation.newStream(client, doExtensiveHealthChecks);
    RealConnection connection = streamAllocation.connection();

    return realChain.proceed(request, streamAllocation, httpStream, connection);
}

分析:

  1. 這個方法中創建了兩個重要的對象,HttpStream 和RealConnection 。這兩個對象是請求協議和連接的核心類,後面做講解。
  2. 這裏又調用了realChain的proceed方法。realChain就是RealInterceptorChain對象,此時index肯定不等於0。該方法的意思是:該攔截器不做實際請求,而是處理後調用下一個攔截器,讓下一個攔截器進行處理。

三CallServerInterceptor類分析

這個類是網絡請求的本質。它的intercept方法源碼如下:

   public Response intercept(Chain chain) throws IOException {
    HttpStream httpStream = ((RealInterceptorChain) chain).httpStream();
    StreamAllocation streamAllocation = ((RealInterceptorChain) chain).streamAllocation();
    Request request = chain.request();

    long sentRequestMillis = System.currentTimeMillis();
    httpStream.writeRequestHeaders(request);//寫請求頭

    if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) {
      Sink requestBodyOut = httpStream.createRequestBody(request, request.body().contentLength());
      BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut);
      request.body().writeTo(bufferedRequestBody);//寫請求體
      bufferedRequestBody.close();
    }
    httpStream.finishRequest();
    Response response = httpStream.readResponseHeaders()
        .request(request)
        .handshake(streamAllocation.connection().handshake())
        .sentRequestAtMillis(sentRequestMillis)
        .receivedResponseAtMillis(System.currentTimeMillis())
        .build();//得到response對象

    if (!forWebSocket || response.code() != 101) {
      response = response.newBuilder()
          .body(httpStream.openResponseBody(response))
          .build();//添加ResponseBody對象
    }
    return response;//返回response對象。
  }

這個類是網絡請求的核心代碼,寫入了請求體,也得到了response對象。

寫入請求體使用的是RequestBody的writeTo方法,調用RequestBody的writeTo方法時需要傳遞一個BufferedSink 對象,這個對象是通過httpStream類的createRequestBody方法得到的。這裏我們先記住,在下一篇blog中再分析httpStream類。

四,總結

1,在ConnectInterceptor類中創建了HttpStream對象 和RealConnection 對象。
2,在CallServerInterceptor中請求網絡,創建response對象,並返回response對象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章