ヘッダーをスキップ
Oracle Fusion Middleware Oracle WebLogic Server RESTful Webサービスの開発
12cリリース1 (12.1.1)
B65960-02
  目次へ移動
目次

前
 
次
 

2 RESTful Webサービスの開発

この章では、Java API for RESTful Web Services (JAX-RS)を使用して、Representational State Transfer (REST)アーキテクチャ・スタイルに従ったWebLogic Webサービスを開発する方法について説明します。

この章の内容は以下のとおりです。

RESTful Webサービスの開発について

JAX-RSは、アノテーションを使用して、RESTful Webサービスの開発を簡略化するJavaプログラミング言語APIです。JAX-RSアノテーションは実行時アノテーションです。JAX-RSリソース・クラスを含むJava EEアプリケーション・アーカイブをWebLogic Serverにデプロイする場合(第3章「RESTful Webサービスのパッケージ化とデプロイ」を参照)、ランタイムはリソースを構成し、ヘルパー・クラスおよびアーティファクトを生成し、リソースをクライアントに公開します。

以下の項で、RESTful Webサービスの開発についての詳細を説明します。

RESTful Webサービスを開発するタスクの概要

表2-1に、JAX-RSアノテーションを使用してRESTful Webサービスを開発するのに必要なタスクのサブセットの概要を示します。高度なタスクの詳細は、「高度なRESTful Webサービス・タスク」を参照してください。

以下で説明する開発タスクに加えて、javax.ws.rs.core.Applicationを拡張するクラスを作成して、RESTful Webサービス・アプリケーション・デプロイメントのコンポーネントを定義し、追加のメタデータを提供できる場合があります。詳細は、「アプリケーション・サブクラスとのパッケージ化」を参照してください。

表2-1 RESTful Webサービスを開発するタスクの概要

タスク 詳細についての参照先

ルート・リソース・クラスを定義します。

ルート・リソース・クラスの定義


@Pathアノテーションを使用して、ルート・リソースの相対URIとそのメソッドを定義します。

変数を使用して@Pathアノテーションを定義する場合、@PathParamアノテーションを使用して、値をそれに割り当てることができます。

ルート・リソースおよびサブリソースの相対URIの定義


@GET@POST@PUTまたは@DELETEを使用して、受信HTTPリクエストをJavaメソッドにマッピングして、それぞれリソースを取得、作成、更新または削除します。

受信HTTPリクエストのJavaメソッドへのマッピング


必要に応じて、リクエストおよびレスポンス・メッセージをカスタマイズして、リソースが生成および消費できるMIMEメディア・タイプを指定します。

リクエストおよびレスポンスのメッセージ・タイプのカスタマイズ


リクエストから情報を抽出します。

リクエストからの情報の抽出


レスポンス・コードをカスタマイズする、または追加メタデータを含めるためのカスタム・レスポンス・メッセージを構築します。

カスタム・レスポンス・メッセージの構築


アプリケーション・デプロイメント・コンテキストまたは個別リクエストのコンテキストに関する情報にアクセスします。

アプリケーション・コンテキストのアクセス


新規のリソースURIを構築、または既存のリソースURIを拡張します。

URIの構築


GETリクエストの処理前に1つ以上の前条件を評価することで、潜在的に帯域幅を縮小し、サーバー・パフォーマンスを改善します。

条件付きGETの使用


WADLにアクセスします。

WADLのアクセス


RESTful Webサービスを保護します。

第5章「RESTful Webサービスの保護」



RESTful Webサービスの例

例2-1に、RESTful Webサービスの簡単な例を示します。この例では:

追加の例を「RESTful Webサービスの詳細」に示します。

例2-1 簡単なRESTful Webサービスの例

package samples.helloworld;
 
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
 
// Specifies the path to the RESTful service
@Path("/helloworld")
public class helloWorld {
 
   // Specifies that the method processes HTTP GET requests 
   @GET
   @Produces("text/plain")
   public String sayHello() {
      return "Hello World!";
   }
}

ルート・リソース・クラスの定義

ルート・リソース・クラスは、次の条件の1つまたは両方がtrueであるPlain Old Java Object (POJO)です。

ルート・リソースおよびサブリソースの相対URIの定義

リソースのクラス・レベルでjavax.ws.rs.Pathアノテーションを追加し、RESTful Webサービスの相対URIを定義します。このようなクラスはルート・リソース・クラスと呼ばれます。特定の機能をグループ化するためのサブリソースを定義するため、@Pathもルート・リソース・クラスのメソッドに追加できます。

次の項では、ルート・リソースおよびサブリソースの相対URIの定義方法について説明します。

リソース・クラスの相対URI (@Path)の定義方法

@Pathアノテーションはリソースの相対URIを定義し、定数または変数(URIパス・テンプレートとして参照される)として定義できます。@Pathアノテーションをクラスまたはメソッド・レベルで追加できます。

URIを定数値として定義するには、定数値を@Pathアノテーションに渡します。先頭と末尾のスラッシュ(/)はオプションです。

