第49章 JAX-RS 2.0 Client API
概要
JAX-RS 2.0 は、REST 呼び出しや HTTP クライアント呼び出しを行うために使用できるフル機能のクライアント API を定義します。これには、Fluent API(要求の構築を簡素化するための)、メッセージを解析するフレームワーク (エンティティープロバイダーと呼ばれるタイプのプラグイン)、クライアント側での非同期呼び出しのサポートが含まれます。
49.1. JAX-RS 2.0 クライアント API の概要
概要
JAX-RS 2.0 は JAX-RS クライアントの Fluent API を定義し、HTTP 要求をステップバイステップで構築してから、適切な HTTP 動詞 (GET、POST、PUT または DELETE) を使用して要求を呼び出すことができます。
Blueprint XML または Spring XML で JAX-RS クライアントを定義することもできます (jaxrs:client
要素を使用)。このアプローチの詳細は、「JAX-RS クライアントエンドポイントの設定」 を参照してください。
Dependencies
アプリケーションで JAX-RS 2.0 クライアント API を使用するには、以下の Maven 依存関係をプロジェクトの pom.xml
ファイルに追加する必要があります。
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-client</artifactId> <version>3.3.6.fuse-780029-redhat-00001</version> </dependency>
非同期呼び出し機能を使用する予定 (「クライアントの非同期処理」を参照) を使用する場合は、以下の Maven 依存関係も必要になります。
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-hc</artifactId> <version>3.3.6.fuse-780029-redhat-00001</version> </dependency>
クライアント API パッケージ
JAX-RS 2.0 クライアントインターフェイスとクラスは、以下の Java パッケージにあります。
javax.ws.rs.client
JAX-RS 2.0 Java クライアントを開発する場合には、通常はコアパッケージからクラスにアクセスする必要もあります。
javax.ws.rs.core
シンプルなクライアント要求の例
次のコードフラグメントは、JAX-RS 2.0 クライアント API を使用して http://example.org/bookstore
JAX-RS サービスで呼び出しを行い、GET HTTP メソッドで呼び出す簡単な例を示しています。
// Java import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Client; import javax.ws.rs.core.Response; ... Client client = ClientBuilder.newClient(); Response res = client.target("http://example.org/bookstore/books/123") .request("application/xml").get();
Fluent API
JAX-RS 2.0 クライアント API は Fluent API(ドメイン固有言語と呼ばれることもあります) として設計されています。Fluent API では、Java メソッドが単純な言語のコマンドであるかのように、Java メソッドのチェーンが単一のステートメントで呼び出されます。JAX-RS 2.0 では、Fluent API を使用して REST 要求を作成して呼び出します。
REST 呼び出しを実行する手順
JAX-RS 2.0 クライアント API を使用すると、クライアント呼び出しは以下のような一連のステップでビルドされ、呼び出されます。
- クライアントをブートストラップします。
- ターゲットを設定します。
- 呼び出しを構築して実行します。
- 応答を解析します。
クライアントのブートストラップ
最初のステップでは、javax.ws.rs.client.Client
オブジェクトを作成し、クライアントをブートストラップします。この Client
インスタンスは比較的重いオブジェクトで、JAX-RS クライアント (場合によってはインターセプターや追加の CXF 機能を含む) をサポートするために必要なテクノロジーのスタックを表します。理想的には、新規オブジェクトを作成する代わりに、可能な場合はクライアントオブジェクトを再利用する必要があります。
新しい Client
オブジェクトを作成するには、以下のように ClientBuilder
クラスで静的メソッドを呼び出します。
// Java import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Client; ... Client client = ClientBuilder.newClient(); ...
ターゲットの設定
ターゲットを設定すると、REST 呼び出しに使用される URI を効果的に定義します。次の例は、path(String)
メソッドを使用して、ベース URI base
を定義し、ベース URI にパスセグメントを追加する方法を示しています。
// Java import javax.ws.rs.client.WebTarget; ... WebTarget base = client.target("http://example.org/bookstore/"); WebTarget books = base.path("books").path("{id}"); ...
呼び出しの構築および実行
これは実際には 2 つのステップを 1 つにまとめたものです。最初に、HTTP 要求 (ヘッダー、受け入れられたメディアタイプなどを含む) を構築し、次に、関連する HTTP メソッドを呼び出します (必要に応じて、オプションで要求メッセージ本文を提供します)。
たとえば、application/xml
メディア型を受け入れるリクエストを作成および呼び出すには、以下を実行します。
// Java import javax.ws.rs.core.Response; ... Response resp = books.resolveTemplate("id", "123").request("application/xml").get();
応答を解析します
最後に、前のステップで取得したレスポンス resp
を解析する必要があります。通常、レスポンスは javax.ws.rs.core.Response
オブジェクトの形式で返されます。これは、HTTP ヘッダーと、他の HTTP メタデータおよび HTTP メッセージボディー (ある場合) ををカプセル化します。
String
形式で返された HTTP メッセージにアクセスする場合、以下のように String.class
引数を指定して readEntity
メソッドを呼び出して、簡単にアクセスできます。
// Java ... String msg = resp.readEntity(String.class);
String.class
を readEntity
の引数として指定すると、レスポンスのメッセージボディーに String
として常にアクセスできます。メッセージボディーを一般的に変換する場合には、エンティティープロバイダー を指定して変換を実行できます。詳細は、「要求と応答の解析」 を参照してください。