RESTful アプリケーションでのリソースのメディア・タイプの定義
リソースは、複数の形式で表示されます。XML、JavaScript Object Notation (JSON)、 Atom 形式や、PNG、JPEG、GIF などのバイナリー形式、プレーン・テキスト形式、 および専有形式が、リソースを表現するために使用されます。REST (Representational State Transfer) は、単一リソースを複数形式で表示する柔軟性を提供します。
始める前に
JAX-RS Web アプリケーションでリソースを定義します。
このタスクについて
リソースには「表現」があります。リソース表現は、 URI を使用してリソースから戻されるか、またはリソースに送信される HTTP メッセージ中のコンテンツ です。リソースがサポートする各表現には、 それぞれ対応するメディア・タイプがあります。例えば、XML としてフォーマットされたコンテンツを リソースが戻そうとする場合、関連するメディア・タイプとして application/xml を HTTP メッセージ内で 使用できます。
アプリケーションの要件に 応じて、リソースは、優先する 1 つのみの形式の表現を戻すことも、複数の形式 の表現を戻すこともできます。例えば、JavaScript クライアントを使用してアクセスされた リソースにとって、JSON 表現が適している場合があります。これは JSON が取り込みやすいためです。
JAX-RS に は、リソース・メソッドが読み取りおよび書き込みを行うのに受け入れ可能なメディア・タイプを宣言するための @Consumes アノテーションおよび @Produces アノテーションがあります。
また、JAX-RS では、 エンティティー・プロバイダーを使用して、Java™ 型とリソース表現 との間でマッピングが行われます。MessageBodyReader エンティティー・プロバイダー は、要求エンティティーを読み取って、その要求エンティティー を Java 型に非直列化します。MessageBodyWriter エンティティー・プロバイダー は、Java 型から応答エンティティーに 直列化します。
Java 型 | MessageBodyReader | MessageBodyWriter | サポートされるコンテンツ・タイプ |
---|---|---|---|
byte[] | X | X | */* |
java.io.InputStream | X | X | */* |
java.io.Reader | X | X | */* |
java.lang.String | X | X | */* |
java.io.File | X | X | */* |
javax.activation.DataSource | X | X | */* |
javax.xml.transform.Source | X | X | text/xml、application/xml、application/*+xml |
javax.ws.rs.core.MultivaluedMap | X | X | application/x-www-form-urlencoded |
JAXB タイプ | X | X | text/xml、application/xml、application/*+xml |
javax.ws.rs.core.StreamingOutput | X | */* |
要求エンティティー・パラメーターとして String 値 が使用されている場合、MessageBodyReader エンティティー・プロバイダー は要求本体を新しい String に非直列化します。 リソース・メソッドで戻りのタイプとして JAXB タイプが使用されている場合、 MessageBodyWriter は JAXB (Java Architecture for XML Binding) オブジェクトを応答本体に直列化します。
ある Java 型 から特定の表現へのカスタムのマッピングが必要な場合は、アプリケーションによって定義されるエンティティー・プロバイダー の使用に関する説明を参照してください。
複数の形式を処理できるクライアントがあり、 戻すための最適のリソース表現をサーバーが決定するようにしたい場合は、 複数のコンテンツ・タイプを処理するための JAX-RS アプリケーションでのコンテンツ・ネゴシエーションの使用 についての説明をお読みください。
XML、 JSON、および Atom の仕様では、アプリケーションでのリソース表現の形式に関する 詳細が提供されています。リソース表現形式について詳しく学習 するには、それらの仕様を参照してください。
手順
- 要求または応答に使用するリソース表現形式 (XML、 JSON、または ATOM など) を決定します。
- リソース・メソッドに適した @Consumes アノテーションおよび @Produces アノテーションを 追加します。
- 要求のコンテンツをリソースが読み取る必要がある場合、 リソース・メソッドに要求エンティティー・パラメーターを追加します。 この要求エンティティー・パラメーター は、アノテーションがないメソッドの単一の Java パラメーター です。
- リソース・メソッドが応答でコンテンツを戻す場合、 JAX-RS エンティティー・プロバイダーが書くことのできる Java オブジェクト を戻します。 この Java オブジェクトは、HTTP 応答内の応答エンティティー にマップされます。戻されるオブジェクトは、JAX-RS がサポートする Java 型であるか、 または、javax.ws.rs.core.Response または javax.ws.rs.core.GenericEntity 型にラップされていなければなりません。
タスクの結果
要求エンティティーがリソース・メソッド・エンティティー・パラメーターにマップされ、 戻される応答オブジェクトは該当するリソース表現の応答エンティティーにマップ されました。
例
以下の例は、RESTful 書店アプリケーション用に XML を リソース表現として定義しています。
- 要求エンティティーを読み取るため、または応答エンティティーを戻す
ために使用したい、リソース・メソッドを特定します。
その後に続く retrieveSpecificBookInformation メソッド 例では、読み取られる要求エンティティーはありません。 しかし、戻される応答オブジェクトが 1 つあります。このオブジェクト は、エンティティー情報が含まれている JAXB オブジェクトをラップしています。リソース・メソッドに @Produces アノテーションが追加されていて、 メディア・タイプが application/xml と設定 されていることは、このリソース・メソッドが 常にメディア・タイプ application/xml の XML 表現を戻すことを示しています。
Accept HTTP 要求ヘッダー値が application/xml メディア・タイプと 互換の値であるクライアントは、このメソッドを正しく起動します。
application/xml メディア・タイプと互換の Accept HTTP ヘッダー値 を持たないクライアントは、自動的に 406 Not Acceptable 応答 状況 (受け入れ可能な応答をサーバーが生成できないことを示す) を 受け取ります。
以下の例は、要求エンティティーを読み取るか、または応答エンティティーを戻す、 リソース・メソッドを特定します。
/* * Book.java * This class represents individual books. The @Produces annotation specifies a media type of application/xml. */ @Path(“/bookstore/books/{bookID}”) public class Book { @GET @Produces(“application/xml”) public javax.ws.rs.core.Response retrieveSpecificBookInformation(@PathParam(“bookID”) String theBookID, @Context javax.ws.rs.core.HttpHeaders headers) { /* … */ return Response.ok(/* JAXB object to represent response body entity */).expires(/* Expires response header value*/).header(“CustomHeaderName”, “CustomHeaderValue”).build(); } @PUT public String updateBookInformation(@PathParam(“bookID”) String theBookID, String theRequestEntity, @javax.ws.rs.HeaderParam(“Content-Length”) String contentLengthHeader) { /* … */ } @DELETE public void removeBook(@PathParam(“bookID”) String theBookID) { /* … */ } }
- 要求情報をコンシュームする必要のあるリソース・メソッドを
特定します。
以下のスニペットでは、book リソースに対する PUT メソッド は、@Consumes アノテーションに定義されているように、メディア・タイプ text/plain が送信された 場合に要求エンティティー・コンテンツを受け入れます。このメソッドは、 @Produces アノテーションに指定されているように、text/plain 表現のコンテンツを 戻します。
Content-Type 値が text/plain のメッセージをクライアントが送信しない 場合、PUT リソース・メソッドは起動されません。Content-Type: application/xml が HTTP 要求ヘッダーに入って 送信された場合、updateBookInformation Java メソッド は呼び出されません。
DELETE メソッドは、要求エンティティーを読み取ることも、 応答エンティティーを戻すこともしないため、 @Consumes アノテーションも @Produces アノテーションも必要ありません。
以下の例 は、要求情報をコンシュームするリソース・メソッドを特定します。
/* * Book.java * This class represents represent individual books with custom headers. */ @Path(“/bookstore/books/{bookID}”) public class Book { @GET @Produces(“application/xml”) public javax.ws.rs.core.Response retrieveSpecificBookInformation(@PathParam(“bookID”) String theBookID, @Context javax.ws.rs.core.HttpHeaders headers) { /* … */ return Response.ok(/* JAXB object to represent response body entity */).expires(/* Expires response header value).header(“CustomHeaderName”, “CustomHeaderValue”).build(); } @PUT @Consumes(“text/plain”) @Produces(“text/plain”) public String updateBookInformation(@PathParam(“bookID”) String theBookID, String theRequestEntity, @javax.ws.rs.HeaderParam(“Content-Length”) String contentLengthHeader) { /* … */ String responseEntity = /* a plain text representation */; return responseEntity; } @DELETE public void removeBook(@PathParam(“bookID”) String theBookID) { /* … */ } }
次のタスク
表現のためにサポートされているすべての標準メディア形式のリストについては、JAX-RS 仕様 を参照してください。
上級ユーザー は、Java 型から表現へのカスタム・マッピングの定義や、 望ましいリソース表現をクライアントがネゴシエーションするためのコンテンツ・ネゴシエーションの使用について検討する場合があるかもしれません。 こういったオプションについて詳しく理解するには、カスタム定義されたエンティティー形式の使用についての説明、 または、コンテンツ・ネゴシエーション情報を使用した複数コンテンツ・タイプの処理についての 説明を参照してください。