最近項目須要使用 Java 重度調用 HTTP API 接口,因而想着封裝一個團隊公用的 HTTP client lib. 這個庫須要支持如下特性:java
鏈接池管理,包括鏈接建立和超時、空閒鏈接數控制、每一個 host 的鏈接數配置等。基本上,咱們想要一個 go HTTP 標準庫自帶的鏈接池管理功能。apache
域名解析控制。由於調用量會比較大,所以但願在域名解析這一層作一個調用端可控的負載均衡,同時能夠對每一個服務器 IP 進行失敗率統計和健康度檢查。緩存
Form/JSON 調用支持良好。服務器
支持同步和異步調用。網絡
在 Java 生態中,雖然有數不清的 HTTP client lib 組件庫,可是大致能夠分爲這三類:app
JDK 自帶的 HttpURLConnection 標準庫;負載均衡
Apache HttpComponents HttpClient, 以及基於該庫的 wrapper, 如 Unirest.異步
非基於 Apache HttpComponents HttpClient, 大量重寫應用層代碼的 HTTP client 組件庫,典型表明是 OkHttp.socket
使用 HttpURLConnection 發起 HTTP 請求最大的優勢是不須要引入額外的依賴,可是使用起來很是繁瑣,也缺少鏈接池管理、域名機械控制等特性支持。以發起一個 HTTP POST 請求爲例:post
能夠看到,使用 HttpURLConnection 發起 HTTP 請求是比較原始(low level)的,基本上你能夠理解爲它就是對網絡棧傳輸層(HTTP 通常爲 TCP,HTTP over QUIC 是 UDP)進行了一次淺層次的封裝,操做原語就是在打開的鏈接上面寫請求 request 與讀響應 response.
並且 HttpURLConnection 沒法支持 HTTP/2. 顯然,官方是知道這些問題的,所以在 Java 9 中,官方在標準庫中引入了一個 high level、支持 HTTP/2 的 HttpClient. 這個庫的接口封裝就很是主流到位了,發起一個簡單的 POST 請求:
封裝的最大特色是鏈式調用很是順滑,支持鏈接管理等特性。可是這個庫只能在 Java 9 及之後的版本使用,Java 9 和 Java 10 並非 LTS 維護版本,而接下來的 Java 11 LTS 要在2018.09.25發佈,應用到線上還須要等待一段時間。所以,雖然挺喜歡這個自帶標準庫(畢竟能夠不引入三方依賴),但當前是沒法在生產環境使用的。
Apache HttpComponents HttpClient 的前身是 Apache Commons HttpClient, 可是 Apache Commons HttpClient 已經中止開發,若是你還在使用它,請切換到 Apache HttpComponents HttpClient 上來。
Apache HttpComponents HttpClient 支持的特性很是豐富,徹底覆蓋咱們的需求,使用起來也很是順手:
對 Client 細緻的配置和自定義支持也是很是到位的:
完整示例請參考 ClientConfiguration.
https://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientConfiguration.java
基本上,在 Java 原生標準庫不給力的狀況下,Apache HttpComponents HttpClient 是最佳的 HTTP Client library 選擇。但這個庫當前還不支持 HTTP/2,支持 HTTP/2 的版本還處於 beta 階段(2018.09.23),所以並不適合用於 Android APP 中使用。
因爲當前 Apache HttpComponents HttpClient 版本並不支持 HTTP/2, 而 HTTP/2 對於移動客戶端而言,不管是從握手延遲、響應延遲,仍是資源開銷看都有至關吸引力。所以這就給了高層次封裝且支持 HTTP/2 的 http client lib 足夠的生存空間。其中最典型的要數OkHttp.
OkHttp 接口設計友好,支持 HTTP/2,而且在弱網和無網環境下有自動檢測和恢復機制,所以,是當前 Android APP 開發中使用最普遍的 HTTP clilent lib 之一。
另外一方面,OkHttp 提供的接口與 Java 9 中 HttpClint 接口比較相似 (嚴格講,應該是 Java 9 借鑑了 OkHttp 等開源庫的接口設計?),所以,對於喜歡減小依賴,鍾情於原生標準庫的開發者來講,在 Java 11 中,從 OkHttp 切換到標準庫是相對容易的。所以,以 OkHttp 爲表明的 http 庫之後的使用場景可能會被蠶食一部分。
HttpURLConnection 封裝層次過低,而且支持特性太少,不建議在項目中使用。除非你的確不想引入第三方 HTTP 依賴(如減小包大小、目標環境不提供三方庫支持等)。
Java 9 中引入的 HttpClient,封裝層次和支持特性都不錯。可是由於 Java 版本的緣由,應用場景還十分有限,建議觀望一段時間再考慮在線上使用。
若是你不須要 HTTP/2特性,Apache HttpComponents HttpClient 是你的最佳選擇,好比在服務器之間的 HTTP 調用。不然,請使用 OkHttp, 如 Android 開發。
擴展閱讀
做者:行思錄
來源:https://liudanking.com/sitelog/java-http-client-lib-comparison/