最近项目须要使用 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/