1. 概要

この記事では、 Google HTTP Client Library for Java について説明します。これは、HTTP接続プロトコルを介してリソースにアクセスするための高速で抽象化されたライブラリです。

クライアントの主な機能は次のとおりです。

  • 低レベルのライブラリを分離できるHTTP抽象化レイヤー
  • HTTP応答および要求コンテンツの高速で効率的かつ柔軟なJSONおよびXML解析モデル
  • HTTPリソースマッピング用の使いやすいアノテーションと抽象化

このライブラリはJava5以降でも使用できるため、レガシー(SEおよびEE)プロジェクトに適しています。

この記事では、ライブラリの最も興味深い機能のいくつかをカバーしながら、がGitHubAPIに接続してユーザーを取得する簡単なアプリケーションを開発します。

2. Mavenの依存関係

ライブラリを使用するには、google-http-client依存関係が必要です。

<dependency>
    <groupId>com.google.http-client</groupId>
    <artifactId>google-http-client</artifactId>
    <version>1.23.0</version>
</dependency>

最新バージョンはMavenCentralにあります。

3. 簡単なリクエストをする

まず、GitHubページに簡単なGETリクエストを送信して、GoogleHttpクライアントがそのままの状態でどのように機能するかを紹介しましょう。

HttpRequestFactory requestFactory
  = new NetHttpTransport().createRequestFactory();
HttpRequest request = requestFactory.buildGetRequest(
  new GenericUrl("https://github.com"));
String rawResponse = request.execute().parseAsString()

最も単純なリクエストを作成するには、少なくとも次のものが必要です。

  • HttpRequestFactoryこれはリクエストの作成に使用されます
  • HttpTransport低レベルHTTPトランスポート層の抽象化
  • GenericUrlURLをラップするクラス
  • HttpRequestはリクエストの実際の実行を処理します

次のセクションでは、これらすべてと、JSON形式を返す実際のAPIを使用したより複雑な例について説明します。

4. プラグ可能なHTTPトランスポート

ライブラリには、十分に抽象化された HttpTransport クラスがあり、その上に構築して、選択した低レベルのHTTPトランスポートライブラリに変更できます。

public class GitHubExample {
    static HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
}

この例では、すべてのJavaSDKにあるHttpURLConnectionに基づくNetHttpTransportを使用しています。 これはよく知られていて信頼できるので、最初の選択として適しています。

もちろん、高度なカスタマイズが必要な場合もあります。そのため、より複雑な低レベルのライブラリが必要になります。

この種の場合には、 ApacheHttpTransport:があります

public class GitHubExample {
    static HttpTransport HTTP_TRANSPORT = new ApacheHttpTransport();
}

ApacheHttpTransport は、接続を構成するためのさまざまな選択肢を含む、人気のある ApacheHttpClientに基づいています。

さらに、ライブラリには低レベルの実装を構築するオプションがあり、非常に柔軟です。

5. JSON解析

Google Httpクライアントには、JSON解析用の別の抽象化が含まれています。 これの主な利点は、低レベルの解析ライブラリの選択が交換可能であることです。

3つの組み込みの選択肢があり、そのすべてが JsonFactory、を拡張し、独自の実装の可能性も含まれています。

5.1. 交換可能な解析ライブラリ

この例では、google-http-client-jackson2依存関係を必要とするJackson2実装を使用します。

<dependency>
    <groupId>com.google.http-client</groupId>
    <artifactId>google-http-client-jackson2</artifactId>
    <version>1.23.0</version>
</dependency>

これに続いて、 JsonFactory:を含めることができます。

public class GitHubExample {

    static HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
    staticJsonFactory JSON_FACTORY = new JacksonFactory();
}

JacksonFactory は、解析/シリアル化操作用の最も高速で最も人気のあるライブラリです。

これには、ライブラリのサイズが犠牲になります(特定の状況では問題になる可能性があります)。 このため、Googleは GsonFactory も提供しています。これは、軽量のJSON解析ライブラリであるGoogleGSONライブラリの実装です。

低レベルのパーサー実装を作成する可能性もあります。

5.2. @ Keyアノテーション

@Key アノテーションを使用して、JSONからの解析またはJSONへのシリアル化が必要なフィールドを示すことができます。

public class User {
 
    @Key
    private String login;
    @Key
    private long id;
    @Key("email")
    private String email;

    // standard getters and setters
}

ここでは、 User 抽象化を作成しています。これは、GitHub APIからバッチで受け取ります(実際の解析については、この記事の後半で説明します)

@Keyアノテーションがないフィールドは内部と見なされ、JSONから解析またはシリアル化されないことに注意してください。 また、フィールドの可視性は重要ではなく、getterメソッドまたはsetterメソッドの存在も重要ではありません。

@Key アノテーションの値を指定して、正しいJSONキーにマップできます。

5.3. GenericJson

宣言し、@Keyとしてマークしたフィールドのみが解析されます。

他のコンテンツを保持するために、クラスを宣言して GenericJson:を拡張できます。

public class User extends GenericJson {
    //...
}

GenericJsonMapインターフェースを実装します。つまり、getメソッドとputメソッドを使用して、リクエスト/レスポンスでJSONコンテンツを設定/取得できます。

6. 電話をかける

Google Httpクライアントでエンドポイントに接続するには、 HttpRequestFactory が必要です。これは、以前の抽象化 HttpTransportおよびJsonFactory:で構成されます。

public class GitHubExample {