例2-2では、リソース・クラスの相対URIが定数値/helloworldとして定義されます。

例2-2 相対URIの定数値としての定義

package samples.helloworld;
import javax.ws.rs.Path;
...
// Specifies the path to the RESTful service
@Path("/helloworld")
public class helloWorld {. . .}

URIをURIパス・テンプレートとして定義するには、1つまたは複数の変数値を@Pathアノテーションに中カッコで囲んで渡します。すると、javax.ws.rs.PathParamアノテーションを使用して、@Pathアノテーションで定義されたリクエストURIから変数情報を抽出でき、メソッド・パラメータの値を初期化できます(変数情報をリクエストURI (@PathParam)から抽出する方法を参照)。

例2-3では、リソース・クラスの相対URIが、中かっこで囲まれた変数を使用して定義されます。たとえば、/users/{username}です。

例2-3 相対URIの変数値としての定義

package samples.helloworld;
 
import javax.ws.rs.Path;
...
// Specifies the path to the RESTful service
@Path("/users/{username}")
public class helloWorld {. . .}
}

変数をさらにカスタマイズするには、デフォルトの正規表現の"[^/]+?"を、変数定義の一部として必要な正規表現を指定することでオーバーライドできます。例:

@Path("users/{username: [a-zA-Z][a-zA-Z_0-9]}")

この例では、username変数は、1つの大文字または小文字で始まり、ゼロまたはそれ以上の英数字またはアンダースコア文字が続くユーザー名にのみ一致します。ユーザー名が要件に一致しない場合、404 (Not Found)レスポンスがクライアントに送信されます。

@Pathアノテーションの詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/Path.htmlを参照してください。

サブリソースの相対URI (@Path)の定義方法

javax.ws.rs.Pathアノテーションをリソースのメソッド・パラメータに追加して、サブリソースを定義します。サブリソースによってユーザーは、リソースに対する特定の機能をグループ化できます。

例2-3で、URIのリクエスト・パスがusers/listの場合は、getUserListサブリソース・メソッドが照合され、ユーザーのリストが返されます。

例2-4 サブリソースの定義

package samples.helloworld;
 
import javax.ws.rs.GET;
import javax.ws.rs.Path;
 
// Specifies the path to the RESTful service
@Path("/users")
public class UserResource {
. . .
    @GET
   @Path("/list")
    public String getUserList() {
      ...
   }
}

実行時の処理: 基底URIの構成方法

基底URIは次のように構成されます。

http://myHostName/contextPath/servletURI/resourceURI
  • myHostName— Web サーバーにマップされるDNS名。これを、WebLogic Serverを実行しているマシン名とリクエストのリスニングに使用するポートを指定するhost:portで置き換えることができます。

  • contextPath—スタンドアロンWebアプリケーションの名前。Webアプリケーション名はEARファイル内のMETA-INF/application.xmlデプロイメント記述子またはWARファイルのweblogic.xmlデプロイメント記述子に指定されます。指定されない場合、デフォルトはWARファイルから.war拡張子を取り去った名前です。詳細は、『Oracle WebLogic Server Webアプリケーション、サーブレット、JSPの開発』のcontext-rootに関する項を参照してください。

  • servletURI—サーブレットのコンテキスト・パスの基底URIです。このパスは表3-1で定義されているパッケージ化オプションの一部として構成されます。特に、次を実行して、サーブレットのコンテキスト・パスを定義できます。

    • web.xmlデプロイメント記述子を更新して、サーブレット・マッピングを定義します。

    • javax.ws.rs.ApplicationPathアノテーションをjavax.ws.rs.core.Applicationを拡張するクラスに追加します(定義されている場合)。

    サーブレットのコンテキスト・パスが上記のオプションの両方を使用して構成されている場合、サーブレット・マッピングが優先されます。上記のオプションのいずれかを使用して、構成内にサーブレットのコンテキスト・パスが構成されない場合、WebLogic ServerはデフォルトのRESTful Webサービス・アプリケーションのコンテキスト・パスresourcesを提供します。詳細は、「RESTful Webサービスのパッケージ化とデプロイメントについて」を参照してください。

  • resourceURI—リソースまたはサブリソースに対して指定された@Path値。

例2-2では、WARファイルに対するコンテキスト・パスがrestとして定義されていて、サーブレットのデフォルトURI (resources)が有効な場合、実行時のリソースにアクセスする基底URIはhttp://myServer:7001/rest/resources/helloworldです。

例2-3では、実行時に、基底URIは変数に対して指定された値に基づき構成されます。たとえば、ユーザーがユーザー名としてjohnsmithを入力した場合、リソースにアクセスする基底URIはhttp://myServer:7001/rest/resources/users/johnsmithです。

受信HTTPリクエストのJavaメソッドへのマッピング

JAX-RSはJavaアノテーションを使用して受信HTTPリクエストをJavaメソッドにマッピングします。表2-2に、同じような名前が付けられたHTTPメソッドにマッピングする、使用可能なアノテーションを示します。

表2-2 HTTPリクエストのJavaメソッドへのマッピング用javax.ws.rsアノテーション

