HTTP Client Library
最近因為團隊使用的 Apache HttpClient 3.x 已經是 2007.12 就已經停止維護的項目了,過了十年,也該是尋找下一個工具的時候了,所以我就開始了 Java HTTP Client Library 的研究心得,一開始當然要先了解各自的特色,然後針對每種 Library 寫最單純的 Example Code,最後就是比較表。
Introduction
- Standards based, pure Java, implementation of HTTP versions 1.0 and 1.1
- Full implementation of all HTTP methods (GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE) in an extensible OO framework.
- Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO, Kerberos authentication schemes.
- Plug-in mechanism for custom authentication schemes.
- Connection management support for use in multi-threaded applications. Supports setting the maximum total connections as well as the maximum connections per host. Detects and closes stale connections.
- Response input streams to efficiently read the response body by streaming directly from the socket to the server.
- The ability to set connection timeouts.
- Support for HTTP/1.1 response caching.
- HTTP/2 support allows all requests to the same host to share a socket.
- Connection pooling reduces request latency (if HTTP/2 isn’t available).
- Transparent GZIP shrinks download sizes.
- Response caching avoids the network completely for repeat requests.
- Supports both synchronous blocking calls and async calls with callbacks.
OkHttp supports Java, the minimum requirement is 1.7.
- JAX-WS Support
- Spring Integration
- Aegis Databinding
- RESTful Service
- WS-* Support
- RESTful Service
- Support synchronous, asynchronous request
Example Code
為了比較好相互比較,以下盡量會以相同寫法呈現,大致為四個步驟:
- New Client
- New Method/Request
- Call/Execute
- Output status code, body, headers
AHC 4.x
HttpClient client = HttpClientBuilder.create().build();
HttpGet get = new HttpGet(url);
HttpResponse response = client.execute(get);
System.out.println(response.getStatusLine().getStatusCode());
System.out.println(EntityUtils.toString(response.getEntity()));
System.out.println(response.getAllHeaders());
AHC 3.x
HttpClient client = new HttpClient();
GetMethod method = new GetMethod(url);
try {
int statusCode = client.executeMethod(method);
System.out.println(statusCode);
System.out.println(new String(method.getResponseBody()));
System.out.println(method.getResponseHeaders());
} finally {
// Release the connection.
method.releaseConnection();
}
Okhttp
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
Response response = client.newCall(request).execute();
System.out.println(response.code());
System.out.println(response.body().string());
System.out.println(response.headers().toMultimap());
CXF
UserService userService = JAXRSClientFactory.create(baseAddress, UserService.class, Collections.singletonList(new JacksonJsonProvider()));
Client client = WebClient.client(userService).accept(MediaType.APPLICATION_JSON_TYPE);
Response result = userService.list(0, 10);
System.out.println(client.getResponse().getStatus());
System.out.println(result);
System.out.println(client.getResponse().getHeaders());
Retrofit2
Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl).addConverterFactory(GsonConverterFactory.create()).build();
UserService service = retrofit.create(UserService.class);
retrofit2.Response> response = service.list(0, 10).execute();
System.out.println(response.code());
System.out.println(response.body());
System.out.println(response.headers().toMultimap());
Comparison table
HTTP Transport Layer
|
HttpClient 3.x |
HttpClient 4.x |
OkHttp |
RESTful Support |
Basic HTTP |
Basic HTTP |
Retrofit |
Performance |
1 |
3 |
2 |
Easy Use |
3 |
2 |
1 |
RESTFul API Layer
- Encapsulation HTTP Connection Layer
- REST API Interface Proxy
- Response Converter
|
CXF |
Retrofit |
RESTful Support |
JAX-RS |
Retrofit Annotation |
Performance |
X |
O |
Easy Use |
O |
O+ |
Conclusion
其實這只是一小部分比較常用的,其他還有很多 Client Library 是沒有時間去了解的,不過經過這次研究,更清楚不同層級 Library 的差異,以及各自專注在不同的職責;從最後的比較表來看,目前在各方面比較好的應該是使用 Okhttp + Retrofit2 吧。
Appendix
official Converter modules
Gson: com.squareup.retrofit:converter-gson
Jackson: com.squareup.retrofit:converter-jackson
Moshi: com.squareup.retrofit:converter-moshi
Protobuf: com.squareup.retrofit:converter-protobuf
Wire: com.squareup.retrofit:converter-wire
Simple XML: com.squareup.retrofit:converter-simplexml