プライマリ・コンテンツに移動
Oracle® Fusion Middleware Oracle WebLogic Server RESTful Webサービスの開発と保護
12c (12.2.1)
E69940-01
  目次へ移動
目次

前
 
次
 

2 RESTful Webサービスの開発

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

この章の内容は次のとおりです:

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

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

次の各項で、RESTful Webサービスの開発について詳しく説明します。

Oracle JDeveloperを使用したRESTful Webサービスの開発の詳細は、『Oracle JDeveloperによるアプリケーションの開発』のRESTful Webサービスおよびクライアントの作成に関する項を参照してください。

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

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


注意:

表2-1で説明されている開発タスクに加えて、RESTful Webサービスの開発時にJersey 2.x (JAX-RS 2.0 RI)で使用できる機能の利用が必要になることもあります。主な機能のリストは、表1-2「Jersey 2.x (JAX-RS 2.0 RI)の主な機能」を参照してください。

表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のアクセス


必要に応じて、javax.ws.rs.core.Applicationを拡張するクラスを作成して、RESTful Webサービス・アプリケーション・デプロイメントのコンポーネントを定義し、追加のメタデータを提供します。

アプリケーション・サブクラスとのパッケージ化


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)レスポンスがクライアントに送信されます。

詳細は、Java EE 7 API仕様@Pathアノテーションを参照してください。

サブリソースの相対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です。このパスは、表4-1で定義されているパッケージ化オプションの一部として構成されます。特に、次を実行して、サーブレットのコンテキスト・パスを定義できます。

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

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

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

  • resourceURI—リソースまたはサブリソースに対して指定された@Path値。このパスは、複数のリソースおよびサブリソースの@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

レスポンス・ヘッダーのみを戻し、実際のリソースは戻しません(つまり、メッセージ本文はありません)。これは、実際にダウンロードせずにリソースの特性を確認して、バンド幅を節約するのに役に立ちます。詳細は、Java EE 7 API仕様@HEADアノテーションを参照してください。

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

はい

@OPTIONS

URIで識別された特定のリソースのリクエスト/レスポンス・チェーンで使用可能な通信オプションを戻します。Allowレスポンス・ヘッダーはリソースでサポートされるHTTPメソッドのセットに設定され、WADLファイルが戻されます。詳細は、Java EE 7 API仕様@OPTIONSアノテーションを参照してください。

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

はい

@HttpMethod

アノテーションの付けられたメソッドを使用してHTTPリクエストを処理する必要があることを示します。詳細は、Java EE 7 API仕様@HttpMethodアノテーションを参照してください。

該当なし


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

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