アノテーション 説明 多重呼出し不変

@GET

URIにより識別されるリソースの表現をクライアントに送信します。フォーマットは、HTML、プレーン・テキスト、JPEGなどです。「リソースの表現の送信方法(@GET)」を参照してください。

@PUT

URIで識別された特定のリソースの表現を作成または更新します。「リソースの表現の作成または更新方法(@PUT)」を参照してください。

@DELETE

URIで識別されたリソースの表現を削除します。「リソースの表現の削除方法(@DELETE)」を参照してください。

@POST

URIで識別された特定のリソースの表現でのアクションを作成、更新、または実行します。「リソースの表現でのアクションの作成、更新、または実行方法(@POST)」を参照してください。

@HEAD

レスポンス・ヘッダーのみを戻し、実際のリソースは戻しません(つまり、メッセージ本文はありません)。これは、実際にダウンロードせずにリソースの特性を確認して、バンド幅を節約するのに役に立ちます。詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/HEAD.htmlを参照してください。

HEADメソッドは明示的に実装されないと、自動的に実装されます。この場合、ランタイムは実装されたGETメソッド(存在する場合)を呼び出し、レスポンス・エンティティ(設定されている場合)を無視します。

@OPTIONS

URIで識別された特定のリソースのリクエスト/レスポンス・チェーンで使用可能な通信オプションを戻します。Allowレスポンス・ヘッダーはリソースでサポートされるHTTPメソッドのセットに設定され、WADLファイルが戻されます。詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/OPTIONS.htmlを参照してください。

OPTIONSメソッドは明示的に実装されないと、自動的に実装されます。このケースでは、Allowレスポンス・ヘッダーはリソースでサポートされるHTTPメソッドのセットに設定され、リソースを記述するWADLが戻されます。

@HttpMethod

アノテーションの付けられたメソッドを使用してHTTPリクエストを処理する必要があることを示します。詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/HttpMethod.htmlを参照してください。

該当せず


次の項では、HTTPリクエストのJavaメソッドへのマッピングに使用されるJAX-RSアノテーションの詳細について説明します。

Jerseyブックマーク・サンプルについて

次の項に示す例は、Jersey 1.9 JAX-RS RIとともに提供されるブックマーク・サンプルからの抜粋です。ブックマーク・サンプルは、ユーザーやブラウザが設定したブックマークを保持するWebアプリケーションを提供します。

サンプル内のリソース・クラス、関連URIパス、各クラスにより実証されるHTTPメソッドについて、次の表にまとめます。

表2-3 Jerseyブックマーク・サンプルについて

リソース・クラス URIパス 実証されるHTTPメソッド

UsersResource

/users/

GET

UserResource

/users/{userid}

GET、PUT、DELETE

BookmarksResource

/users/{userid}/bookmarks

GET、POST

BookmarkResource

/users/{userid}/bookmarks/{bmid}

GET、PUT、DELETE


ブックマーク・サンプルおよびその他のJerseyサンプルは、次のいずれかの方法でアクセスできます。

リソースの表現の送信方法(@GET)

javax.ws.rs.GETアノテーションは、URIにより識別されるリソースの表現をクライアントに送信します。レスポンスのエンティティ本文で戻される形式または表現は、HTML、プレーン・テキスト、JPEGなどです。@GETアノテーションの詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/GET.htmlを参照してください。

例2-5では、Jerseyブックマーク・サンプルのBookmarksResourceクラスからの、アノテーションが付けられたJavaメソッドgetBookmarkAsJsonArrayが、HTTP GETリクエストを処理します。Jerseyブックマーク・サンプルの詳細は、「Jerseyブックマーク・サンプルについて」を参照してください。

例2-5 HTTP GETリクエストのJavaメソッドへのマッピング(BookmarksResourceクラス)

import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;
...
public class BookmarksResource {
...
    @Path("{bmid: .+}")
    public BookmarkResource getBookmark(@PathParam("bmid") String bmid) {
        return new BookmarkResource(uriInfo, em, 
                userResource.getUserEntity(), bmid);
    }
    @GET
    @Produces("application/json")
    public JSONArray getBookmarksAsJsonArray() {
        JSONArray uriArray = new JSONArray();
        for (BookmarkEntity bookmarkEntity : getBookmarks()) {
            UriBuilder ub = uriInfo.getAbsolutePathBuilder();
            URI bookmarkUri = ub.
                    path(bookmarkEntity.getBookmarkEntityPK().getBmid()).
                    build();
            uriArray.put(bookmarkUri.toASCIIString());
        }
        return uriArray;
    }
...
}

例2-6では、Jerseyブックマーク・サンプルのBookmarkResourceクラスからの、アノテーションが付けられたJavaメソッドgetBookmarkが、HTTP GETリクエストを処理します。この例では、戻されたJSONオブジェクトの処理方法を示します。Jerseyブックマーク・サンプルの詳細は、「Jerseyブックマーク・サンプルについて」を参照してください。

例2-6 HTTP GETリクエストのJavaメソッドへのマッピング(BookmarkResourceクラス)