    static HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
    static JsonFactory JSON_FACTORY = new JacksonFactory();

    private static void run() throws Exception {
        HttpRequestFactory requestFactory 
          = HTTP_TRANSPORT.createRequestFactory(
            (HttpRequest request) -> {
              request.setParser(new JsonObjectParser(JSON_FACTORY));
          });
    }
}

次に必要になるのは、接続するURLです。 ライブラリはこれをGenericUrlを拡張するクラスとして処理し、宣言されたフィールドはクエリパラメータとして扱われます。

public class GitHubUrl extends GenericUrl {

    public GitHubUrl(String encodedUrl) {
        super(encodedUrl);
    }

    @Key
    public int per_page;
 
}

ここで、 GitHubUrlで、 per_page プロパティを宣言して、GitHubAPIへの1回の呼び出しで必要なユーザー数を示します。

GitHubUrl:を使用して呼び出しを作成し続けましょう

private static void run() throws Exception {
    HttpRequestFactory requestFactory
      = HTTP_TRANSPORT.createRequestFactory(
        (HttpRequest request) -> {
          request.setParser(new JsonObjectParser(JSON_FACTORY));
        });
    GitHubUrl url = new GitHubUrl("https://api.github.com/users");
    url.per_page = 10;
    HttpRequest request = requestFactory.buildGetRequest(url);
    Type type = new TypeToken<List<User>>() {}.getType();
    List<User> users = (List<User>)request
      .execute()
      .parseAs(type);
}

API呼び出しに必要なユーザー数を指定し、HttpRequestFactoryを使用してリクエストを作成する方法に注目してください。

これに続いて、GitHub APIの応答にはユーザーのリストが含まれているため、複雑なものを提供する必要がありますタイプ 、 これはリスト

次に、最後の行で、呼び出しを行い、Userクラスのリストへの応答を解析します。

7. カスタムヘッダー

APIリクエストを行うときに通常行うことの1つは、ある種のカスタムヘッダー、または変更されたヘッダーを含めることです。

HttpHeaders headers = request.getHeaders();
headers.setUserAgent("Baeldung Client");
headers.set("Time-Zone", "Europe/Amsterdam");

これを行うには、リクエストを作成した後、実行して必要な値を追加する前に、HttpHeadersを取得します。

GoogleHttpクライアントに注意してください特別なメソッドとしていくつかのヘッダーが含まれています。 The ユーザーエージェントたとえば、ヘッダーをsetメソッドだけに含めようとすると、エラーがスローされます。

8. 指数バックオフ

Google Httpクライアントのもう1つの重要な機能は、特定のステータスコードとしきい値に基づいてリクエストを再試行できることです。

リクエストオブジェクトを作成した直後に、指数バックオフ設定を含めることができます。

ExponentialBackOff backoff = new ExponentialBackOff.Builder()
  .setInitialIntervalMillis(500)
  .setMaxElapsedTimeMillis(900000)
  .setMaxIntervalMillis(6000)
  .setMultiplier(1.5)
  .setRandomizationFactor(0.5)
  .build();
request.setUnsuccessfulResponseHandler(
  new HttpBackOffUnsuccessfulResponseHandler(backoff));

指数バックオフはHttpRequestでデフォルトでオフになっているため、HttpUnsuccessfulResponseHandlerのインスタンスをHttpRequestに含めてアクティブにする必要があります。

9. ロギング

Google Httpクライアントは、 java.util.logging.Logger を使用して、URL、ヘッダー、コンテンツなどのHTTPリクエストとレスポンスの詳細をログに記録します。

通常、ロギングはlogging.propertiesファイルを使用して管理されます。

handlers = java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level = ALL
com.google.api.client.http.level = ALL

この例では、 ConsoleHandler を使用していますが、FileHandlerを選択することもできます。

プロパティファイルは、JDKロギング機能の動作を設定します。 この構成ファイルは、システムプロパティとして指定できます。

-Djava.util.logging.config.file=logging.properties

したがって、ファイルとシステムプロパティを設定した後、ライブラリは次のようなログを生成します。

-------------- REQUEST  --------------
GET https://api.github.com/users?page=1&per_page=10
Accept-Encoding: gzip
User-Agent: Google-HTTP-Java-Client/1.23.0 (gzip)

Nov 12, 2017 6:43:15 PM com.google.api.client.http.HttpRequest execute
curl -v --compressed -H 'Accept-Encoding: gzip' -H 'User-Agent: Google-HTTP-Java-Client/1.23.0 (gzip)' -- 'https://api.github.com/users?page=1&per_page=10'
Nov 12, 2017 6:43:16 PM com.google.api.client.http.HttpResponse 
-------------- RESPONSE --------------
HTTP/1.1 200 OK
Status: 200 OK
Transfer-Encoding: chunked
Server: GitHub.com
Access-Control-Allow-Origin: *
...
Link: <https://api.github.com/users?page=1&per_page=10&since=19>; rel="next", <https://api.github.com/users{?since}>; rel="first"
X-GitHub-Request-Id: 8D6A:1B54F:3377D97:3E37B36:5A08DC93
Content-Type: application/json; charset=utf-8
...

10. 結論

このチュートリアルでは、Java用のGoogleHTTPクライアントライブラリとそのより便利な機能を紹介しました。 彼らのGithubには、ライブラリのソースコードだけでなく、それに関する詳細情報が含まれています。

いつものように、このチュートリアルの完全なソースコードは、GitHubからで入手できます。