次の項に示す例は、Jersey 2.x (JAX-RS 2.0 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などです。詳細は、Java EE 7 API仕様@GETアノテーションを参照してください。

例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(MediaType.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(MediaType.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で識別された特定のリソースの表現を作成または更新します。詳細は、Java EE 7 API仕様@PUTアノテーションを参照してください。

例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(MediaType.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で識別された特定のリソースの表現を削除します。レスポンスのエンティティ本文ではステータス・メッセージが返されるか、または空の可能性があります。詳細は、Java EE 7 API仕様@DELETEアノテーションを参照してください。

例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で識別された特定のリソースの表現でのアクションを作成、更新、または実行します。詳細は、Java EE 7 API仕様@POSTアノテーションを参照してください。

例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(MediaType.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.Consumesまたはjavax.ws.rs.Producesアノテーションを追加し、リクエストおよびレスポンス・メディア・タイプをカスタマイズします。次の項を参照してください。

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

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

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

詳細は、Java EE 7 API仕様@Consumesアノテーションを参照してください。

例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 許可されません」エラーを返します。

詳細は、Java EE 7 API仕様@Producesアノテーションを参照してください。

例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パッケージにより、リクエスト・メッセージから情報を抽出してJavaメソッドのパラメータに注入できるアノテーションのセット(表2-4を参照)が定義されます。

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

アノテーション 説明

@BeanParam

単一のBeanに集約済リクエスト・パラメータを注入します。詳細は、Java EE 7 API仕様@BeanParamアノテーションを参照してください。

その他の使用方法の詳細は、Jersey 2.21ユーザー・ガイドパラメータ・アノテーション(@*Param)に関する項を参照してください。

@CookieParam

HTTP Cookie関連ヘッダーから情報を抽出し、メソッド・パラメータの値を初期化します。詳細は、Java EE 7 API仕様@CookieParamアノテーションを参照してください。

@DefaultValue

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

@Encoded

@FormParam@MatrixParam@PathParamまたは@QueryParamのいずれかのアノテーションを使用してバインドされるパラメータ値のエンコードを有効にします。詳細は、「パラメータ値のエンコードの有効化(@Encoded)」を参照してください。

@FormParam

タイプapplication/x-www-form-urlencodedのHTMLフォームから情報を抽出します。詳細は、Java EE 7 API仕様@FormParamアノテーションを参照してください。

@HeaderParam

HTTPヘッダーから情報を抽出し、メソッド・パラメータの値を初期化します。詳細は、Java EE 7 API仕様@HeaderParamアノテーションを参照してください。

@MatrixParam

URIパス・セグメントから情報を抽出し、メソッド・パラメータの値を初期化します。詳細は、Java EE 7 API仕様@MatrixParamアノテーションを参照してください。

@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)」を参照してください。

詳細は、Java EE 7 API仕様@QueryParamアノテーションを参照してください。

例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。詳細は、Java EE 7 API仕様@DefaultValueアノテーションを参照してください。

例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) 
    { ... }
}

パラメータ値のエンコードの有効化(@Encoded)

クラスまたはメソッド・レベルでjavax.ws.rs.Encodedアノテーションを追加して、@FormParam@MatrixParam@PathParamまたは@QueryParamのいずれかのアノテーションを使用してバインドされるパラメータ値のエンコードを有効にします。クラス・レベルで指定した場合は、そのクラスのすべてのメソッドのパラメータがエンコードされます。詳細は、Java EE 7 API仕様@Encodedアノテーションを参照してください。

例2-15@Encodedアノテーションは、@PathParamアノテーションを使用してバインドされるパラメータ値のエンコードを有効にします。

例2-15 パラメータ値のエンコード

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

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

デフォルトでは、正常な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インスタンスを構築できます。詳細は、Java EE 7 API仕様Responseメソッドを参照してください。

表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インスタンスを作成します。詳細は、Java EE 7 API仕様Response.ResponseBuilderメソッドを参照してください。

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

メソッド 説明

allow()

リソースに許可されているメソッドを設定します。

build()

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

cacheControl()

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

clone()

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

contentLocation()

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

cookie()

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

encoding()

メッセージ・エンティティのコンテンツ・エンコーディングを設定します。

entity()

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

expires()

有効期限を設定します。

header()

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

language()

言語を設定します。

lastModified()

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

link()

リンク・ヘッダーを追加します。

links()

1つ以上のリンク・ヘッダーを追加します。

location()

場所を設定します。

newInstance()

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

replaceAll()

既存のヘッダーをすべて新しく指定したヘッダーで置き換えます。

status()

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

tag()

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

type()

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

variant()

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

variants()

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


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

例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;
...
@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オブジェクトを作成する必要があります。詳細は、Java EE 7 API仕様GenericEntityメソッドを参照してください。

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

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

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();
   }
}

エンティティ・プロバイダを使用したHTTPリクエストおよびレスポンスのエンティティ本文のマッピング

表2-7に、HTTPリクエストおよびレスポンスのエンティティ本文で自動的にサポートされるJavaタイプを示します。

表2-7 HTTPリクエストおよびレスポンスのエンティティ本文でサポートされるJavaタイプ

Javaタイプ サポートされるメディア・タイプ

byte[]

すべてのメディア・タイプ(*/*)

java.lang.String

すべてのメディア・タイプ(*/*)

java.io.InputStream

すべてのメディア・タイプ(*/*)

java.io.Reader

すべてのメディア・タイプ(*/*)

java.io.File

すべてのメディア・タイプ(*/*)

javax.activation.DataSource

すべてのメディア・タイプ(*/*)

javax.xml.transform.Source

