読者です 読者をやめる 読者になる 読者になる

ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

google-http-java-client 入門

Java ライブラリ

Java で HTTP 通信するときのクライアントライブラリを何にするかいつも悩むのですが、最近 google-http-java-client が気になってたのでちょっと使ってみました。 汎用的に HTTP 通信ができればよい、というような用途にはちょうど良さそうです。

数年前からベータ版や RC 版としては存在していましたが、正式にリリースされたのは今年のようです。

google-http-java-client について

Google によって書かれた Java の HTTP クライアントライブラリです。

HTTP トランスポートの抽象化がされており、実際の HTTP 通信を行う低層のライブラリを選択できるのが特徴です。 例えば java.net.HttpURLConnection を使ったり、Apache HTTP Client を使ったりできます。

また、リクエストやレスポンスのコンテンツボディの XMLJSON のパースやシリアライズを行う機能も含まれており、便利です。

使用できる環境は、Java 5 以降の Java SE 環境や Java EE 環境、Android 1.5 以降などです。

ざっくりとした使い方

準備

使用するためには JAR ファイルをライブラリパスに追加するとか、Maven の依存関係管理に追加するとかする必要があります。 2014 年 11 月 8 日現在の最新バージョンは 1.19.0 で、Maven Central Repository に置かれています。

Gradle を使っているならば次のように依存関係を記述すればよいです。

repositories {
    mavenCentral()
}

dependencies {
    compile 'com.google.http-client:google-http-client:1.19.0'
}

HTTP リクエストを行う処理の全体の流れ

  1. HttpTransport オブジェクトを用意する。
    • これはアプリケーション全体で 1 つだけ存在すればよい。
  2. HttpTransportcreateRequestFactory メソッドを呼んで HttpRequestFactory オブジェクトを生成する。
  3. HttpRequestFactory から HttpRequest を生成する。
  4. HttpRequestexecute メソッドを呼び出してリクエスト実行、レスポンスとして HttpResponse を取得。
  5. レスポンスを処理したあと、終了処理。

サンプルコード

GET リクエストを投げてレスポンスボディを表示する例を Gist に置いてあります。 バージョン 1.19.0 を使用しています。

レスポンスのパース

HttpRequest#setParser メソッド を使って ObjectParser インターフェイスを実装したインスタンスをパーサーとして登録しておくと、レスポンスのパースを任せることができます。

ライブラリに含まれている ObjectParser の実装としては、JsonObjectParser クラスUrlEncodedParser クラス があります。

サンプルコード

/* 必要な import 文
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.UrlEncodedParser;
import com.google.api.client.util.GenericData;
*/

// HttpRequest オブジェクトにパーサーを設定しておく。
// (req は HttpRequest オブジェクト)
req.setParser(new UrlEncodedParser());
// リクエスト実行。
HttpResponse res = req.execute();
try {
    // レスポンスのパースを行う。 (上で設定した UrlEncodedParser が使われる。)
    GenericData d = res.parseAs(GenericData.class);
} finally {
    // (以下略)

レスポンスのパース後のクラスを作る

上の例ではパース後のクラスとして GenericData を使用しましたが、どういうパラメータが渡ってくるかわかっている場合、それを受け取るためのクラスを用意しておいて、フィールドに値を設定させることもできます。

例えば、OAuth 1.0 Protocol の Temporary Credentials を取得するためのリクエストのレスポンスをパースする場合を考えてみましょう。 レスポンスの形式は 「oauth_token=xxxxx&oauth_token_secret=xxxxx&oauth_callback_confirmed=true」 というものであることはわかっているので、次のようなクラスでレスポンスを受け取ることができます。 @Key アノテーション をフィールドに付けることで、パースした結果を受け取るフィールドであることを示しています。

/* 必要な import 文
import com.google.api.client.util.GenericData;
import com.google.api.client.util.Key;
*/

// 必ずしも GenericData を継承する必要はないが、継承しておけばフィールドで定義されていないパラメータも受け取ることができる。
public class OAuthTemporaryCredentialResponse extends GenericData {
    @Key("oauth_token")
    public String identifier;
    @Key("oauth_token_secret")
    public String sharedSecret;
    @Key("oauth_callback_confirmed")
    public String callbackConfirmed;
}

そして、パース時にこのクラスを指定することでパース結果を OAuthTemporaryCredentialResponse オブジェクトとして受け取ることができます。

    OAuthTemporaryCredentialResponse d = res.parseAs(OAuthTemporaryCredentialResponse.class);
    System.out.println("identifier: " + d.identifier); // フィールドアクセスによりレスポンスの値にアクセスできる。

関連