import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;
...
public class BookmarkResource {
...
    @GET
    @Produces("application/json")
    public JSONObject getBookmark() {
        return asJson();
    }
...
    public JSONObject asJson() {
        try {
            return new JSONObject()
            .put("userid", bookmarkEntity.getBookmarkEntityPK().getUserid())
            .put("sdesc", bookmarkEntity.getSdesc())
            .put("ldesc", bookmarkEntity.getLdesc())
            .put("uri", bookmarkEntity.getUri());
        } catch (JSONException je){
            return null;
        }
    }
}

リソースの表現の作成または更新方法(@PUT)

javax.ws.rs.PUTアノテーションは、URIで識別された特定のリソースの表現を作成または更新します。@PUTアノテーションの詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/PUT.htmlを参照してください。

例2-7では、Jerseyブックマーク・サンプルのBookmarkResourceクラスからの、アノテーションが付けられたJavaメソッドputBookmarkが、HTTP PUTリクエストを処理し、指定したブックマークを更新します。Jerseyブックマーク・サンプルの詳細は、「Jerseyブックマーク・サンプルについて」を参照してください。

例2-7 HTTP PUTリクエストのJavaメソッドへのマッピング

import javax.ws.rs.PUT;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;
...
public class BookmarkResource {
...
    @PUT
    @Consumes("application/json")
    public void putBookmark(JSONObject jsonEntity) throws JSONException {
        bookmarkEntity.setLdesc(jsonEntity.getString("ldesc"));
        bookmarkEntity.setSdesc(jsonEntity.getString("sdesc"));
        bookmarkEntity.setUpdated(new Date());
        
        TransactionManager.manage(new Transactional(em) { public void transact() {
            em.merge(bookmarkEntity);
        }});
    }    
 
}

リソースの表現の削除方法(@DELETE)

javax.ws.rs.DELETEアノテーションは、URIで識別された特定のリソースの表現を削除します。レスポンスのエンティティ本文ではステータス・メッセージが返されるか、または空の可能性があります。@DELETEアノテーションの詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/DELETE.htmlを参照してください。

例2-8では、Jerseyブックマーク・サンプルのBookmarkResourceクラスからの、アノテーションが付けられたJavaメソッドdeleteBookmarkが、HTTP DELETEリクエストを処理し、指定したブックマークを削除します。Jerseyブックマーク・サンプルの詳細は、「Jerseyブックマーク・サンプルについて」を参照してください。

例2-8 HTTP DELETEリクエストのJavaメソッドへのマッピング

import javax.ws.rs.DELETE;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;
...
public class BookmarkResource {
...
    @DELETE
    public void deleteBookmark() {
        TransactionManager.manage(new Transactional(em) { public void transact() {
            UserEntity userEntity = bookmarkEntity.getUserEntity();
            userEntity.getBookmarkEntityCollection().remove(bookmarkEntity);
            em.merge(userEntity);
            em.remove(bookmarkEntity);
        }});
    }    
}

リソースの表現でのアクションの作成、更新、または実行方法(@POST)

javax.ws.rs.POSTアノテーションは、URIで識別された特定のリソースの表現でのアクションを作成、更新、または実行します。@POSTアノテーションの詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/POST.htmlを参照してください。

例2-9では、Jerseyブックマーク・サンプルのBookmarksResourceクラスからの、アノテーションが付けられたJavaメソッドpostFormが、HTTP POSTリクエストを処理し、指定した情報を更新します。Jerseyブックマーク・サンプルの詳細は、「Jerseyブックマーク・サンプルについて」を参照してください。

例2-9 HTTP POSTリクエストのJavaメソッドへのマッピング

import javax.ws.rs.POST;
import javax.ws.rs.Produces;
...
public class BookmarksResource {
...
    @POST
    @Consumes("application/json")
    public Response postForm(JSONObject bookmark) throws JSONException {
        final BookmarkEntity bookmarkEntity = new BookmarkEntity(
                getBookmarkId(bookmark.getString("uri")), 
                userResource.getUserEntity().getUserid());
 
        bookmarkEntity.setUri(bookmark.getString("uri"));
        bookmarkEntity.setUpdated(new Date());
        bookmarkEntity.setSdesc(bookmark.getString("sdesc"));
        bookmarkEntity.setLdesc(bookmark.getString("ldesc"));
        userResource.getUserEntity().getBookmarkEntityCollection().add(bookmarkEntity);
 
        TransactionManager.manage(new Transactional(em) { public void transact() {
            em.merge(userResource.getUserEntity());
        }});
 
        URI bookmarkUri = uriInfo.getAbsolutePathBuilder().
                path(bookmarkEntity.getBookmarkEntityPK().getBmid()).
                build();
        return Response.created(bookmarkUri).build();
    }
}

リクエストおよびレスポンスのメッセージ・タイプのカスタマイズ

リソースのクラス・レベルでjavax.ws.rs.Producesまたはjavax.ws.rs.Consumesアノテーションを追加し、リクエストおよびレスポンス・メッセージ・タイプをカスタマイズします。次の項を参照してください。

