OkHttp3系列(一)初識OkHttp3


OkHttp3是由Square貢獻的HTTP客戶端框架,主要用在Andorid中,但是由於其易用的API、強大的功能、請求的快速等特點,也被大量采用在后端開發領域。本系列文章講述OkHttp3的基本使用、OkHttp3的高級功能以及OkHttp3源碼的解析等,請持續關注。


本篇文章是此系列的第一篇。

介紹

OkHttp是一款優秀的HTTP客戶端框架,OkHttp3OkHttp發展到版本3.0之后的名字。在maven中央倉庫搜索okhttp,可以看到包名為com.squareup.okhttp項目的最后版本號是2.7.5,而3.0版本之后,包名更改為com.squareup.okhttp3,同時版本號從3.0.0-RC1開始。后面為了區分,OkHttp 3.0之后的版本統一稱為OkHttp3

OkHttp3目前已更新到4.8.03.X版本的編寫語言為Java,更新到4.0版本以后,編寫語言修改為Kotlin(可見OkHttp3Android的支持力度)。因為筆者對Kotlin語言不是很了解,而且主要領域在后端開發,所以本系列文章都是以OkHttp3 3.X版本的最后一個更新版本3.14.9為基礎構建代碼、分析代碼。

其他框架

Apache HttpClient

在后端領域,出現比較早而且使用仍然很廣泛的HTTP客戶端框架非Apache HttpClient莫屬了,目前大量項目和公司仍在采用該框架。Apache HttpClient有着不錯的性能、豐富的功能以及強大的自定義實現等特色。但是隨着技術的發展和設計理念的改變,Apache HttpClient顯的有些落伍。Apache HttpClientOkHttp3相比,主要的劣勢在於Apache HttpClient的API設計過於臃腫,使用起來有諸多不便,此外Apache HttpClient對於一些功能沒有提供原生化的支持,需要在每次使用的時候自定義(比如池化HTTP請求、空閑連接處理等),對於首次接觸的開發者就顯得不是特別友好。而OkHttp3是一款對新手很友好的框架,簡便易懂的API以及原生封裝高級功能的特性使得用戶在進行簡單的請求時只需要編寫少量代碼即可完成功能。

下面的示例分別使用Apache HttpClientOkHttp3發送POST請求,比較兩者的代碼量和功能。

// Apache HttpClient發送POST請求
public static String doPost(String url, String params) throws Exception {
    CloseableHttpClient httpclient = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost(url);
    httpPost.setHeader("Content-Type", "application/json");
    String charSet = "UTF-8";
    StringEntity entity = new StringEntity(params, charSet);
    httpPost.setEntity(entity);        
    CloseableHttpResponse response = null;
    
    try {
        response = httpclient.execute(httpPost);
        StatusLine status = response.getStatusLine();
        int state = status.getStatusCode();
        if (state == HttpStatus.SC_OK) {
            HttpEntity responseEntity = response.getEntity();
            String jsonString = EntityUtils.toString(responseEntity);
            return jsonString;
        }
    } finally {
        if (response != null) {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            httpclient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return "";
}
// OkHttp3發送POST請求
public JSONObject doPost(String url, String params) throws Exception {

    OkHttpClient.Builder builder = new OkHttpClient.Builder().build();

    MediaType APPLICATION_JSON = MediaType.parse("application/json");
    Request request = new Request.Builder()
            .url(url)
            .post(RequestBody.create(APPLICATION_JSON, body))
            .addHeader("Content-Type", "application/json")
            .build();

    Response response = null;


    try {
        response = okHttpClient.newCall(request).execute();
    } catch (Exception e) {
        e.printStackTrace();
    }

    if (response.isSuccessful()) {
        return response.body() == null ? "" : response.body().string();
    }

    return "";
}

Apache HttpClient示例的代碼量明顯多於OkHttp3,而且后者代碼的更易讀,同時后者已經默認實現連接池、重試等功能,而前者要是支持這些額外的功能則需要自定義實現。

HttpClient

JDK 11中提供了原生的HTTP客戶端框架,位於包java.net.http中。HttpClient的API設計的也簡單易懂,完成功能所需的代碼量也不是很多,而且API的設計和OkHttp3有幾分相似。

// 使用HttpClient發送POST請求的部分代碼示例
HttpRequest request = HttpRequest.newBuilder()
        .POST(HttpRequest.BodyPublishers.ofString(body))
        .uri(URI.create(url))
        .version(HttpClient.Version.HTTP_1_1)
        .header("Content-Type", "application/json")
        .build();
HttpResponse<String> response = null;
try {
    response = httpClient.send(request,HttpResponse.BodyHandlers.ofString());
} catch (Exception e) {
    e.printStackTrace();
}

但是由於出現的比較晚,提供的功能比較有限,比如對於multipart/form-data的請求就很難實現。但是憑借原生的支持以及優秀的API設計,我覺得它是一個很有前途的HTTP客戶端框架。

功能特色

OkHttp3能在目前眾多HTTP客戶端框架中脫穎而出,並受到持續追捧,在於它提供了一些優秀的功能。

  • 支持允許對同一主機的所有請求共享一個連接。
  • 使用連接池降低請求延遲。
  • 自動處理GZip壓縮減少流量消耗。
  • 緩存請求響應,避免網絡重復請求。
  • 網絡出現問題時,能夠靜默恢復。
  • 對於多個IP的服務,失敗時能夠自動切換到備用地址。
  • 支持現代TLS功能(TLS 1.3,ALPN,證書固定)。
  • 請求/響應API具有流暢的構建器和不變性。
  • 支持同步請求和異步請求。
  • 支持自定義攔截器以實現更高級的功能(例如重定向、日志打印等)。

使用示例

Get請求

OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
    Request request = new Request.Builder()
        .url(url)
        .build();

    try (Response response = client.newCall(request).execute()) {
        return response.body().string();
    }
}

POST請求

public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");

OkHttpClient client = new OkHttpClient();

String post(String url, String json) throws IOException {
    RequestBody body = RequestBody.create(json, JSON);
    Request request = new Request.Builder()
        .url(url)
        .post(body)
        .build();
    try (Response response = client.newCall(request).execute()) {
        return response.body().string();
    }
}

小結

本篇內容介紹了OkHttp3的來源歷史、和其他框架進行了比較、介紹了OkHttp3特色功能並提供了OkHttp3使用的基礎示例。下篇文章將會介紹OkHttp3提供的MockWebServer功能,介紹下該功能如何幫助我們完善代碼。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM