Red Hat Training
A Red Hat training course is available for Red Hat Fuse
49.4. 要求と応答の解析
概要
HTTP 呼び出しを行う際の重要な側面は、クライアントが送信要求メッセージと受信応答を解析できる必要があることです。JAX-RS 2.0 では、主要な概念は、メディアタイプでタグ付けされた raw メッセージを表す Entity クラスです。未加工メッセージを解析するために、メディアタイプと特定の Java タイプとの間で変換できる複数の エンティティープロバイダー を登録できます。
つまり、JAX-RS 2.0 のコンテキストでは、Entity は raw メッセージの表現で、エンティティープロバイダーは (メディア型に基づく) raw メッセージを解析する機能を提供するプラグインです。
Entities
Entity は、メタデータ (メディア型、言語、およびエンコーディング) によって拡張されたメッセージボディーです。Entity インスタンスはメッセージを raw 形式で保持し、特定のメディア型に関連付けられます。Entity オブジェクトのコンテンツを、 Java オブジェクトに変換するには、指定のメディア型を必要な Java 型にマッピングできる エンティティープロバイダー が必要です。
バリアント
javax.ws.rs.core.Variant オブジェクトは、以下のように Entity に関連付けられたメタデータをカプセル化します。
- メディアタイプ
- 言語
- エンコーディング
実質的に、Entity は HTTP メッセージの内容で設定され、Variant メタデータによって拡張されると考えることができます。
エンティティープロバイダー
エンティティープロバイダーは、メディアタイプと Java 型間のマッピング機能を提供するクラスです。実際には、エンティティープロバイダーは、特定のメディアタイプ (または複数のメディアタイプ) のメッセージを解析できるクラスと考えることができます。エンティティープロバイダーには、以下の 2 つの異なるバリアントがあります。
MessageBodyReader- メディアタイプから Java 型へのマッピング機能を提供します。
MessageBodyWriter- Java 型からメディアタイプへのマッピング機能を提供します。
標準のエンティティープロバイダー
次の Java とメディアタイプの組み合わせのエンティティープロバイダーが標準として提供されています。
byte[]-
すべてのメディア型 (
*/*) java.lang.String-
すべてのメディア型 (
*/*) java.io.InputStream-
すべてのメディア型 (
*/*) java.io.Reader-
すべてのメディア型 (
*/*) java.io.File-
すべてのメディア型 (
*/*) javax.activation.DataSource-
すべてのメディア型 (
*/*) javax.xml.transform.Source-
XML 型 (
text/xml、application/xml、およびapplication/*+xmlフォームのメディア型)。 javax.xml.bind.JAXBElementおよびアプリケーションが提供する JAXB クラス-
XML 型 (
text/xml、application/xml、およびapplication/*+xmlフォームのメディア型)。 MultivaluedMap<String,String>-
フォームコンテンツ (
application/x-www-form-urlencoded)。 StreamingOutput-
すべてのメディア型 (
*/*)、MessageBodyWriterのみ。 java.lang.Boolean、java.lang.Character、java.lang.Number-
text/plainのみ対象。ボックス/アンボックス変換でサポートされるプリミティブタイプ。
Response オブジェクト
デフォルトの戻り値型は javax.ws.rs.core.Response 型で、型付けされていない応答を表します。Response オブジェクトは、メッセージボディー、HTTP ステータス、HTTP ヘッダー、メディア型など、完全な HTTP 応答へのアクセスを提供します。
応答ステータスへのアクセス
応答の状態には、getStatus メソッド (HTTP ステータスコードを返す) からアクセスできます。
int status = resp.getStatus();
または、説明文字列も提供する getStatusInfo メソッドでアクセスすることもできます。
String statusReason = resp.getStatusInfo().getReasonPhrase();
返されるヘッダーへのアクセス
以下の方法のいずれかを使用して HTTP ヘッダーにアクセスできます。
MultivaluedMap<String,Object> getHeaders() MultivaluedMap<String,String> getStringHeaders() String getHeaderString(String name)
たとえば、Response に Date ヘッダーがあることが分かっている場合は、以下のようにアクセスできます。
String dateAsString = resp.getHeaderString("Date");返されるクッキーへのアクセス
以下のように、getCookies メソッドを使用して、Response で設定された新しいクッキーにアクセスできます。
import javax.ws.rs.core.NewCookie; ... java.util.Map<String,NewCookie> cookieMap = resp.getCookies(); java.util.Collection<NewCookie> cookieCollection = cookieMap.values();
返されるメッセージコンテンツへのアクセス
Response オブジェクトの readEntity メソッドのいずれかを呼び出すと、返されるメッセージコンテンツにアクセスできます。readEntity メソッドは利用可能なエンティティープロバイダーを自動的に呼び出し、メッセージを要求された型 (readEntity の最初の引数として指定) に変換します。たとえば、メッセージコンテンツに String 型としてアクセスするには、次のように指定します。
String messageBody = resp.readEntity(String.class);
コレクションの戻り値
返されたメッセージを Java 汎用型 (例: List または Collection 型) としてアクセスする必要がある場合、javax.ws.rs.core.GenericType<T> コンストラクションを使用してリクエストメッセージ型を指定できます。以下に例を示します。
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Client;
import javax.ws.rs.core.GenericType;
import java.util.List;
...
GenericType<List<String>> stringListType = new GenericType<List<String>>() {};
Client client = ClientBuilder.newClient();
List<String> bookNames = client.target("http://example.org/bookstore/booknames")
.request("text/plain")
.get(stringListType);