リクエストのメッセージ・タイプのカスタマイズ方法(@Consumes)

javax.ws.rs.Consumesアノテーションにより、クライアントから送信され、リソースが消費できる表現のMIMEメディア・タイプを指定できます。@Consumesアノテーションはクラスとメソッド・レベルの両方に指定でき、複数のメディア・タイプを同じ@Consumes宣言で宣言できます。

指定されたMIMEメディア・タイプを消費できるメソッドがリソース内にない場合、ランタイムはHTTP 「415 - サポートされていないメディア・タイプ」エラーを返します。

@Consumesアノテーションの詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/Consumes.htmlを参照してください。

例2-11では、JavaクラスhelloWorldに定義された@Consumesアノテーションは、クラスがtext/plain MIMEメディア・タイプを使用してメッセージを作成することを指定します。

例2-10 @Consumesを使用したリクエストのメッセージ・タイプのカスタマイズ

package samples.consumes;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
...
@Path("/helloworld")
public class helloWorld {
...
    @POST
    @Consumes("text/plain")
    public void postMessage(String message) {
       // Store the message
   }
}

レスポンスのメッセージ・タイプのカスタマイズ方法(@Produces)

javax.ws.rs.Producesアノテーションにより、リソースが生成でき、クライアントに戻すことができる、表現のMIMEメディア・タイプを指定できます。@Producesアノテーションはクラスとメソッド・レベルの両方に指定でき、複数のメディア・タイプを同じ@Produces宣言で宣言できます。

指定されたMIMEメディア・タイプを生成できるメソッドがリソース内にない場合、ランタイムはHTTP 「406 許可されません」エラーを返します。

@Producesアノテーションの詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/Produces.htmlを参照してください。

例2-11では、JavaクラスSomeResourceに指定された@Producesアノテーションは、クラスがtext/plain MIMEメディア・タイプを使用してメッセージを作成することを指定します。doGetAsPlainTextメソッドのデフォルトは、クラス・レベルで指定されたMIMEメディア・タイプです。doGetAsHtmlメソッドはクラス・レベルの設定をオーバーライドし、メソッドがプレーン・テキストではなくHTMLを生成することを指定します。

例2-11 @Producesを使用したレスポンスのメッセージ・タイプのカスタマイズ

package samples.produces;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;

@Path("/myResource")
@Produces("text/plain")
public class SomeResource {
    @GET
    public String doGetAsPlainText() { ... }

    @GET
    @Produces("text/html")
    public String doGetAsHtml() { ... }
}

実行時の処理: レスポンス・メッセージに対するリソース・メソッドの選択方法

リソース・クラスが複数のMIMEメディア・タイプの生成が可能な場合、選択されたリソース・メソッドは、HTTPリクエストのAcceptヘッダーに宣言された受入れ可能なメディア・タイプに対応します。例2-11では、AcceptヘッダーがAccept: text/htmlの場合、doGetAsPlainTextメソッドが呼び出されます。

複数のMIMEメディア・タイプが@Producesアノテーションに含まれており、両方がクライアントに受入れ可能な場合、指定された最初のメディア・タイプが使用されます。例2-11では、AcceptヘッダーがAccept: application/html, application/textの場合、doGetAsHtmlメソッドが呼び出され、リストの最初に表示されるapplication/html MIMEメディア・タイプが使用されます。

リクエストからの情報の抽出

javax.ws.rsパッケージでは、表2-2に示すとおり、リクエストから情報を抽出し、Javaメソッドにパラメータを注入できるアノテーションのセットを定義します。

表2-4 リクエストから情報を抽出するためのjavax.ws.rsアノテーション

アノテーション 説明

@CookieParam

HTTP Cookie関連ヘッダーから情報を抽出し、メソッド・パラメータの値を初期化します。詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/CookieParam.htmlを参照してください。

@DefaultValue

次に示すアノテーションのいずれかを使用してバインドされるリクエスト・メタデータのデフォルト値を定義します。@CookieParam@FormParam@HeaderParam@MatrixParam@PathParamまたは@QueryParam。詳細は、「DefaultValueの定義方法(@DefaultValue)」を参照してください。

@Encoded

次に示すアノテーションのいずれかを使用してバインドされるパラメータ値とデコードを無効にします。@FormParam@MatrixParam@PathParamまたは@QueryParam。メソッドまたはクラスでこのアノテーションを使用して、メソッドまたはクラス・レベルでパラメータのデコードを無効にします。詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/Encoded.htmlを参照してください。

@FormParam

タイプapplication/x-www-form-urlencodedのHTMLフォームから情報を抽出します。詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/FormParam.htmlを参照してください。

@HeaderParam

HTTPヘッダーから情報を抽出し、メソッド・パラメータの値を初期化します。詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/HeaderParam.htmlを参照してください。

@MatrixParam

URIパス・セグメントから情報を抽出し、メソッド・パラメータの値を初期化します。詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/MatrixParam.htmlを参照してください。

@PathParam

