それでは、従業員データを対象としたCRUD操作を提供するリソースクラスを作ってみましょう。このリソースクラスは、以下のように、IDと名前、年齢を持ちます。
public class Employee { private long id; private String name; private int age; // コンストラクタ、アクセッサは省略 }
従業員データを操作するためのURIとHTTPメソッドは以下のように定義します。
従業員の操作 | メソッド | URI | レスポンスの表現形式 |
---|---|---|---|
検索 | GET | /crudsample/employees?name={name} | JSON、XML |
取得 | GET | /crudsample/employees/{ID} | JSON、XML |
登録 | POST | /crudsample/employees | JSON、XML |
更新 | PUT | /crudsample/employees/{ID} | なし |
削除 | DELETE | /crudsample/employees/{ID} | なし |
このようにRESTでは、操作内容とHTTPメソッドを一致させます。上記の取得・更新・削除のように、同一のURIでもHTTPメソッドを変えることによって異なる操作を設定できます。
JAX-RSで上記のリソースに対応するEmployeeResourceクラスを作成します。少々長くなりますので、ソースコードを分割しながら紹介します(リスト2-1〜3)。
まずはクラス宣言とフィールド宣言です。
@Path("crudsample/employees") //【1】このリソースの起点のURIを指定 @RequestScoped //【2】CDIと統合 public class EmployeeResource { //【3】ビジネスロジックを注入 @Inject private EmployeeService service;
ポイントを解説します。
【1】では、@Pathアノテーションによりリソース全体で共通のURIを定義しています。前述の表では、「/crudsample/employees」というURIがどの操作でも共通になっています。そのようなURIはリソースクラスの@Pathアノテーションに設定することで、一元化して定義できます。
【2】では、リソースクラスをCDIのBeanとして宣言しています。Java EE環境では、JAX-RSとCDIを統合できるため、インジェクションが可能となります。
【3】ではビジネスロジックを実行するEmployeeServiceというBeanをインジェクションしています。【2】でリソースクラスをCDIのBeanとしたことにより、他のCDI Beanをインジェクションできます。
続いて、HTTPメソッドのGETに対応するリソースクラスのメソッドを説明します。まずは、名前を指定して従業員を検索するsearchメソッドです。このメソッドは次のURIに対応付けています。
GET /curdsample/employees?name=hoge HTTP/1.1
@GET // 【4】GET crudsample/employees?name=<name> に対応 @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) //【5】XMLかJSONを生成 public List<Employee> search(@QueryParam("name") String name) { return service.findByName(name); }
【4】では、@GETアノテーションを指定してsearchメソッドを上記のGETリクエストに対応付けています。URIに含まれるクエリストリングnameの値(上のURIの例ではhoge)は、searchメソッドの引数nameに割り当てられます。これは引数に、@QueryStringアノテーションを指定しているためです。JAX-RSではHTTPリクエストのさまざまな値を取得するためのアノテーションを多数用意しています。
【5】では、@Producesアノテーションにより、searchメソッドの戻り値のList
実行時にどちらのデータ形式を選択するかは、クライアントからの指定に従います。クライアントのHTTPリクエストに、受け入れ可能な表現形式を示すAcceptヘッダがある場合、その形式で返却します。
例えば、「Accept : application/json」ヘッダを付与して実行すると、以下のようなJSON形式のデータを返却します。
一方、「Accept: Application/xml」ヘッダを付与して、リクエストを発行すると、以下のようなXML形式のデータを返却します。
上記以外のAcceptヘッダを指定すると、エラーとなります。
このように、アノテーションの設定のみでさまざまな表現形式に対応できるのがJAX-RSの特徴の1つです。
次に、従業員をIDで検索するメソッドを見てみましょう。
@GET @Path("{id}") // 【6】crudsample/employees/{id} に対応 @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public Employee get(@PathParam("id") long id) { return service.findById(id); }
【6】では 従業員1人分の情報を取得するためのGETリクエストのURIを定義しています。getメソッドに設定した「@Path(“{id}”)」というアノテーションは、リソースクラスに付与した@Pathアノテーションからの相対パスとして解釈されるため、「/crudsample/employees /{id}」というURIに対応します。
{id}のような{ }で囲まれた文字列は、URIの中の可変文字列を意味しています。IDを指定するようなリソースに対しては、URI中にIDを埋め込む方式がRESTでは一般的です。
URIの可変文字列をメソッドの中で使用するには、メソッドの引数に@PathParamアノテーションを指定します。
最後は、HTTPメソッドのPOST、PUT、DELETEに対応するメソッドです。
@POST // 【7】POST crudsample/employees に対応 @Consumes(MediaType.APPLICATION_FORM_URLENCODED) //【8】HTTPフォームを受け取る @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public Employee newEmployee(@FormParam("name")String name, @FormParam("age")int age) { return service.save(name, age); } @PUT // 【9】PUT curdsample/employees/{id} に対応 @Path("{id}") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public void updateEmployee(@PathParam("id") long id, @FormParam("name")String name, @FormParam("age")int age) { service.update(new Employee(id, name, age)); } @DELETE // 【10】DELETE crudsample/employees/{id} に対応 @Path("{id}") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public void deleteEmployee(@PathParam("id") long id) { service.delete(id); } }
【7】では、@POSTアノテーションを指定して、POSTに対応するメソッドであることを宣言しています。このnewEmployeeメソッドでは、新しい従業員IDを発行するため、従業員データを戻り値として返すことで、発行したIDをクライアントに通知しています。
【8】では、@Consumesアノテーションによって、newEmployeeメソッドが受け取ることのできるデータ形式を指定しています。ここでは、通常のHTMLのFORMを受け取ると定義しています。FORMの各属性の値は、メソッドの引数の@FormParamアノテーションによって取得できます。
【9】では、@PUTアノテーションによって、PUTメソッドによる更新操作を定義しています。PUTでは、従業員IDを指定することを前提にするため、idをURIに含めるように指定します。このメソッドでは返却するデータがないため、戻り値をvoidにしています。その場合、クライアントにはHTTPレスポンスコード「204」(No Content)のみが返却されます。
【10】では、@DELETEアノテーションによって、DELETEメソッドによる従業員削除メソッドを定義しています。
以上が、JAX-RSのリソースクラスの基本的な作成方法となります。アノテーションによって、リクエストパラメータの解析や、レスポンスデータの作成といった定型的なコードが削除され、とてもシンプルなコードになります。
また、今回は割愛しましたが、リクエストパラメータからCookie やHTTPヘッダなどを取得するためのアノテーションも用意しています。
続いて次ページでは、JAX-RSの応用的な使い方を幾つか紹介します。
Copyright © ITmedia, Inc. All Rights Reserved.