議題
JavaでHTTP通信を書くことになったけれど、クライアントライブラリはいったいどれを使うのが良いのか?
候補が多くて迷った。
前提条件
- 簡単に導入してサクッと使いたい
- 分かりやすくてシンプルなコードにしたい
- そんなにたくさん機能はいらない
- Androidでも使えるといい
何があるか
使ったことがあるもの、知っているもの
- Apache Commons HttpClient > 昔よく使った古株の有名どころ。情報が多い。
- Apache HttpComponents > 上記の発展系
- OkHttp > 最近Androidアプリで使った
- google-http-java-client > 使ったことないけどそこそこメジャーっぽい
- HttpURLConnectionで自前実装 > 昔実装したけど結構めんどい
他にもないか探す
Googleで「okhttp vs」や「apache httpclient vs」の検索候補で出てくるやつをリストアップ
- Google Volley https://github.com/google/volley
- ion https://github.com/koush/ion
- Loopj http://loopj.com/android-async-http/
- Unirest http://unirest.io/
- Jersey https://jersey.java.net/
- Netty https://netty.io/
- Retrofit http://square.github.io/retrofit/
ものによってはHttpClientだけでなく、JSONパースなど色んな機能を含んでいる。
探せばもっとありそう。
世論調査
Uさんの選択
アーリーアダプターな仕事仲間のUさんは、最近手がけたアプリでOkHttpを使っていた。
ネットの記事(日本人)
-
http://qiita.com/Reyurnible/items/33049c293c70bd9924ee
→ 2016-12-09 Retrofit推し -
http://kikutaro777.hatenablog.com/entry/2015/07/19/044634
→ 2015-07-19 Unirest使ってみた -
http://vividcode.hatenablog.com/entry/java/google-http-java-client
→ 2014-11-08 google-http-java-client使ってみた -
http://qiita.com/kou_hon/items/ddfb3fcb0277103e8b03
→VolleyからOkHttpに乗り換え
比較記事じゃないのでジャッジしづらいが、それぞれの雰囲気は伝わる。
4によるとVolleyをAndroidで使うのは厳しそう。
ネットの記事(海外)
-
http://stackoverflow.com/questions/1322335/what-is-the-best-java-library-to-use-for-http-post-get-etc
→2009 Commons HttpClientイチ推し。ただ7年前の記事なので古い。 -
https://www.quora.com/What-is-the-best-both-fast-and-reliable-HTTP-client-library-in-Java
→2014-2015 Unirest、Jersey、Netty、OkHttpなど推し。ばらけ過ぎて参考にならない。
選別方針
- 前提条件に合う
- 新しいものの方が進化してるはず
- ユーザーが多いほうが情報が多く、将来性もある
ざっくり切り捨てる
- Apache Commons HttpClient > 古い
- Apache HttpComponents > 古い
- HttpURLConnection > めんどい
- Google Volley > ディス記事をいくつか見た
- ion > 「もしかして イオン http」って出るくらいマイナー
- Netty > ライブラリというかフレームワークなので仰々しすぎる
- Loopj > あまり情報がない。マイナーすぎ
- Retrofit > 良さげだが、OkHttpを使うし今回の趣旨から少しずれる
ここまでの印象
残ったライブラリたち。
- OkHttp > 本命
- google-http-java-client > 対抗馬
- Unirest > ダークホース
- Jersey > 謎の黒幕
vs でググる
google-http-java-client vs OkHttp
→ 情報が見つからない。
Unirest vs OkHttp
→ https://android.libhunt.com/project/unirest-java/vs/okhttp 知名度は圧倒的にOkHttp
OkHttp vs Jersey
→ 情報がつからない。
ユーザー数比較
記事の多さなどから、なんとなくOkHttp一番ユーザー多そう。
Jerseyは一般的な言葉(ジャージ)なのでググりづらく謎。
コード比較
よくある機能でコードを比較する。
ヘッダーとボディを設定してPOSTするサンプル。
OkHttp
OkHttpClient client = new OkHttpClient();
MediaType MIMEType= MediaType.parse("application/json; charset=utf-8");
RequestBody requestBody = RequestBody.create (MIMEType,"{}");
Request request = new Request.Builder().url(url).post(requestBody).build();
Response response = client.newCall(request).execute();
オブジェクト作りすぎでちょっと読みづらい。
google-http-java-client
Response response =
client
.preparePost("http://localhost:8080/post")
.setBody(builder.toString())
.execute()
.get();
メソッドチェーンでスッキリしているが、POSTなのに最後get()なのが勘違いしそう。
Unirest
HttpResponse<JsonNode> jsonResponse = Unirest.post("http://localhost:8080/post")
.header("Content-Type", "application/json")
.queryString("apiKey", "123")
.field("param1", "nitori")
.field("param2", "1234")
.asJson();
こちらもメソッドチェーン。特に突っ込みどころはない。
Jersey
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080/post").path("resource");
Form form = new Form();
form.param("x", "foo");
form.param("y", "bar");
MyJAXBBean bean =
target.request(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.entity(form,MediaType.APPLICATION_FORM_URLENCODED_TYPE),
MyJAXBBean.class);
※公式のサンプルそのまま
結論
ユーザー数が多くデファクトスタンダード的なポジションを築いているOkHttpが一番無難。
マイナーであることに目をつぶれば、コード的にはUnirestが一番使い勝手がよく綺麗に実装できそう。
さらなる何か
より突っ込んだ要件だと、パフォーマンス、Cookie管理、リトライ、マルチスレッドなど、色々考察する必要がある。
おまけ
Java9 で標準ライブラリにHttpClientが用意されるとかされないとか。
https://thoughtfulsoftware.wordpress.com/2016/09/12/java-9-the-new-httpclient/
でもまだAndroidでは使えない。