相対URIを変数として定義します(URIパス・テンプレートとして参照)。詳細は、「リクエストURIからの変数情報の抽出方法(@PathParam)」を参照してください。

@QueryParam

リクエストURIの問合せ部分から情報を抽出し、メソッド・パラメータの値を初期化します。詳細は、「リクエスト・パラメータの抽出方法(@QueryParam)」を参照してください。


リクエストURIからの変数情報の抽出方法(@PathParam)

javax.ws.rs.PathParamアノテーションをリソースのメソッド・パラメータに追加し、リクエストURIから変数情報を抽出し、メソッド・パラメータの値を初期化します。@DefaultValueアノテーションを使用して、変数値のデフォルト値を定義できます。「DefaultValueの定義方法(@DefaultValue)」を参照してください。

例2-3では、@PathParamアノテーションが、@PathアノテーションによりURIパスの一部として定義されたusername変数の値をuserNameメソッド・パラメータに割り当てます。

例2-12 リクエストURIからの変数情報の抽出

package samples.helloworld;
 
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.PathParam;
 
// Specifies the path to the RESTful service
@Path("/users")
public class helloWorld {
. . .
    @GET
    @Path("/{username}")
    @Produces("text/xml")
    public String getUser(@PathParam("username") String userName) {
      ...
   }
}

リクエスト・パラメータの抽出方法(@QueryParam)

javax.ws.rs.QueryParamアノテーションをリソースのメソッド・パラメータに追加し、リクエストURIの問合せ部分から情報を抽出し、メソッド・パラメータの値を初期化します。

アノテーションの付けられたメソッド・パラメータの種類は次のとおりです。

  • プリミティブ型(intcharbyteなど)

  • ユーザー定義型

  • 1つの文字列引数を受入れるコンストラクタ

  • 1つの文字列引数を受入れる静的メソッドvalueOfまたはfromString(たとえば、integer.valueOf(String))

  • List<T>Set<T>、またはSortedSet<T>

@QueryParamアノテーションが指定されても、関連する問合せパラメータがリクエストに存在しない場合、そのパラメータ値は、ListSetまたはSortedSetの場合は空のコレクション、プリミティブ型の場合はJava定義のデフォルト、およびその他のすべてのオブジェクト型の場合はNULLに設定されます。または、@DefaultValueアノテーションを使用して、パラメータのデフォルト値を定義できます。「DefaultValueの定義方法(@DefaultValue)」を参照してください。

@QueryParamアノテーションの詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/QueryParam.htmlを参照してください。

例2-13では、step問合せパラメータがリクエストURIの問合せコンポーネントに存在する場合、その値はstepメソッドのパラメータに整数値として割り当てられます。値が整数値として解析できない場合、400 (クライアント・エラー)レスポンスが返ります。step問合せパラメータがリクエストURIの問合せコンポーネント内に存在しない場合、値はNULLに設定されます。

例2-13 リクエスト・パラメータの抽出(@QueryParam)

import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.QueryParam;
...
    @Path("smooth")
    @GET
    public Response smooth(@QueryParam("step") int step) 
    { ... }
}

DefaultValueの定義方法(@DefaultValue)

javax.ws.rs.DefaultValueアノテーションを追加して、次に示すアノテーションのいずれかを使用してバインドされるリクエスト・メタデータのデフォルト値を定義します。@CookieParam@FormParam@HeaderParam@MatrixParam@PathParamまたは@QueryParam@DefaultValueアノテーションの詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/DefaultValue.htmlを参照してください。

例2-14では、step問合せパラメータがリクエストURIの問合せコンポーネントに存在しない場合、デフォルトの値2がstepパラメータに割り当てられます。

例2-14 DefaultValueの定義(@DefaultValue)

import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.QueryParam;
...
    @Path("smooth")
    @GET
    public Response smooth(@DefaultValue("2") @QueryParam("step") int step) 
    { ... }
}

カスタム・レスポンス・メッセージの構築

デフォルトでは、正常なGETリクエストには200 OK、正常なPUTリクエストには201 CREATEDなどの、HTTP仕様で定義されたデフォルト・レスポンス・コードを使用して、JAX-RSはHTTPリクエストに応答します。

場合によっては、返されたレスポンス・コードをカスタマイズする、または追加メタデータ情報をレスポンスに含めることがあります。たとえば、新しく作成されたリソースにURIを指定するためのLocationヘッダーを含めるような場合です。返されたレスポンス・メッセージは、javax.ws.rs.core.Responseクラスを使用して変更できます。

アプリケーションではResponseクラスを直接拡張するか、表2-5で定義された静的Responseメソッドの1つを使用することで、javax.ws.rs.core.Response.ResponseBuilderインスタンスを作成してResponseインスタンスを構築できます。Responseメソッドの詳細は、Javadoc (http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/core/Response.html)を参照してください。

表2-5 ResponseBuilderクラスを使用したレスポンス・インスタンスの作成

メソッド 説明

created()

新しいResponseBuilderインスタンスを作成して、Locationヘッダーを指定された値に設定します。

fromResponse()

