Jerseyを使ってRESTを簡便化する
では、JerseyはRESTの利用に関してどのような役割を果たすのでしょうか? Jerseyは、上述の低いレベルのHTTP処理を行います。Jerseyは、RESTfulなHTTPリクエストを、Javaコードの中の処理機構に直接マッピングする方法を提供します。
例えば、RESTfulなURLであるhttp://localhost:9090/card-dealer-rest/rest/card-dealer/cardが、HTTPメソッド GETによってWebサーバに送信されたとしましょう。Jerseyがない場合、RESTステートメントを処理するには、コンピュータからのHTTPリクエストを取得し、URLを分解してそれが表すものを調べ、HTTPのMETHODフィールドに基づく一連のプログラミングによって、RESTfulなHTTPリクエストに対するHTTPレスポンスを作成するという、低レベルの処理を行う必要があります。これはかなりの作業です。しかしJerseyを使用すれば、その作業はずっと容易になります。
リスト1に、Jerseyで拡張したコードを示します。
01: @Path("/card-dealer")
02: public class CardDealerRest {
03: //Some Java code follows......
04: .
05: .
06: @GET
07: @Produces(MediaType.APPLICATION_JSON)
08: @Path("/card")
09: public Response getCard(@QueryParam("shoeId") String shoeId) throws IOException, InvalidCardDeckException
10: {
11: //Some Java code for the method follows......
12: .
13: .
14: .
15: return generateResponse(gson.toJson(rc),
16: MediaType.APPLICATION_JSON_TYPE);
17: }
18: //Some more Java code follows......
19: .
20 .
21: //end of class
22: }
CardDealerRestクラスの宣言の上の行01にある、Javaアノテーション@Pathの使用方法に着目してください。@Pathは、URLセグメントをクラスにマッピングし、次にそのクラス内のメソッドにマッピングするJerseyアノテーションです。この例では、行01の@Pathにより、/card-dealerがCardDealerRestクラスにマッピングされます。従って、/card-dealerというURLベースを持つHTTPリクエストはすべて、JerseyのおかげでJavaクラスCardDealerRestのインスタンスに引き渡されることになります。
行08では、@PathによってURLの後ろの部分/cardを、getCard()というメソッドにマッピングしています。このように、Jerseyを使用することにより、RESTfulなHTTPリクエストを取り出し、Javaクラスのメソッドにバインドして、サーバ側の動作を簡素化できます。
これが、JerseyがURLをコードにマッピングする仕組みです。web.xml内では、WebサーバがHTTPリクエストをJerseyサーブレットに引き渡すエントリポイントとして、URLベースを定義します。そしてJerseyの@Pathアノテーションを使用して、URLの残りの部分をどのようにマッピングするかを定義します。まずはクラス(Jerseyの用語ではリソースクラス)にマッピングし、次にクラス内のメソッドにマッピングします。図2は、この概念を示したものです。
他にも、リソースのメソッドが受けつけるMIMEタイプを宣言したり、HTTPリクエストのMETHODをリソースクラスの特定のメソッドにバインドしたり、HTTPレスポンスに設定して返すMIMEタイプを定義したりするためのJerseyアノテーションがあります。
表1に、Sunのドキュメントから抜粋した、基本的なJerseyアノテーションの説明を示します。
| アノテーション | 説明 |
| @Path | @Pathアノテーションの値は、/helloworldのように、Javaクラスがホスティングされる場所を示す相対URIパスです。URIに変数を埋め込み、URIパステンプレートを作成することもできます。たとえば、ユーザ名を入力してもらい、/helloworld/{username}のように、それをURIにおける変数としてアプリケーションに引き渡すことができます。 |
| @GET | @GETアノテーションはリクエストメソッド指定子で、同じ名前のHTTPメソッドに対応します。このアノテーションが付与されたJavaメソッドは、HTTP GETリクエストを処理します。リソースの動作は、リソースがレスポンスを返すHTTPメソッドによって決まります。 |
| @POST | @POSTアノテーションはリクエストメソッド指定子で、同じ名前のHTTPメソッドに対応します。このアノテーションが付与されたJavaメソッドは、HTTP POSTリクエストを処理します。リソースの動作は、リソースがレスポンスを返すHTTPメソッドによって決まります。 |
| @PUT | @PUTアノテーションはリクエストメソッド指定子で、同じ名前のHTTPメソッドに対応します。このアノテーションが付与されたJavaメソッドは、HTTP PUTリクエストを処理します。リソースの動作は、リソースがレスポンスを返すHTTPメソッドによって決まります。 |
| @DELETE | @DELETEアノテーションはリクエストメソッド指定子で、同じ名前のHTTPメソッドに対応します。このアノテーションが付与されたJavaメソッドは、HTTP DELETEリクエストを処理します。リソースの動作は、リソースがレスポンスを返すHTTPメソッドによって決まります。 |
| @HEAD | @HEADアノテーションはリクエストメソッド指定子で、同じ名前のHTTPメソッドに対応します。このアノテーションが付与されたJavaメソッドは、HTTP HEADリクエストを処理します。リソースの動作は、リソースがレスポンスを返すHTTPメソッドによって決まります。 |
| @PathParam | @PathParamアノテーションは、リソースクラスで使用するために抽出することのできるパラメータの1つです。URIパスパラメータは、リクエストされたURIから抽出されます。パラメータ名は、クラスレベルの@Pathアノテーションで指定されたURIパステンプレートの変数名に対応します。 |
| @QueryParam | @QueryParamアノテーションは、リソースクラスで使用するために抽出することのできるパラメータの1つです。クエリパラメータは、リクエストされたURIのクエリパラメータから抽出されます。 |
| @Consumes | @Consumesアノテーションは、リソースが処理することのできる、クライアントから送信されたMIMEメディアタイプを指定するために使用します。 |
| @Produces | @Producesアノテーションは、"text/plain"など、リソースが生成してクライアントに返すことのできるMIMEメディアタイプを指定するために使用します。 |
| @Provider | @Providerアノテーションは、MessageBodyReaderやMessageBodyWriterなど、JAX-RSランタイムに関連するものすべてに使用します。HTTPリクエストでは、MessageBodyReaderによってHTTPリクエストのエンティティボディをメソッドのパラメータにマッピングします。レスポンス側では、MessageBodyWriterによって戻り値をHTTPレスポンスのエンティティボディにマッピングします。アプリケーションにおいて、HTTPヘッダや別のステータスコードなど、その他のメタデータを引き渡す必要がある場合には、メソッドにおいて、Response.ResponseBuilderによってエンティティをラッピングするResponseを作成し、それを返すことができます。 |
Jerseyアノテーションに対するJavadocについては、ここを参照ください。