XMLメディア・タイプ(text/xmlapplication/xmlおよびapplication/*+xml)およびJSONメディア・タイプ(application/jsonapplication/*+json)

javax.xml.bind.JAXBElementおよびアプリケーション提供のJAXBのクラス

XMLメディア・タイプ(text/xmlapplication/xmlおよびapplication/*+xml)

MultivaluedMap<String,String>

フォーム・コンテンツ(application/x-www-form-urlencoded)

StreamingOutput

すべてのメディア・タイプ(*/*)、MessageBodyWriterのみ


RESTful Webサービスで、表2-7に示されていないタイプを使用する場合は、表2-8に定義されているインタフェースのいずれかを実装することでエンティティ・プロバイダを定義し、HTTPリクエストおよびレスポンスのエンティティ本文をメソッドのパラメータおよび戻りタイプにマップする必要があります。

表2-8 HTTPリクエストおよびレスポンスのエンティティ本文をメソッドのパラメータおよび戻りタイプにマップするためのエンティティ・プロバイダ

エンティティ・プロバイダ 説明

javax.ws.rs.ext.MessageBodyReader

HTTPリクエストのエンティティ本文をメソッドのパラメータにマップします。@Consumesアノテーションを使用すると、必要に応じて、エンティティ・プロバイダでサポートされているMIMEメディア・タイプを指定できます。詳細は、「リクエスト・メッセージおよびレスポンス・メッセージのメディア・タイプのカスタマイズ」を参照してください。

以下に例を示します。

@Consumes("application/x-www-form-urlencoded")
@Provider
public class FormReader implements MessageBodyReader<NameValuePair> { ... }

javax.ws.rs.ext.MessageBodyWriter

HTTPレスポンスのエンティティ本文に戻り値をマップします。@Producesアノテーションを使用すると、必要に応じて、エンティティ・プロバイダでサポートされているMIMEメディア・タイプを指定できます。詳細は、「リクエスト・メッセージおよびレスポンス・メッセージのメディア・タイプのカスタマイズ」を参照してください。

以下に例を示します。

@Produces("text/html")
@Provider
public class FormWriter implements 
        MessageBodyWriter<Hashtable<String, String>> { ... }


注意:

Jersey JSONには、Jersey JSON拡張モジュールとともに配布されるJAX-RS MessageBodyReaderプロバイダおよびMessageBodyWriterプロバイダのセットが用意されています。詳細は、Jersey 2.21ユーザー・ガイドJSONに関する項を参照してください。

次に示すコードの抜粋は、カスタム・タイプを返すメソッド(getClass)を含むクラスの例を示しています。このコードにはエンティティ・プロバイダを記述する必要があります。

public class Class1
{
  public String hello() { return "Hello"; }
  public Class2 getClass(String name) { return new Class2(); };
}
 
public class Class2
{
  public Class2() { }
}

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

javax.ws.rs.core.Contextアノテーションを使用すると、アプリケーション・デプロイメント・コンテキストと個別リクエストのコンテキストに関する情報にアクセスできます。表2-9@Contextアノテーションを使用してアクセスできるコンテキスト・タイプの概要を示します。詳細は、Java EE 7 API仕様@Contextアノテーションを参照してください。

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

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

HttpHeaders

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

Providers

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

Request

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

SecurityContext

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

UriInfo

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


URIの構築

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

  • デプロイされたアプリケーションの基底URI

  • 基底URIに相対するリクエストURI

  • 絶対パスURI (問合せパラメータ付きの場合もあり)

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

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

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

例2-18 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;
 
    ...
 
    @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-19に、EntityTagevaluatePreconditions()メソッドに渡し、前条件の一致の有無に基づいてレスポンスを構築する方法を示します。

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

...
@Path("/employee/{joiningdate}")
public class Employee {
 
    Date joiningdate;
    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サービスからアクセスできます。


注意:

コンテキスト・タイプapplication/vnd.sun.wadl+xmlは、Microsoft Internet Explorer 8では認識されません。その場合、参照用にWADLのコピーをローカル・ファイル・システムにダウンロードできます。

以下に例を示します。

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

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

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

例2-20 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サービス・タスク

JAX-RSとEJBテクノロジおよびContexts and Dependency Injection (CDI)との統合やJAXBおよびJSONの使用など、高度なRESTful Webサービス開発タスクの詳細は、Jersey 2.21ユーザー・ガイドを参照してください。