新しいResponseBuilderインスタンスを作成して、既存のレスポンスをコピーします。

noContent()

新しいResponseBuilderインスタンスを作成して、空のレスポンスを定義します。

notAcceptable()

新しいResponseBuilderインスタンスを作成して、許可できないレスポンスを定義します。

notModified()

新しいResponseBuilderインスタンスを作成して、変更されていないステータスを返します。

ok()

新しいResponseBuilderインスタンスを作成して、OKステータスを返します。

seeOther()

リダイレクトのための新しいResponseBuilderインスタンスを作成します。

serverError()

新しいResponseBuilderインスタンスを作成して、サーバー・エラー・ステータスを返します。

status()

新しいResponseBuilderインスタンスを作成して、指定されたステータスを返します。

temporaryRedirect()

一時的なリダイレクトのための新しいResponseBuilderインスタンスを作成します。


ResponseBuilderインスタンスを作成した後は、表2-6で定義されたメソッドを呼び出してカスタム・リソースを定義できます。次に、build()メソッドを呼び出して最終的なResponseインスタンスを作成します。ResponseBuilderクラスとそのメソッドの詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/core/Response.ResponseBuilder.htmlを参照してください。

表2-6 カスタム・レスポンスを構築するためのResponseBuilderメソッド

メソッド 説明

build()

現在のResponseBuilderインスタンスからレスポンス・インスタンスを作成します。

cacheControl()

キャッシュ・コントロールを設定します。

clone()

ResponseBuilderのコピーを作成してその状態を保存します。

contentLocation()

コンテンツの場所を設定します。

cookie()

レスポンスにCookieを追加します。

entity()

エンティティを定義します。

expires()

有効期限を設定します。

header()

レスポンスにヘッダーを追加します。

language()

言語を設定します。

lastModified()

最終変更日を設定します。

location()

場所を設定します。

newInstance()

新しいResponseBuilderインスタンスを作成します。

status()

ステータスを設定します。

tag()

エンティティ・タグを設定します。

type()

レスポンス・メディア・タイプを設定します。

variant()

表現メタデータを設定します。

variants()

使用可能なバリアントの一覧を示すVaryヘッダーを追加します。


例2-15は、ResponseBuilderを使用したResponseインスタンスの構築方法を示しています。この例では、200 OKの標準ステータス・コードが返され、レスポンスのメディア・タイプがtext/htmlに設定されます。build()メソッドの呼出しによって最終的なResponseインスタンスが作成されます。

例2-15 カスタム・レスポンスの構築

import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.ResponseBuilder;
...
@Path("/content")
public class getDocs {
   @GET
   @Path("{id}")
   public Response getHTMLDoc(@PathParm("id") int docId)
   {
      Document document = ...;
      ResponseBuilder response = Response.ok(document);
      response.type("text/html");
      return response.build();
   }
}

汎用型を使用してHTTPレスポンスを構築する場合、実行時に型のイレイジャを回避するために、汎用型を保持するjavax.ws.rs.core.GenericEntityオブジェクトを作成する必要があります。詳細は、http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/core/GenericEntity.htmlを参照してください。

例2-16に、汎用型を保持するGenericEntityを使用する、HTTPレスポンスの構築方法の例を示します。

例2-16 汎用型を使用したカスタム・レスポンスの構築

import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.ResponseBuilder;
javax.ws.rs.core.GenericEntity;
...
@Path("/content")
public class getDocs {
   @GET
   @Path("{id}")
   public Response getHTMLDoc(@PathParm("id") int docId)
   {
      Document document = ...;
      List<String> list = new ArrayList<String>();
      GenericEntity<List<String>> entity = new GenericEntity<List<String>>(list) {};
      ...
      ResponseBuilder response = Response.ok(document);
      response.entity(entity);
      return response.build();
   }
}

アプリケーション・コンテキストのアクセス

javax.ws.rs.core.Contextアノテーションを使用すると、アプリケーション・デプロイメント・コンテキストと個別リクエストのコンテキストに関する情報にアクセスできます。表2-7@Contextアノテーションを使用してアクセスできるコンテキスト・タイプの概要を示します。詳細は、Javadoc (http://docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/core/Context.html)を参照してください。

表2-7 コンテキスト・タイプ

コンテキスト・タイプ名 目的

HttpHeaders

HTTPヘッダー情報にアクセスします。

Providers

一連の検索基準を基に、プロバイダ・インスタンスを参照します。

Request

最も一致する表現バリアントを判別し、リソースの現在の状態が定義済の前条件に一致するかどうかを評価します。詳細は、「条件付きGETの使用」を参照してください。

SecurityContext

セキュリティ・コンテキストにアクセスし、RESTful Webサービスを保護します。詳細は、「SecurityContextを使用したRESTful Webサービスの保護」を参照してください。

UriInfo

アプリケーションおよびリクエストURI情報にアクセスします。詳細は、「URIの構築」を参照してください。


URIの構築

javax.ws.rs.core.UriInfoを使用して、アプリケーションおよびリクエストURI情報にアクセスできます。具体的には、UriInfoは次の情報を返すために使用できます。

UriInfoを使用して、URIまたはjavax.ws.rs.core.UriBuilderインスタンスを返すことができます。UriBuilderはURIの構築プロセスを簡素化し、新規URIの構築、または既存URIの拡張にも使用できます。

UriBuilderメソッドは、対応するURIコンポーネントでは許可されていない文字のコンテキスト・エンコーディングを、次のルールに基づいて実行します。

例2-17に、@Contextを使用したUriInfoのインスタンスの取得と、そのインスタンスを使用して、リクエストURIの絶対パスをUriBuilderインスタンスとして返す方法を示します。次に、UriBuilderを使用して、ユーザーIDをパス・セグメントとして追加して特定のユーザー・リソースに対するURIを構築し、配列内に格納します。この例では、UriInfoインスタンスはクラス・フィールドに注入されます。この例は、「Jerseyブックマーク・サンプルについて」に記述されているとおり、ブックマーク・サンプルからの抜粋です。

例2-17 URIの構築

import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.Context;
...
@Path("/users/")
public class UsersResource {
 
    @Context UriInfo uriInfo;
 
    ...
 
    @GET
    @Produces("application/json")
    public JSONArray getUsersAsJsonArray() {
        JSONArray uriArray = new JSONArray();
        for (UserEntity userEntity : getUsers()) {
            UriBuilder ub = uriInfo.getAbsolutePathBuilder();
            URI userUri = ub.path(userEntity.getUserid()).build();
            uriArray.put(userUri.toASCIIString());
        }
        return uriArray;
    }
}

条件付きGETの使用

条件付きGETを使用すると、GETリクエストを処理する前に前条件を1つ以上評価できます。前条件が一致する場合、Not Modified (304)レスポンスを通常のレスポンスのかわりに返すことが可能で、これによって潜在的に帯域幅が縮小され、サーバー・パフォーマンスが向上します。

JAX-RSは、条件付きGETの実行を可能にするjavax.ws.rs.core.Requestコンテキスト・インタフェースを提供します。evaluatePreconditions()メソッドを呼び出してjavax.ws.rs.core.EntityTag、(java.util.Dateオブジェクトとして)最終変更日のタイムスタンプ、あるいはその両方を渡します。値はIf-None-MatchヘッダーまたはIf-Not-Modifiedヘッダーと、このヘッダーがリクエストとともに送信された場合は、それぞれ比較されます。

ヘッダーがリクエストとともに含まれ、前条件値がヘッダー値と一致する場合は、evaluatePreconditions()メソッドが定義済のResponseBuilderレスポンスをNot Modified (304)のステータス・コードとともに返します。前条件値が一致しない場合、evaluatePreconditions()メソッドはNULLを返し、通常のレスポンスが200, OKステータスとともに返されます。

例2-18に、EntityTagevaluatePreconditions()メソッドに渡し、前条件の一致の有無に基づいてレスポンスを構築する方法を示します。

例2-18 条件付きGETの使用

...
@Path("/employee/{joiningdate}")
public class Employee {
 
    Date joiningdate;
    @GET
    @Produces("application/xml")    
    public Employee(@PathParam("joiningdate") Date joiningdate, @Context Request req, 
            @Context UriInfo ui) {
 
        this.joiningdate = joiningdate;
        ...
        this.tag = computeEntityTag(ui.getRequestUri());
        if (req.getMethod().equals("GET")) {
            Response.ResponseBuilder rb = req.evaluatePreconditions(tag);
            // Preconditions met
            if (rb != null) {
                return rb.build();
            }
            // Preconditions not met
            rb = Response.ok();
            rb.tag(tag);
            return rb.build();
        }
    }
}

WADLのアクセス

Web Application Description Language (WADL)は、RESTful Webサービス・アプリケーションを記述するXMLベースのファイル形式です。デフォルトでは、ベースWADLがランタイムに生成され、RESTfulアプリケーションの基底URIでGET/application.wadlリソースに発行することで、RESTful Webサービスからアクセスできます。例:

GET http://<path_to_REST_app>/application.wadl

もしくは、OPTIONSメソッドを使用して特定のリソースに対するWADLを返すこともできます。

例2-19に、例2-1の簡単なRESTful Webサービスに対するWADLの例を示します。

例2-19 WADLの例

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application xmlns="http://research.sun.com/wadl/2006/10">
   <doc xmlns:jersey="http://jersey.dev.java.net/" 
              jersey:generatedBy="Jersey: 0.10-ea-SNAPSHOT 08/27/2008 08:24 PM"/>
   <resources base="http://localhost:9998/">        
      <resource path="/helloworld">            
         <method name="GET" id="sayHello">
            <response>
               <representation mediaType="text/plain"/>
            </response>
         </method>
      </resource>
   </resources>
</application> 

高度なRESTful Webサービス・タスク

以下に示すものを含む、高度なRESTful Webサービス・デプロイメント・タスクの詳細は、『Jersey 1.9 User Guide』(http://jersey.java.net/nonav/documentation/1.9/user-guide.html)を参照してください。