1.2.15. RESTful Webサービス

1.2.15.1. RESTful Webサービス・プロジェクトの作成

新規プロジェクトから作成
動的Webプロジェクト・ウィザードで、RESTful Webサービスのプロジェクトを作成できます。
メニューから ファイル新規プロジェクトを選択し、新規プロジェクトダイアログを表示します。
新規プロジェクト画面のWeb配下の 動的 Web プロジェクトを選択し、次へをクリックします。


図1.2.15.1-1

プロジェクト名を入力し、構成変更をクリックします。


図1.2.15.1-2

プロジェクト・ファセットJAX-RS (REST Web Service) 1.1を選択し、OK を押します。


図1.2.15.1-3

次の Javaページでは、ソース・フォルダなどを変更可能ですが、 特に変更の必要が無い場合、次へで先に進んでください。
Web モジュールでも、必要に応じて適宜、指定を変更後、次へをクリックします。


図1.2.15.1-4

JAX-RS Capabilitiesページでライブラリー構成を無効を選択し、Servlet Information に以下の内容を入力します。


図1.2.15.1-5

表1.2.15.1-1
項目
説明
JAX-RS servlet name
必須。JAX-RSサーブレット名を設定します。
JAX-RS servlet class name
必須。com.nec.webotx.jersey.spi.container.servlet.ServletContainerを設定します。
URL マッピング・パターン
JAX-RSサーブレットにマッピングするURLパターンを設定します。通常は[/jaxrs/*]を設定します。
完了 をクリックすると、JAX-RS(REST Web Service) ファセットを持つ動的Webプロジェクトが以下のようなディレクトリ構成で作成されます。


図1.2.15.1-6

既存の動的WebプロジェクトからRESTful Webサービスへ変換
既存の動的WebプロジェクトにJAX-RS(REST Web Service) ファセットの追加と変更ができます。
既存動的Webプロジェクトを選択して、右クリックして表示されるプロジェクトの プロパティーダイアログで プロジェクト・ファセットを選択します。


図1.2.15.1-7

JAX-RS (REST Web Service)を選択し、完了をクリックします。


図1.2.15.1-8

1.2.15.2. JAX-RSのアノテーション

JAX-RS カテゴリに所属するアノテーションについては、 [ アプリケーション開発ガイド(共通) > 8. アノテーション定義支援ツール > 8.4. サポートするアノテーション > 8.4.6. JAX-RSアノテーション ] をご覧ください。

1.2.15.3. ルートリソースクラス

ルートリソースクラスは、リソースメソッド、サブリソースメソッド、またはサブリソースロケータのどれかを一つ以上持ち、クラスレベルでPathアノテーションでアノテートされたJavaのpublicのクラスです。 ルートリソースはRESTful Webサービスに提供するリソースのルートで、他のリソースの入り口になります。

ルートリソースクラスの例を下記に示します。
  1 package com.sun.ws.rest.samples.helloworld.resources;
  2 
  3 import javax.ws.rs.GET;
  4 import javax.ws.rs.Produces;
  5 import javax.ws.rs.Path;
  6 
  7 // The Java class will be hosted at the URI path "/helloworld"
  8 @Path("/helloworld")
  9 public class HelloWorldResource {
 10 
 11     // The Java method will process HTTP GET requests
 12     @GET
 13     // The Java method will produce content identified by the MIME Media
 14     // type "text/plain"
 15     @Produces("text/plain")
 16     public String getClichedMessage() {
 17         // Return some cliched textual content
 18         return "Hello World";
 19     }
 20 }
ライフサイクル
ルートリソースクラスのライフサイクルは以下の三種類があります。
コンストラクタ
ルートリソースクラスは、publicデフォルトコンストラクタ(明示的に宣言されないコンストラクタ)も含めて、少なくとも一つ以上のpublicコンストラクタを持つ必要があります。 コンストラクタのパラメータで使用できるインジェクション用アノテーションと、オプションのアノテーションの組み合わせは表1.2.15.3-1を参照ください。

パラメータを持つコンストラクタの例を次に示します。
@Path("ResourceTest1")
public class Resource1{
    private String query1;
    public Resource1(@Encoded @DefaultValue("abc") @QueryParam("queryParam1") String query) {
    query1 = query;
}	
@GET
@Path("/queryParam1Value")
    public String getQuery1Value() {
        return "query1=" + query1;
    }
}
この例では、クライアントからURL http://sample.com/example/ResourceTest1/queryParam1Value?queryParam1=queryValueでアクセスすると、queryValueを返却します。
フィールドおよびbeanプロパティ
ルートリソースクラスのフィールドおよびbeanプロパティで使用できるアノテーションと、オプションのアノテーションの組み合わせを次の表に示します。JAX-RSエンジンは、ルートリソースクラスをインスタンス化する際に、アノテーション定義されたフィールドおよびbeanプロパティに値をインジェクトします。表にあるアノテーションの意味は[1.2.15.9. アノテーションのパラメータ]で説明します。
表1.2.15.3-1
項番 インジェクション用アノテーション オプションのアノテーション
Encoded DefaultValue
1 MatrixParam
2 QueryParam
3 PathParam ×
4 CookieParam ×
5 HeaderParam ×
6 FormParam ×
7 Context × ×
○:インジェクション用のアノテーションと組み合わせて使用できることを示します。
×:インジェクション用のアノテーションが使用できないことを示します。

ルートリソースクラスのフィールドで@Encodedアノテーションを使用する例を次に示します。
private @Encoded @DefaultValue("value1") @QueryParam("id") String id;
URLで“会社”をUTF-8でencodeしたパラメータの値“%E4%BC%9A%E7%A4%BE”でアクセスすると (http://sample.com/example/ResourceTest3/queryParam1Value?id=%E4%BC%9A%E7%A4%BE) リソースクラスで取得できるidの値は“%E4%BC%9A%E7%A4%BE”となり、encodeされた内容になります。
@Encoded アノテーションを使用しない場合、元の文字列“会社”で取得できます。

beanプロパティの@DefaultValueと組み合わせの例:
private String property1;
@DefaultValue("10") @QueryParam("paramProperty1")
public void setProperty1(String property1) {
  this.property1 = property1;
}
この例では、URLの“paramProperty1”QueryParamの値を自動的にproperty1にインジェクションします。
リソースメソッド
リソースメソッドは、JAX-RS仕様で定義されたリクエストメソッド識別子でアノテートされたルートリソースクラスのpublicメソッドです。ルートリソースクラスは、一つ以上のリソースメソッドを持つことができます。
JAX-RS仕様で定義されたリクエストメソッド識別子は[1.2.15.6. HTTPメソッド]を参照して下さい。

リソースメソッドの例を次に示します。
@Path("resource_method")
public class ResourceMethodResource {
	@GET
	public String resourceMethod() {
		return "this is a resource method.";
	}
}
ルートリソースクラスResourceMethodResourceのメソッドresourceMethod()はリソースメソッドです。 クライアントからURI「resource_method」にアクセスする時、JAX-RSエンジンはそのメソッドを呼び出します。
サブリソースメソッド
@Pathアノテーションでアノテートされたリソースメソッドをサブリソースメソッドと呼びます。サブリソースメソッドとリソースメソッドの違いは、Pathアノテーションを使用しているか否かになります。

サブリソースメソッドの例を次に示します。
@Path("/resourceTest1")
public class Resource1 {
    public Resource1(){
    }
...
    @GET
    @Path("/testPathParam/{arg1}/{arg2}")
    public String listPathParam(@PathParam("arg1") String arg1,@PathParam("arg2") String arg2) {
        return "arg1="+arg1+" and arg2="+arg2;
    }
...
}
listPathParamメソッドはサブリソースメソッドです。 /resourceTest1/testPathParam/{arg1}/{arg2}のURIにリクエストすると、listPathParam()はそのリクエストを処理します。
サブリソースロケータ
サブリソースロケーターは、リクエストメソッド識別子が適用されず、@Pathアノテーションのみでアノテートされたルートリソースクラスのメソッドです。 サブリソースロケータは、HTTPリクエストに対する残りの処理を行うサブリソースクラスを返却します。サブリソースクラスについては、[1.2.15.4. サブリソースクラス] を参照して下さい。

ルートリソースクラスのサブリソースロケータの例を次に示します。
@Path("/resourceTest1")
public class Resource1 {
    @Path("/testSubResourceLocator/{id}")
    public Resource1_1 getResource1_1(@PathParam("id") String id){
        return new Resource1_1(id);
    }
...
}
対応するサブリソースクラスの例を次に示します。
public class Resource1_1 {
    private String resourceID;
    public Resource1_1(String id){
        resourceID = id;
  }    
    @GET
    public String getDetails(){
        return "This resource id is "+resourceID;
    }
}
この例では、ルートリソースクラスResource1はHTTPリクエストを直接処理しません。サブリソースロケータgetResource1_1が返すサブリソースクラスResource1_1がそのリクエストを処理します。

1.2.15.4. サブリソースクラス

サブリソースクラスは、リソースメソッド、サブリソースメソッド、またはサブリソースロケータのどれかを一つ以上持ち、クラスレベルで@Path アノテーションでアノテートされていないJava のクラスです。
サブリソースクラスは、サブリソースロケータから移譲されたリクエストを直接処理するか、同じ仕組みによって、さらにサブリソースクラスにリクエストを移譲します。

サブリソースクラスの例を次に示します。
public class Resource1_1 {
    private String resourceID;
    public Resource1_1(String id){
        resourceID = id;
  }    
    @GET
    public String getDetails(){
        return "This resource id is "+resourceID;
    }
}
サブリソースクラスのインスタンスは、JAX-RSエンジンによって生成されません。サブリソースクラスは、対応するサブリソースロケータでインスタンス化する必要があります。
ライフサイクル
サブリソースクラスのインスタンスは、JAX-RSエンジンによって生成されません。 サブリソースクラスは、対応するサブリソースロケータでインスタンス化する必要があります。このため、サブリソースロケータまたはサブリソースクラスで、コンストラクタのパラメータ、フィールド、およびbeanプロパティを初期化する必要があります。
コンストラクタ
サブリソースクラスのコンストラクタのパラメータでは、JAX-RS仕様のアノテーションを使用しないでください。使用されている場合は無視されます。
フィールドおよびbeanプロパティ
JAX-RS仕様のアノテーションをサブリソースクラスのフィールドおよびbeanプロパティで使用しないでください。使用されている場合は無視されます。
リソースメソッド、サブリソースメソッドおよびサブリソースロケータ
サブリソースクラスのリソースメソッド、サブリソースメソッド、およびサブリソースロケータは、ルートリソースクラスの場合と同じです。

1.2.15.5. URIテンプレート

@PathアノテーションはリソースのURIを指定するアノテーションです。ルートリソースクラス、サブリソースメソッド、サブリソースロケータに使用できます。

@Pathアノテーションの値は、Webリソースを含むWebアプリケーション(WARファイル)のコンテキストルートに対して相対的なURIを示します。書式は @Path("相対URI") で表されます。
 URIは”/”から始まらなくても同じ意味を持ちます。@Path("users/user1")と@Path("/users/user1")は同じURIになります。

 URIには変数を使用できます。変数を使用する場合、変数名を{}で囲みます。
 例として、@Path("/users/{username}")のように指定します。
 username変数の値は、リソースクラスで@PathParamアノテーションを用いて取得できます。

 また、URIには正規表現で記述もできます。
 例として、@Path("/testRegular1/{username:[a-zA-Z][a-zA-Z_0-9]*}")の場合、usernameの値は「[a-zA-Z][a-zA-Z_0-9]*」と一致します。

PathアノテーションのURIにアスタリスク(*)のみを指定した場合は、リソースメソッドのみを呼び出すことができます。サブリソースメソッド、およびサブリソースロケータを呼び出した場合は、java.lang.StringIndexOutOfBoundsException例外がスローされます。

アノテーションの値は、自動的にエンコードされます。例として、次に示すアノテーションの意味は同じです。
 @Path ("widget list/{id}")
 @Path ("widget%20list/{id}")

1.2.15.6. HTTPメソッド

HTTPメソッドアノテーションはHTTPリクエストメソッドの識別子です。リソースメソッドの前に定義することで、そのメソッドは対応するHTTPメソッドのリクエストを処理できます。

@GET
HTTPのGETリクエストを処理するメソッドの識別子です。このアノテーションを使用できる対象は下記のとおりです。
@POST
HTTPのPOSTリクエストを処理するメソッドの識別子です。このアノテーションを使用できる対象は下記のとおりです。
@PUT
HTTPのPUTリクエストを処理するメソッドの識別子です。このアノテーションを使用できる対象は下記のとおりです。
@DELETE
HTTPのDELETEリクエストを処理するメソッドの識別子です。このアノテーションを使用できる対象は下記のとおりです。
@HEAD
HTTPのHEADリクエストを処理するメソッドの識別子です。このアノテーションを使用できる対象は下記のとおりです。 リソースクラスはHEADリクエストを受け取った時、@HEADでアノテートされたメソッドでHEADリクエストを処理します。@HEADでアノテートされたメソッドが存在しない場合、@GETでアノテートされたメソッドによりHEADリクエストを処理し、レスポンスボディを返信しません。
@OPTIONS
HTTPのOPTIONSリクエストを処理するメソッドの識別子です。このアノテーションを使用できる対象は下記のとおりです。 リソースクラスはOPTIONSリクエストを受け取った時、@OPTIONSでアノテートされたメソッドでリクエストを処理します。@OPTIONSでアノテートされたメソッドが存在しない場合、自動生成したmetadataレスポンスを返信します。 metadataはそのルートリソースクラスのwadl情報です。下記に例で説明します。

import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("optionsmethod")
public class OptionsMethodResource {
	@GET
	public String getHello() {
		return "hello";
	}
}
クライアントからHTTP OPTIONSリクエストメソッドでURI「optionsmethod」のリソースをリクエストする時、サーバから下記の内容が返信されます。
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://wadl.dev.java.net/2009/02">
    <doc xmlns:jersey="http://jersey.java.net/" jersey:generatedBy="Jersey: 1.11 12/09/2011 10:27 AM"/>
    <grammars/>
    <resources base="http://{server-name:port}/{context-root}/{url-pattern}/">
        <resource path="optionsmethod">
            <method id="getHello" name="GET">
                <response>
                    <representation mediaType="*/*"/>
                </response>
            </method>
        </resource>
    </resources>
</application>

1.2.15.7. MIMEタイプ宣言

@Consumesアノテーション
@Consumesアノテーションはリソースで受け付けるリクエストのMIMEタイプを表します。以下の箇所で@Consumesアノテーションが使用できます。     エンティティプロバイダについては、[1.2.15.12. プロバイダ] を参照して下さい。

アノテーションで指定したMIMEタイプ以外は受け付けず例外になリます。その時、INFOで「Mapped exception to response: 415 (Unsupported Media Type)」ログを出力します。HTTPステータスコードに415 Unsupported Media Typeがクライアント返却して、例外javax.ws.rs.WebApplicationExceptionのstackがログに出力します。
@Producesアノテーション
@Produces アノテーションはリソースから返却されるメッセージのMIMEタイプを指定します。 以下の箇所で@Producesアノテーションを使用できます。     エンティティプロバイダについては、[1.2.15.12. プロバイダ] を参照して下さい。

1.2.15.8. アノテーションの継承

親クラスやインタフェースのメソッドで使用されているJAX-RS仕様のアノテーションは子クラスや実装クラスに継承できます。 アノテーションが継承される条件を次に示します。 親クラスを継承し、かつインタフェースを実装している場合で、アノテーションを継承する条件に両方合致する場合は親クラスのアノテーションを優先しています。

複数の親クラスを継承している場合、または複数のインタフェースを実装している場合、それぞれ最初に継承または実装している親クラスまたはインタフェースのアノテーションが優先されます。アノテーションが継承される例を以下に示します。

1.インタフェース実装の例:
//インタフェース
public interface A {
    @GET
    public String getValue(@QueryParam("query") String query);
}
//インタフェースを実装するルートリソースクラス
@Path("/root/")
public class Resource implements A {
    public String getValue(String query) {…}
}
URL http://sample.com/example/resource/root?query=10 に対するHTTP GETリクエストは、リソースメソッドgetValue()にディスパッチされます。リソースメソッドgetValue()はインタフェースのGETアノテーションを継承しているためです。

2.クラス継承の例
//親クラス
public class ParentClassA {
	@GET
	public String getValue(@QueryParam("query1") String query1){
		return "query1 = "+query1;
	}
}
//子クラス
@Path("/inheretance")
public class SubClass extends ParentClassA {
	public String getValue(String query){
		return query;
	}
}
URL http://sample.com/example/resource/inheretance?query1=10 にアクセスすると、queryの値は10を取得できます。

3.複数インタフェース実装例
public interface InterfaceA {
	@GET
	public String getValue(@PathParam("path1") String path1);
}
public interface InterfaceB {
	@GET
	public String getValue(@QueryParam("query") String query);
}
@Path("/inheretance/{path1}")
public class SubClass implements InterfaceB, InterfaceA{
	public String getValue(String param){
		return param;
	}
}

URL http://sample.com/example/resource/inheretance/aaa?query=456 にアクセスすると、paramの値は456を取得できます。これは、InterfaceBが先にインタフェース実装されており、InterfaceBのアノテーションが優先利用されるためです。 以下のようにInterfaceAを先に
@Path("/inheretance/{path1}")
public class SubClass implements InterfaceA, InterfaceB{
	public String getValue(String param){
		return param;
	}
}
この場合、http://sample.com/example/resource/inheretance/aaa?query=456 にアクセスすると、paramの値はaaaを取得できます。

1.2.15.9. アノテーションのパラメータ

リソースクラスのコンストラクターのパラメータの値、フィールドの値とリソースメソッド、サブリソースメソッド、サブリソースロケータのパラメータの値はアノテーションより取得できます。

以下のアノテーションはリソースクラスのコンストラクターのパラメータ、リソースメソッド、サブリソースメソッド、サブリソースロケータのパラメータとクラスのフィールド、Beanプロパティで使用できます。

アノテーションで取得できるパラメータの型の一覧およびDefaultValueアノテーションの組み合わせを次の表に示します。
表1.2.15.9-1
項番 データ型 アノテーション
PathParam QueryParam MatrixParam CookieParam HeaderParam FormParam Context
1 プリミティブ int ○※1 ×
2 short ○※1 ×
3 long ○※1 ×
4 float ○※1 ×
5 double ○※1 ×
6 char × × × × × × ×
7 byte ○※1 ×
8 boolean ○※1 ×
9 String型の引数を一つ取るコンストラクタを持つ型 ○※1 ×
10 String型の引数を一つ取りその型のインスタンスを返すコンストラクタを持ち、かつstaticなvalueOfまたはfromStringメソッドを持つ型 ※2 ○※1 ×
11 List<T>(Tが上記項番9、10のデータ型) ○※1 × ×
12 Set<T>(Tが上記項番9、10のデータ型) ○※1 × ×
13 Sorted Set<T>(Tが上記項番9、10のデータ型) ○※1 × ×
14 PathSegment ○※1 × × × × × ×
15 コンテキスト型 UriInfo × × × × × × ○※1
16 HttpHeaders × × × × × × ○※1
17 Request × × × × × × ○※1
18 SecurityContext × × × × × × ○※1
19 Providers × × × × × × ○※1
20 ServletConfig × × × × × × ○※1
21 ServletContext × × × × × × ○※1
22 HttpServletRequest × × × × × × ○※1
23 HttpServletResponse × × × × × × ○※1
(凡例)
  ○:インジェクション用アノテーションを使用できることを示します。
  ×:インジェクション用アノテーションを使用できないことを示します。

※1
DefaultValueアノテーションを組み合わせて使用できません。

※2
String型の引数を一つ取りその型のインスタンスを返すコンストラクタを持つ型が、staticなvalueOfメソッドとstaticなfromStringメソッドの両方を持つ場合、型がenum型であれば、staticなfromStringメソッドを使用します。enum型以外であれば、staticなvalueOfメソッドを使用します。
@HeaderParamアノテーション
HTTPリクエストヘッダの情報を取得するために使用します。

例:public String getHeaderParam(@HeaderParam("connection") List<String> headers)と定義すると、HTTPリクエストヘッダのコネクション情報をheadersパラメータにインジェクションできます。

@HeaderParamアノテーションを指定できる対象:
表1.2.15.9-2
ルートリソースクラスのコンス トラクターのパラメーター ルート(サブ)リソースクラスのリソースメソッドのパラメータ ルート(サブ)リソースクラスのサブリソースメソッドのパラメータ ルート(サブ)リソースクラスのサブリソースロケータのパラメータ ルートリソースクラスのフィールド ルートリソースクラスのBeanプロパティ
(凡例)
  ○:指定できることを示します。
  ×:指定できないことを示します。
  −:該当するパラメータがないことを示します。
@CookieParamアノテーション
HTTP Cookieの情報を取得するために使用します。

例:public String listCookieParam(@CookieParam("sessionid") Cookie arg1,@Context HttpServletResponse response)と定義すると、HTTP CookieのセッションIDをarg1にインジェクションできます。

@HeaderParamアノテーションを指定できる対象:
表1.2.15.9-3
ルートリソースクラスのコンス トラクターのパラメーター ルート(サブ)リソースクラスのリソースメソッドのパラメータ ルート(サブ)リソースクラスのサブリソースメソッドのパラメータ ルート(サブ)リソースクラスのサブリソースロケータのパラメータ ルートリソースクラスのフィールド ルートリソースクラスのBeanプロパティ
(凡例)
  ○:指定できることを示します。
  ×:指定できないことを示します。
  −:該当するパラメータがないことを示します。
@MatrixParamアノテーション
リクエストURIのマトリクスパラメータの値を取得するために使用します。

例:public String listMatrixParam(@MatrixParam("bookName") String arg1, @MatrixParam("author") String arg2)と定義すると、 URIに http://sample.com/example/resourceTest1/testMatrixParam;bookName=study;author=Tom を指定した場合、studyをarg1に、Tomをarg2にインジェクションできます。

@MatrixParamアノテーションを指定できる対象:
表1.2.15.9-4
ルートリソースクラスのコンス トラクターのパラメーター ルート(サブ)リソースクラスのリソースメソッドのパラメータ ルート(サブ)リソースクラスのサブリソースメソッドのパラメータ ルート(サブ)リソースクラスのサブリソースロケータのパラメータ ルートリソースクラスのフィールド ルートリソースクラスのBeanプロパティ
(凡例)
  ○:指定できることを示します。
  ×:指定できないことを示します。
  −:該当するパラメータがないことを示します。
@QueryParamアノテーション
リクエストURIのクエリパラメータの値を取得するために使用します。

例:public String listPathParam(@QueryParam("arg1") String arg1)) {…} と定義すると、 URIに http://sample.com/example/resources/resource3?arg1=arg1Value を指定した場合、 arg1Valueをarg1にインジェクションできます。

@QueryParamアノテーションを指定できる対象:
表1.2.15.9-5
ルートリソースクラスのコンストラクターのパラメーター ルート(サブ)リソースクラスのリソースメソッドのパラメータ ルート(サブ)リソースクラスのサブリソースメソッドのパラメータ ルート(サブ)リソースクラスのサブリソースロケータのパラメータ ルートリソースクラスのフィールド ルートリソースクラスのBeanプロパティ
(凡例)
  ○:指定できることを示します。
  ×:指定できないことを示します。
  −:該当するパラメータがないことを示します。
@PathParamアノテーション
URIのパスの値を取得するために使用します。

例:@Path(“resources/resource3/{arg1}/{arg2}”) public String listPathParam(@PathParam("arg1") String arg1, @PathParam("arg2") String arg2) {…} と定義すると、 URIに http://sample.com/example/resources/resource3/arg1Value/argValue2 を指定した場合、 arg1Valueをarg1に、argValue2をarg2にインジェクションできます。

@PathParamアノテーションを指定できる対象:
表1.2.15.9-6
ルートリソースクラスのコンス トラクターのパラメーター ルート(サブ)リソースクラスのリソースメソッドのパラメータ ルート(サブ)リソースクラスのサブリソースメソッドのパラメータ ルート(サブ)リソースクラスのサブリソースロケータのパラメータ ルートリソースクラスのフィールド ルートリソースクラスのBeanプロパティ
(凡例)
  ○:指定できることを示します。
  ×:指定できないことを示します。
  −:該当するパラメータがないことを示します。
@Contextアノテーション
コンテキストの値をインジェクトするために使用します。

以下の型をパラメータに指定できます。
javax.ws.rs.core.UriInfo
URIを構成する各コンポーネント(クエリパラメータやマトリクスパラメータなど)を保持するコンテキストです。HTTPリクエストごとの情報を提供します。
例:
@Path("/root")
public class Resource {
  private @Context UriInfo uriInfo;
  @GET
  public String getValue() {
    String value = this.uriInfo.getQueryParameters().getFirst("query");
    return value;
  }
}
URL http://sample.com/example/root?query=10 にアクセスすると、valueの値は10になります。
javax.ws.rs.core.HttpHeaders
HTTPリクエストのHTTPヘッダを保持するコンテキストです。
例:
@Path("/root")
public class Resource {
  private @Context HttpHeaders httpHeaders;
  @GET
  public String getValue () {
    String value = this.httpHeaders.getRequestHeader("Accept").get(0);
    return value;
  }
}
HTTP Acceptヘッダに"application/xml"を指定し、 URL http://sample.com/example/root"に対するHTTP GETリクエストでアクセスすると、 valueの値はapplication/xmlになります。
javax.ws.rs.core.Providers
デプロイされたWebリソースで動作するプロバイダを保持するコンテキストです。
例:
@Path("/root")
public class Resource {
  private @Context Providers providers;
  @GET
  public String getValue() {
    //providersフィールドから例外マッピングプロバイダを取得します
    return this.providers.getExceptionMapper(RuntimeException.class);
  }
}
URL http://sample.com/example/root にアクセスすると、java.lang.RuntimeExceptionを処理できる例外マッピングプロバイダインスタンスが取得できます。
javax.ws.rs.core.SecurityContext
処理中のHTTPリクエストに関連するセキュリティ情報を保持するコンテキストです。
例:
@Path("/root")
public class Resource {
private @Context SecurityContext securityContext;
  @GET
  public String getValue () {
    String value = "Authentication Scheme: "
        + this.securityContext.getAuthenticationScheme()
        + ", User Principal: " + this.securityContext.getUserPrincipal()
        + ", Is secure: " + this.securityContext.isSecure()
        + ", Is user in role: " + this.securityContext.isUserInRole("admin");
    return value;
  }
}
セキュリティ情報を含むweb.xmlの例を次に示します。
<?xml version="1.0" encoding="UTF-8"?>
<web-app ...>
  ...
  <security-constraint>
     <web-resource-collection>
       <web-resource-name>Test Resource</web-resource-name>
       <url-pattern>/*</url-pattern>
       <http-method>GET</http-method>
     </web-resource-collection>
     <auth-constraint>
       <role-name>admin</role-name>
     </auth-constraint>
  </security-constraint>
  <login-config>
     <auth-method>BASIC</auth-method>
     <realm-name>jaxrs_server</realm-name>
  </login-config>
  <security-role>
     <role-name>admin</role-name>
  </security-role>
</web-app>
URL http://sample.com/example/root にアクセスすると、web.xmlの設定と実際の認証情報に基づいてセキュリティ情報が取得できます。 WebOTXのJAX-RSではBASIC認証とDigest認証が使用できます。
javax.ws.rs.core.HttpServletRequest
javax.servlet.http.HttpServletRequestはServlet仕様で定義されているクラスです。
例:
@Path("/root")
public class Resource {
  private @Context HttpServletRequest httpRequest;
  @GET
  public String getValue() {
    return this.httpRequest.getParameter("TestParam");
  }
}
URL: http://sample.com/example/root?TestParam=TestValueでアクセスすると、 getValue()よりTestParamパラメータの値TestValueを取得できます。
javax.ws.rs.core.HttpServletResponse
javax.servlet.http.HttpServletResponse はServlet仕様で定義されているクラスです。
例:
@Path("/root")
public class Resource {
  private @Context HttpServletResponse httpResponse;
  @GET
  public void getValue() throws IOException {
    String entity = "Response mentioned using HttpServletResponse";
    httpResponse.setHeader("abc","xyz");
    httpResponse.getOutputStream().write(entity.getBytes());
    httpResponse.getOutputStream().flush();
    httpResponse.getOutputStream().close(); 
  }
}
URL:http://sample.com/example/root にHTTP GETリクエストでアクセスすると、httpResponseフィールドにHttpServletResponseがインジェクトされ、その後HTTP GETリクエストを処理するgetValue()メソッドが呼び出されます。
javax.ws.rs.core.ServletConfig
javax.servlet.ServletConfig はServlet仕様で定義されているクラスです。
例:
@Path("/root")
public class Resource {
  private @Context ServletConfig config;
  @GET
  public String getValue() {
    return this.config.getInitParameter("TestParam");    
  }
}
追加の初期化パラメータ(init-param要素)を含むweb.xmlの例を次に示します。
<web-app ...>
<servlet>
<init-param>
      <param-name>TestParam</param-name>
      <param-value>TestValue</param-value>
</init-param>
……
</servlet>
</web-app>
URL:http://sample.com/example/root にHTTP GETリクエストでアクセスすると、初期化パラメータ"TestParam"の値"TestValue"を取得できます。
javax.ws.rs.core.ServletContext
javax.servlet.ServletContext はServlet仕様で定義されているクラスです。
例:
@Path("/root")
public class Resource {
  private @Context ServletContext context;
  @GET
  public String getValue() {
    return this.context.getInitParameter("TestParam");    
  }
}
コンテキストスコープの初期化パラメータ(context-param要素)を含むweb.xmlを次に示します。
<?xml version="1.0" encoding="UTF-8"?>
<web-app ...>
  ...
  <context-param>
    <param-name>TestParam</param-name>
    <param-value>TestValue</param-value>
  </context-param>
</web-app>
URL:http://sample.com/example/root にHTTP GETリクエストでアクセスすると、コンテキストスコープの初期化パラメータ"TestParam"の値"TestValue"が取得できます。
javax.ws.rs.core.Request
RFC 2616で規定されるコンテント・ネゴシエーションを行うためのコンテキストを格納しているクラスです。
@FormParamアノテーション
HTMLフォームからPOSTされたパラメータは@FormParamでアノテートされたパラメータにインジェクションされます。この時のMIMEタイプは"application/x-www-form-urlencoded"ではなければなりません。

@FormParamアノテーションを指定できる対象:
表1.2.15.9-7
ルートリソースクラスのコンストラクターのパラメーター ルート(サブ)リソースクラスのリソースメソッドのパラメータ ルート(サブ)リソースクラスのサブリソースメソッドのパラメータ ルート(サブ)リソースクラスのサブリソースロケータのパラメータ ルートリソースクラスのフィールド ルートリソースクラスのBeanプロパティ
(凡例)
  ○:指定できることを示します。
  ×:指定できないことを示します。
  −:該当するパラメータがないことを示します。

例:
html form:
<html>
<head>
<meta http-equiv="content-type" content="text/xml;charset=utf-8">
<title> test RESTFulWebService @FromParam</title>
</head>
<body>
<form action="http://localhost:8080/WebProject1/myApplication1/testFormParam" method="post" >
<table>
<tr>
<td>FirstName:</td>
<td><input type="text" name="firstname"></td>
</tr>
<tr>
<td>Age:</td>
<td><input type="text" name="age"></td>
</tr>
</table>
<input type="submit" value="Submit" >
</form>
</body>
</html>
リソースクラス:
@Path("testFormParam")
public class FormResource {
@POST
@Consumes("application/x-www-form-urlencoded")
public String getFormString(@FormParam("firstname") String name, @FormParam("age") int age){
	return "firstname="+name+";age="+age;
	}
}
FirstName入力ボックスにname1を入力し、age入力ボックスに20を入力した場合、リソースクラスの@FormParamからname1と20を取得できます。
@Encodedアノテーション
Encodedアノテーションは、自動でURLにあるパラメータの値をデコードされるのを無効化します。
@DefaultValueアノテーション
DefaultValueアノテーションはパラメータのデフォルト値を設定できます。

各アノテーションのパラメータとデフォルト値の対応について、次の表で説明します。
表1.2.15.9-8
パラメータ DefaultValue使用の結果 備考(リクエストパスに指定パラメータの存在状況によって、DefaultValueの利用状況を説明します)
MatrixParam 対応するParamがリクエストパスに存在しない場合、デフォルト値が使用されます。(備考欄の(2)に該当する場合、DefaultValueを使用しません) (1)リクエストパスに指定パラメータが存在しない場合、DefaultValue を利用します。例えば、リクエストパスに「;null」あるいは「; 指定パラメータ以外のパラメータ= XXX」を指定します。
(2)リクエストパスに指定パラメータがある場合、DefaultValue を利用しません。指定パラメータに値を与えない場合、値はnullになります。指定パラメータに値を与え場合、実際値を利用します。例えば、リクエストパスに「;指定パラメータ名」しか指定しない場合、値はnullになります。
QueryParam 同上 同上
FormParam 同上 同上
CookieParam 同上 同上

※複数のパラメータ値を指定する場合、最後の値を利用します。
HeaderParam 対応するParamがリクエストに存在しない場合、DefaultValue値が使用されます。(備考欄の(2)に該当する場合、DefaultValueを使用しません) (1)リクエストパスに指定するパラメータが存在しない場合、DefaultValue値を利用します。 リクエストパスに一番目に指定するパラメータの値が指定しない場合(「指定パラメータ」のように指定します)、DefaultValue値を利用します。
(2)一番目のパラメータは指定パラメータで、また有効の値を指定する場合、DefaultValue値を利用しません。
PathParam DefaultValueアノテーションを無視します。 --
Context DefaultValueアノテーションを無視します。 --

1.2.15.10. エンティティパラメータ

リソースメソッドのパラメータのうち、アノテーションでアノテートされていないパラメータをエンティティパラメータと呼びます。エンティティパラメータの値は、HTTPエンティティボディです。HTTPエンティティボディからエンティティパラメータのインスタンスへはエンティティプロバイダで変換しています。エンティティプロバイダの詳細は [1.2.15.12. プロバイダ] を参照ください。

リソースメソッド、サブリソースメソッド、サブリソースロケータには一つエンティティパラメータのみ定義できます。複数なエンティティパラメータを定義した場合、メソッドの一つ目のエンティティパラメータが有効になります。他のエンティティパラメータは無視されます。使用できるエンティティパラメータの型は提供するエンティティプロバイダに従います。

Javaの型に適合するエンティティプロバイダの詳細は [表1.2.15.12-1] を参照ください。それらのエンティティプロバイダ以外にカスタマイズプロバイダも定義できます。定義方法は [1.2.15.12. プロバイダ] を参照ください。

以下はエンティティパラメータの型がFile(内蔵エンティティプロバイダを利用します)の場合の例です。内蔵エンティティプロバイダはリクエストボディの内容をFileオブジェクトに変更するので、リソースクラスでリクエストボディの内容を含むFileオブジェクトを利用できます。
@Path("EntityParameter")
public class EntityParameter {
	@POST
	@Path("getFileBody")
	public String getFileBody(File fileBody) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileBody),"UTF-8"));
		String line=null;
		StringBuffer sb = new StringBuffer();
		while((line=br.readLine()) != null){
			sb.append(line);
		}
		return sb.toString();
	}
}

1.2.15.11. レスポンスの作成

リソースメソッドの処理が完了すると、リソースメソッドの戻り値の型によりHTTPレスポンスボディが生成されます。HTTPレスポンスボディに対応するJavaの型は提供するエンティティプロバイダに従います。 Javaの型に対応するエンティティプロバイダの詳細は表1.2.15.12-1を参照して下さい。 そのJavaの型のインスタンスが返却される時、カスタムエンティティプロバイダは必要ではありません。それらのJavaの型以外の型のインスタンスを返却する時、 カスタマイズエンティティプロバイダの作成が必要です。エンティティプロバイダの作成は [1.2.15.12. プロバイダ] を参照ください。 HTTPレスポンスメッセージにヘッダなどの情報を設定したい場合、JAX-RS APIに定義されているResponseクラスが使用できます。

内蔵エンティティプロバイダ対応するJavaの型
リソースメソッドの戻りの型が「void」である場合、リクエストが処理した後、エンティティが含まれないとレスポンスコードが204のHTTPレスポンスを返します。また、httpメソッドがGETの場合で戻りの型が「void」である場合、ログにINFOレベルで「A HTTP GET method,{メソッドのsignature}MUST return a non-void type.」というメッセージが出力されます。戻りの型が「void」以外である場合、HTTPレスポンスに対応するエンティティプロバイダが必要です。 表1.2.15.12-1のJavaの型のエンティティプロバイダを使用する場合、他のエンティティプロバイダを作成する必要がありません。

例:Javaの型(java.io.InputStream)の使用例
1.リソースクラス InputStreamResource を定義します。
@Path("/inputStreamRes")
public class InputStreamResource {
	private Map<String, String> fileRecord = new HashMap<String, String>();
	public InputStreamResource() {
		fileRecord.put("id1", "ファイルパス");
	}
	@GET
	@Path("/{fileId}")
	public InputStream getInputStream(@PathParam("fileId") String fileId) {
		FileInputStream inStream = null;
		String filePath = fileRecord.get(fileId);
		if (filePath != null) {
			try {
				inStream = new FileInputStream(filePath);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}
		return inStream;
	}
}
パスパラメータ「fileId」により、対応するFileファイルのInputStreamを取得して返却します。

2.クライアント側が「/inputStreamRes/id1」にアクセスすると、サーバ側はInputStreamのエンティティプロバイダ(InputStreamProvider)を利用して、InputStreamインスタンスをHTTPレスポンスに対応させて返信します。
Responseタイプ
HTTPレスポンスの返信時に、HTTPレスポンスメッセージの状態コード、MIMEタイプ、エンティティなどをカスタマイズしたい場合、JAX-RS APIに定義するjavax.ws.rs.core.Responseクラスが利用できます。APIの詳細はJAX-RSのJavaDocを参照ください。

下記はResponseの使用例です。
1.ルートリソースクラスResponseResourceを定義します。
@Path("ResponseResource")
public class ResponseResource {
    @GET
    @Path("helloworld")
    public Response getHelloWorldByResponse() {
	    String entityBody = "HelloWorld";
	    return Response.ok(entityBody, MediaType.TEXT_HTML_TYPE).build();
    }
}
2.クライアント側からGETで「/ResponseResource/helloworld」をリクエストすると、 サブリソーメソッドgetHelloWorldByResponse()はレスポンス状態コード「200」、MIMEタイプ「text/html」、エンティティ「HelloWorld」のレスポンスメッセージを返信します。
カスタムエンティティプロバイダ対応するJavaの型
リソースメソッドの戻り型はユーザ実装のJavaクラスが使用できます。その場合、HTTPレスポンスに対応するカスタムエンティティプロバイダを作成する必要があります。カスタムエンティティプロバイダ作成についての詳細は[1.2.15.12. プロバイダ]を参照ください。

1.2.15.12. プロバイダ

プロバイダはJSR311に定義する@Providerアノテーションで表記し、JSR311に定義するプロバイダインタフェースを実装するクラスです。プロバイダの機能はプロバイダの種類によって異なります。 プロバイダはエンティティプロバイダ、コンテキストプロバイダと例外マッピングプロバイダの三つの種類があります。

エンティティプロバイダと例外マッピングプロバイダは以下の図に示します。


図1.2.15.12-1

エンティティプロバイダ
エンティティプロバイダは下記の機能を提供します。 (1)の場合のプロバイダはMessageBodyReaderプロバイダを呼び出します。(2)の場合のプロバイダはMessageBodyWriterプロバイダを呼び出します。
内蔵エンティティプロバイダ
WebOTXではいくつかのJavaの型に対応するプロバイダを提供しています(内蔵エンティティプロバイダと呼びます)。エンティティパラメータあるいはリソースメソッドの返却値は内蔵エンティティプロバイダに対応するJavaの型の場合、それらのJavaの型に対してプロバイダを作成する必要はありません。 内蔵エンティティプロバイダに対応するJavaの型と対応のMIMEタイプは下記「表1.2.15.12-1」の説明を参照ください。リソースクラスは表にリストしたJavaの型以外の型を使用する場合、カスタマイズプロバイダを作成する必要があります。

  @Consumesと@ProducesのMIMEタイプの設定により、リクエストボディを以下のJavaの型に解析するプロバイダと、以下の型をレスポンスボディに解析するプロバイダを提供しています。   
表1.2.15.12-1
項番 Javaの型 Charset(※1) MIMEタイプ
1 byte[] × 任意(*/*)
2 java.lang.String 任意(*/*)
3 java.io.InputStream × 任意(*/*)
4 java.io.Reader 任意(*/*)
5 java.io.File(※2) × 任意(*/*)
6 javax.activation.DataSource × 任意(*/*)
7 javax.xml.transform.Source(※3) × text/xml、application/xml、application/*+xml
8 javax.xml.bind.JAXBElement text/xml、application/xml、application/*+xml
9 MultivaluedMap<String,String> application/x-www-form-urlencoded
10 StreamingOutput (※レスポンスのみ) × 任意(*/*)
11 java.awt.image.RenderedImage × image/*、application/octet-stream
12 org.w3c.dom.Document × pplication/xml、text/xml、*/*
13 com.nec.webotx.jersey.core.provider.EntityHolder<T> Tに指定した型と同じMIMEタイプになります。
14 XmlRootElementアノテーションおよび/またはXmlTypeアノテーションでアノテートされたJAXBクラス × text/xml、application/xml、application/*+xml
15 com.nec.webotx.jersey.api.representation.Form 任意(*/*)
16 javax.mail.internet.MimeMultipart multipart/*
17 JSONフォーマットのデータ形式 application/javascript、application/xml、text/xml
18 java.util.List<T>(※4) text/xml、application/xml、application/*+xml
19 void(レスポンスのみ) 任意(*/*)
20 javax.ws.rs.core.Response(※レスポンスのみ) 任意(*/*)
21 javax.ws.rs.core.GenericEntity<T>(※5) Tに指定した型と同じMIMEタイプになります。
上記のJavaの型とMIMEタイプを使用する場合、内蔵エンティティプロバイダを利用します。

(凡例)
  ○:サポートされているパラメータを示します。
  △:Tに指定した型と同じcharsetであることを示します。
  ×:未サポートのパラメータを示します。
  −:該当しないことを示します。
  任意(*/*):すべてのMIMEタイプをサポートしていることを示します。


※1
Producesアノテーションまたは戻り値にcharsetパラメータが含まれる場合、HTTPレスポンスに変換するときに、その情報がContent-Type HTTPヘッダのcharsetパラメータに反映されるかどうかを示します。
  ○:反映されます。Producesアノテーションおよび戻り値にcharsetパラメータが含まれない場合はUTF-8が仮定されます。
  ×:反映されません。

※2
リソースメソッドのパラメータがjava.io.Fileの場合、RESTful WebServiceで一時ファイルを作成する必要があります。一時ファイルの作成のディレクトリに書込みアクセス権がない場合、WebOTXのserver.logに「java.io.IOException:アクセスが拒否されました」という例外を出力します。

一時ディレクトリの例:

Windowsの場合: C:/Users/{コンピュータ名}/AppData/Local/Temp/

Linuxの場合: /tmp/

※3
次に示す実装クラスを使用できます。
※4
TにはXmlRootElementアノテーションでアノテートされたJAXBクラスを指定できます。

※5
Tにはこの表の項番21以外とエンティティプロバイダのみ以外の型を指定できます。
カスタムエンティティプロバイダ
ユーザ実装のJavaクラスを使用する場合、MessageBodyReaderインタフェースとMessageBodyWriterインタフェースの実装が必要になります。

    カスタムMessageBodyReaderエンティティプロバイダ

カスタムMessageBodyReaderエンティティプロバイダを作成するには、MessageBodyReaderインタフェースを実装し、アノテーション@Providerを付与します。
javax.ws.rs.ext.MessageBodyReader<T>インタフェースはJAX-RS APIに定義されているインタフェースです。
詳細は下表1.2.15.12-2に示します。
表1.2.15.12-2
メソッド 説明
boolean isReadable(java.lang.Class<?>, java.lang.reflect.Type , java.lang.annotation.Annotation[] , MediaType) MessageBodyReaderの実装クラスは特定のJavaタイプのインスタンスを作成できるかどうかを判断します。

true:作成できます。
false:作成できません。
T readFrom(java.lang.Class<T>,java.lang.reflect.Type, java.lang.annotation.Annotation[],MediaType, MultivaluedMap<java.lang.String,java.lang.String>,java.io.InputStream) InputStreamでTが指定するJavaタイプのインスタンスを作成して、返却します。isReadable()がtrueの場合のみ、そのメソッドをコールします。
下記の例はユーザ実装のJavaクラスのNamePasswordBeanのMessageBodyReaderエンティティプロバイダです。
 リソースクラスにNamePasswordBeanのインスタンスをエンティティパラメータあるいは返却値とする場合、そのプロバイダを利用します。
 
例:
  @Provider
 public class NamePasswordBeanReader implements MessageBodyReader<NamePasswordBean> {

	@Override
	public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2,MediaType arg3) {
		return arg0 == NamePasswordBean.class;
	}

	@Override
	public NamePasswordBean readFrom(Class<NamePasswordBean> arg0, Type arg1,Annotation[] arg2, MediaType arg3, MultivaluedMap<String, String> arg4, InputStream arg5) throws IOException, WebApplicationException {
		//NamePasswordBeanインスタンスを作成。
                ……
	}
}
 
プロバイダがリクエストから特定のMIMEタイプのエンティティのみ処理するには、クラスレベルで@Consumesアノテーションが必要になります。@Consumesアノテーションの値はプロバイダがサポートするMIMEタイプです。@Consumesアノテーションを設定しない場合、任意(*/*)のMIMEタイプになります。

(1)MessageBodyReaderエンティティプロバイダのマッチルール


複数のMessageBodyReaderエンティティプロバイダが存在する時、マッチルールによってプロバイダを検索します。

下記はマッチルールの概要説明です。
(1):HTTPリクエストから「Content-Type」ヘッダの値を取得します。取得できない場合、「application/octet-stream」とします。
(2):リソースメソッドに定義するリクエストエンティティボディから対応するJavaの型を取得します。
(3):(1)に取得するMIMEタイプをサポートするプロバイダの集合を取得します。

マッチルールは下記に従います。
「x/y < x/* < */*」 特定のMIMEタイプをサポートするプロバイダは、全てのMIMEタイプをサポートするプロバイダより判断(使用)を優先します。

(4):(3)から選択した毎プロバイダのisReadable()メソッドをコールし、「true」を返却するプロバイダを使用します。複数のプロバイダを定義し、それらのプロバイダがすべてisReadable()がtrueを返却する場合: Applicationを継承する場合、サブクラスに先に追加されたプロバイダを利用します。PackagesResourceConfigとcom.nec.webotx.jersey.config.property.packagesを利用する場合、クラス名のASC順で前のプロバイダを利用します。
(5):適当なプロバイダを選択できない場合は、例外が発生し、ログに「A message body reader for Java class {ユーザ実装のJavaクラス}, and Java type class {ユーザ実装のJavaクラス}, and MIME media type {MIMEタイプ} was not found」を出力します。HTTPステータスコード415が返されます。

    カスタムMessageBodyWriterエンティティプロバイダ
カスタムMessageBodyWriterエンティティプロバイダを作成するには、MessageBodyWriterインターフェイスの実装とアノテーション@Providerの付与が必要です。
javax.ws.rs.ext.MessageBodyWriter<T>インタフェースはJAX-RS APIに定義されているインタフェースです。

クラス名/インタフェース 説明
public interface MessageBodyWriter<T> -
メソッド -
boolean isWriteable(java.lang.Class<?>,java.lang.reflect.Type, java.lang.annotation.Annotation[], MediaType) MessageBodyWriterの実装クラスが特定のJavaタイプのインスタンスをHTTPレスポンスに変換できるかどうかを判断します。 true:変換できます。false:変換できません。
long getSize(T,java.lang.Class<?>,java.lang.reflect.Type, java.lang.annotation.Annotation[], MediaType) writeTo()メソッドをコールする前、TのインスタンスをHTTPレスポンスエンティティにシリアライズするバイトの長さが返却されます。 「-1」:全てのバイトの長さ
void writeTo(T,java.lang.Class<?>, java.lang.reflect.Type,java.lang.annotation.Annotation[], MediaType,MultivaluedMap<java.lang.String,java.lang.Object>, java.io.OutputStream) エンティティにシリアライズします。isWriteable()がtrueの場合のみ、そのメソッドをコールします。
下記の例はユーザ実装のJavaクラスであるNamePasswordBeanのMessageBodyWriterエンティティプロバイダです。
リソースクラスはNamePasswordBeanのインスタンスを返却する時、そのプロバイダが利用できます。
例:
 @Provider
public class NamePasswordBeanWriter implements MessageBodyWriter<NamePasswordBean> {

	@Override
	public long getSize(NamePasswordBean arg0, Class<?> arg1, Type arg2,Annotation[] arg3, MediaType arg4) {
		return -1;
	}

	@Override
	public boolean isWriteable(Class<?> classType, Type arg1, Annotation[] arg2,MediaType arg3) {
		return classType == NamePasswordBean.class;
	}

	@Override
	public void writeTo(NamePasswordBean arg0, Class<?> arg1, Type arg2,Annotation[] arg3, MediaType arg4,MultivaluedMap<String, Object> arg5, OutputStream arg6) throws IOException, WebApplicationException {
		// NamePasswordBeanのインスタンスをシリアライズするロジック
     …………
	}
}
 
そのプロバイダは特定のタイプのレスポンスボディを返す時、クラスレベルで@Producesアノテーションが必要になります。レスポンスを返信する時、@Producesアノテーションの値はレスポンスのコンテントタイプ(content-type)とします。@Producesアノテーションを設定しない場合、「All media type(*/*)」はレスポンスのコンテントタイプ(content-type)とします。

(1)MessageBodyWriterエンティティプロバイダのマッチルール


複数のMessageBodyWriterエンティティプロバイダが存在する時、マッチルールによってプロバイダの検索を行います。
下記はマッチルールの概要説明です。


XML
ユーザ実装のJavaクラスを使用する場合、カスタムエンティティプロバイダの作成が必要ですが、カスタムエンティティプロバイダを作成せずに、XMLデータ形式で送受信することもできます。この時、XMLデータ形式はJAXB (JSR 222 implementation)で扱います。
JAXBでXMLを扱う場合、2つの方法があります。1つは「JAXBアノテーション」を利用してJavaの型とXMLデータ形式を対応させます。
もう一つは「javax.xml.bind. JAXBElement<T>」クラスを利用して、Javaの型とXMLデータ形式を対応させます。

    JAXBアノテーション

ユーザ実装のJavaクラスにこのアノテーションを付与します。リソースメソッドの返却値あるいはエンティティパラメータは、このユーザ実装のJavaクラスを利用する場合、エンティティプロバイダを利用して、XMLデータ形式のリクエストボディからそのユーザ実装のJavaクラスのインスタンスに変換します。あるいは、そのユーザ実装のJavaクラスのインスタンスからXMLデータ形式のレスポンスボディに変換します。

下記にRESTful Webサービスの例で説明します。
(1)ユーザ実装のJavaクラスであるPlanetクラスを定義します。このクラスのインスタンスはリソースメソッドの返却値として、クライアント側へ返却します。
   @XmlRootElement
   public class Planet {
       public int id;
       public String name;
       public double radius;
   }
  
PlanetクラスにはJAXBに定義するアノテーションが使用できます。

(2)リソースクラスを定義。
   @Path("planet")
   public class Resource {
   
       @GET
       @Produces(MediaType.APPLICATION_XML)
       public Planet getPlanet() {
           Planet p = new Planet();
           p.id = 1;
           p.name = "Earth";
          p.radius = 1.0;  
          return p;
      }
 }
  
ResourceクラスにリソースメソッドgetPlanet()を定義する@Producesアノテーションを使用して「application/xml」を設定します。
クライアントがそのリソースをリクエストすると、下記のXMLがレスポンスボディとして返却されます。
  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <planet>
      <id>1</id>
      <name>Earth</name>
      <radius>1.0</radius>
   </planet>
  
  「JAXBアノテーション」方式を利用し、ユーザ実装のJavaクラスにJAXBに定義するアノテーションを付与した場合、リソースメソッドの@Producesアノテーションを使用してMIMEタイプを「text/xml、application/xml 、application/*+xml」に設定する必要があります。

  @Producesアノテーションを設定しない場合、デフォルトで「application/xml」が使用されます。

  他のMIMEタイプを設定した場合、例外が発生しログに「javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer(reader) for Java class {ユーザ実装のJavaクラス}, and Java type class {ユーザ実装のJavaクラス}, and MIME media type {設定したMIMEタイプ} was not found」が出力されます。

    JAXBElementクラス

JAXBアノテーションを使用せずJavaの型とXMLを対応するには、javax.xml.bind.JAXBElement<T>クラスを使用します。

下記の例で使用方法を説明します。
(1)ユーザ実装のJavaクラスであるPlanetクラスを定義します。このクラスのインスタンスはリソースメソッドの返却値として、クライアント側へ返却します。
   public class Planet {
       public int id;
       public String name;
       public double radius;
   }
  
(2)リソースクラスを定義します。
   @Path("planet")
   public class Resource {
       @GET
       @Produces(MediaType.APPLICATION_XML)
       public JAXBElement<Planet> getPlanet() {
           Planet p = new Planet();
           p.id = 1;
           p.name = "Earth";
          p.radius = 1.0;
  
          return new JAXBElement<Planet>(new QName(“myplanet”), Planet.class, p);
      }
   }
  
javax.xml.bind.JAXBElementを利用する場合、リソースメソッドgetPlanet()の返却値はJAXBElement<Planet>に変更してください。カスタムPlanetクラスのインスタンスを作成し、JAXBElementのコンストラクタのパラメータとして利用します。
JAXBElementのコンストラクタのパラメータQNameはXMLデータ形式のルート要素です。

クライアントへ返信するレスポンスボディを下記に示します。
  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <myplanet>
        <id>1</id>
        <name>Earth</name>
        <radius>1.0</radius>
    <myplanet>
  
リソースクラスにJAXBElement方式を使用する場合、@Producesアノテーションを使用してMIMEタイプを「text/xml、application/xml 、application/*+xml」に設定する必要があります。

@Producesアノテーションを設定しない場合、デフォルトで「application/xml」が使用されます。

他のMIMEタイプを設定すると、例外が発生しログに「javax.ws.rs.WebApplicationException: com.nec.webotx.jersey.api.MessageException: A message body writer(reader) for Java class javax.xml.bind.JAXBElement, and Java type javax.xml.bind.JAXBElement<ユーザ実装のJavaクラス >, and MIME media type {設定したMIMEタイプ} was not found」が出力されます。

JSON
JSONデータ形式で送受信する場合に、以下三つの方式が使用できます。

(1) POJO
(2) JAXB
(3) JSONObject/JSONArray

Caution
任意のメンバ変数がシリアライズできない場合、エラーとなり次の例外が発生します。「JsonMappingException: No serializer found for class {サブリソースロケータの情報} and no properties discovered to create BeanSerializer」。その変数を無視するのであれば、アノテーション「@JsonIgnoreProperties(value = {"hibernateLazyInitializer", "変数名"})」を使用してください。

    POJO

RESTful Webサービスを作成する際に、下記の設定が必要です。
(1)RESTful Webサービスのweb.xmlファイルに <servlet>に下記のパラメータ設定の追加が必要です。
     <init-param>
       <param-name>
            com.nec.webotx.jersey.api.json.POJOMappingFeature
       </param-name>
       <param-value>true</param-value>
   </init-param>
  
「POJOベース」のJSON表現を使用する場合、JSONWithPaddingクラスが使用できます。
JSONWithPaddingクラスの詳細は下記の表に示します。
クラス名 説明
com.nec.webotx.jersey.api.json. JSONWithPadding implements com.nec.webotx.org.codehaus.jackson.map.JsonSerializableWithType An entity supporting JSON with Padding (JSONP)
コンストラクタ -
public JSONWithPadding(Object jsonSource) Pad JSON using the default function name "callback".jsonSource: the JSON to pad.
public JSONWithPadding(Object jsonSource, String callbackName) Pad JSON using a declared callback function name.jsonSource: the JSON to pad.callbackName: the callback function name.
public void serialize(JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException JsonSerializableWithTypeインタフェースに定義するメソッド
public void serializeWithType(JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonProcessingException JsonSerializableWithTypeインタフェースに定義するメソッド

下記の例は「JSONP(JSON with Padding)」で「POJOベース」のJSON表現を説明します。
(1) POJOクラス「NonJAXBBean」を作成します
   public class NonJAXBBean {
    public String name = "non-JAXB-bean";
    public String description = "I am not a JAXB bean, just an unannotated POJO";
    public int[] array = {1, 1, 2, 3, 5, 8, 13, 21};
   }
  
(2) リソースクラス「NonJAXBBeanResource」を定義します
	import com.nec.webotx.jersey.api.json.JSONWithPadding;
	import javax.ws.rs.GET;
	import javax.ws.rs.Path;
	import javax.ws.rs.Produces;
	import javax.ws.rs.core.MediaType;

	@Path("/nonJAXBResource")
	public class NonJAXBBeanResource {

	    @GET 
	    @Produces({"application/javascript", MediaType.APPLICATION_JSON})
	    public JSONWithPadding getSimpleBeanJSONP() {
	        return new JSONWithPadding(new NonJAXBBean());
	    }
	}
  
リソースクラスNonJAXBBeanResourceのリソースメソッドgetSimpleBeanJSONP()はJSONWithPaddingインスタンスを返却します。


クライアント側は「/nonJAXBResource」が指定するリソースをリクエストする場合、下記のJSON表現でレスポンスボディを返信します。
  {"name":"non-JAXB-bean","description":"I am not a JAXB bean, just an unannotated POJO","array":[1,1,2,3,5,8,13,21]}
  
上記のリソースクラスNonJAXBBeanResourceのリソースメソッドgetSimpleBeanJSONP()には@Producesを指定します。指定するMIMEタイプはJSONに関連するMIMEタイプ(text/json、application/json)でなければなりません。

JSONに関連しないMIMEタイプを指定した場合、例外が発生しログに「javax.ws.rs.WebApplicationException: com.nec.webotx.jersey.api.MessageException:A message body writer for Java type, {ユーザ実装のJavaクラス}, and MIME media type, {指定するMIMEタイプ}, was not found. If you want to serialize a parametrized type, you might want to use GenericEntity」が出力されます。

@Producesを指定しない場合、リクエストの「Accept」ヘッダにより、関連するレスポンスメッセージを返信します。

    JAXB

JAXBを使用してデータ形式を取得する場合、ユーザ実装のJavaクラスにJAXBを定義するアノテーションが必要になります。リソースクラスにそのクラスのインスタンスを返却します。また、@ProducesアノテーションはJSONに関連するMIMEタイプ(application/json)を指定します。

下記例で説明します。
(1)ユーザ実装のJavaクラスにJAXBアノテーションを使用します。
   @XmlRootElement
   public class MyJaxbBean {
     public String name;
     public int age;
         
     public MyJaxbBean() {} // JAXB needs this default constructor
   
     public MyJaxbBean(String name, int age) {
       this.name = name;
      this.age = age;
    }
 }
  
(2)リソースメソッドにそのクラスのインスタンスが返却されます。@Producesに「application/json」を設定します。
   @GET @Produces("application/json")
   public MyJaxbBean getMyBean() {
      return new MyJaxbBean("Agamemnon", 32);
  }
  
(3)クライアント側からそのリソースをリクエストする時、下記のJSONデータ形式でレスポンスを返信します。
  {"name":"Agamemnon", "age":"32"}
  
リソースから返信するJSONデータ形式を変更するために、ContextResolver<T>インタフェースの実装が必要です。

ContextResolver<T>インタフェースを実装の例を下記に示します。
   @Provider
   public class JAXBContextResolver implements ContextResolver<JAXBContext> {
   
       private JAXBContext context;
       private Class[] types = {MyJaxbBean.class};
   
       public JAXBContextResolver() throws Exception {
           this.context = 
   	  new JSONJAXBContext( 
  	    JSONConfiguration.natural().build(), types); 
      }
       
      public JAXBContext getContext(Class<?> objectType) {
          for (Class type : types) {
              if (type == objectType) {
                  return context;
              }
          }
          return null;
      }
  }
  
ユーザ実装のJavaクラスであるMyJaxbBeanを解析する時、上記のJSONJAXBContextインスタンスを使用します。

上記の例にある「ContextResolver<T>」インタフェースはコンテキストプロバイダが定義するインタフェースです。コンテキストプロバイダの詳細は 下記の「コンテキストプロバイダ」を参照してください。

下記にJSONConfigurationクラスで使用できるJSON表現(JSON Notation)を説明します。 使用できるJSON表現は次の4つです。

?:MAPPED(default notation)
?:NATURAL
?:JETTISON_MAPPED
?:BADGERFISH

    下記の四つのNotationの設定オプションを説明するため、JAXB beansとリソースクラスを例とします。

JAXB beansクラス詳細:
	   @XmlRootElement
	   public class Address {
	       public String street;
	       public String town;
	   
	       public Address(){}
	   
	       public Address(String street, String town) {
	           this.street = street;
	          this.town = town;
	      }
	  }
   

Contactクラス詳細:

	   @XmlRootElement
	   public class Contact {
	       public int id;
	       public String name;
	       public List<Address> addresses;
	   
	       public Contact() {};
	   
	      public Contact(int id, String name, List<Address> addresses) {
	          this.name = name;
	          this.id = id;
	          this.addresses = 
	  	        (addresses != null) ? new LinkedList<Address>(addresses) : null;
	      }
	 }
   
リソースクラス詳細:
   @Path("/JAXBJSONResource")
   public class JAXBJSONResource {
	 @GET
	 @Produces("application/json")
	 public Contact getContact() {
		 Address[] addresses = new Address[]{new Address("Long Street 1", "Short Village")};
		 Contact contact = new Contact(2, "BOb", Arrays.asList(addresses));
		
		 return contact;
 	 }
   }
   

コンテキストプロバイダ詳細:

   @Provider
   public class JAXBContextResolver implements ContextResolver<JAXBContext> {
	  private JAXBContext context;
	  private Class[] types = {Contact.class};
	
	  public JAXBContextResolver() throws Exception {
		  this.context = new JSONJAXBContext(JSONConfiguration.mapped().build() // ※(1)
				 types);
	  }

	  public JAXBContext getContext(Class<?> type) {
		  for(Class supportType: types) {
			  if (type == supportType) {
				 return context;
			  }
		}
		return null;
	}
  }
   
※(1):「JSONConfiguration.mapped().build()」は、Notaionによりパラメータが異なります。

    Mapped Notation

    Mapped notationを使用したい場合、JSONConfigurationクラスのmapped()メソッドを使用する必要があります。 詳細は上記の例のJAXBContextResolverの※(1)で「JSONConfiguration.mapped().build()」を使用して下さい。
上記の例でMapped notationを使用する場合、JSONのデータ形式は下記に示します。
    { "id":"2" ,"name":"Bob","addresses":{"street":"Long Street 1","town":"Short Village"}}
   
下記はMapped notation でJSONConfigurationに関連する設定オプションを説明します。

(1)arrays(String... arrays)
上記の例におけるContactクラスの「addresses」はList型です。「addresses」に1つ以上の要素が存在する場合、JavaScriptに基づくクライアントは配列で「addresses」の要素を取得するため、例えばaddresses[0].townあるいはaddresses[1].town、JSONConfiguration の設定オプションarraysメソッドを使用します。

JAXBContextResolverの(*)(1)で「JSONConfiguration.mapped().arrays("addresses").build()」に変更します。arraysメソッドは繰り返し使用できます。例:

「JSONConfiguration.mapped().arrays("field1").arrays(“field2”).build()」あるいはarraysメソッドに複数の文字列が使用できます。例: 「JSONConfiguration.mapped().arrays("field1",“field2”).build()」

上記の二つの方式のJSONデータ形式は同じです。arraysメソッドを使用する場合のJSONデータ形式を下記に示します。
    {"id":"2","name":"BOb","addresses":[{"street":"Long Street 1" ,"town":"Short Village"}]}
    

(2)nonStrings(String... nonStrings)
上記の例ではContactクラスの「id」はInteger型です。デフォルトでJSONデータ形式に文字列として処理します。Integerで処理するにはJSONConfiguration の設定オプションnonStrings(String... nonStrings)が使用できます。

JAXBContextResolverの※(1)で「JSONConfiguration.mapped().nonStrings("id").build()」に変更します。JSONデータ形式は下記に示します。
    {"id":2 ,"name":"BOb","addresses":{"street":"Long Street 1","town":"Short Village"}}
    
また、nonStrings(String... nonStrings)メソッドに複数の文字列が使用できます。例:「JSONConfiguration.mapped().nonStrings("field1",”field2”).build()」。また、nonStrings(String... nonStrings)メソッドは繰り返し使用できます。例:「JSONConfiguration.mapped().nonStrings("field1").nonStrings("field2").build()」。

(3)attributeAsElement(String... attributeAsElements)
JAXB beansの変数にアノテーション「@XmlAttribute」を使用する時、その変数はJSONデータ形式の属性として表現されます。JSONデータ形式では、変数名の前に記号「@」を付加します。例として、上記のContactクラスの「id」変数にアノテーション「@XmlAttribute」を使用する場合:
	 ...
	 @XmlAttribute
	 public int id;
	 ...
    
JSONデータ形式は下記の通り表現されます。
    {"@id":"2" ...
    
上記の場合で出力内容に「@」記号を付けないためには、JSONConfiguration の設定オプションattributeAsElement(String... attributeAsElements)を使用します。 JAXBContextResolverの(1)で「JSONConfiguration.mapped().attributeAsElement("id").build()」に変更する必要があります。逆に出力内容に属性を表記する「@」記号を付与する場合、attributeAsElement(String... attributeAsElements)を使用しないでください。

(4)rootUnwrapping(boolean rootUnwrapping)
XMLドキュメントにはルート要素が必要ですが、JSONデータ形式ではルート要素が必要ではなく、デフォルトでルート要素がありません。JSONデータ形式でルート要素を追加するにはJSONConfiguration の設定オプションrootUnwrapping(boolean rootUnwrapping)が使用できます。メソッドのデフォルト値は「true」です。

JAXBContextResolverの※(1)で「JSONConfiguration.mapped().rootUnwrapping(false).build()」に変更します。JSONデータ形式は下記に示します。
    {"contact":{"id":"2","name":"BOb","addresses":{"street":"Long Street 1" ,"town":"Short Village"}}}
    
(5)xml2JsonNs(Map<String, String> jsonXml2JsonNs)
上記の例でContactクラスにJAXBのアノテーション「@XmlElement(namespace="namespace_value")」を使用する場合
	…
	@XmlElement(namespace="http://www.nec.cn.jersey")
	public List<Address> addresses;
	…
    
変数「addresses」は名前空間「http://www.nec.cn.jersey」を使用しています。クライアント側で変数「addresses」の値を正しく取得するためには、JSONにXML名前空間を付与します。JSONConfiguration の設定オプションxml2JsonNs(Map<String, String> jsonXml2JsonNs)を使用します。

上記のJAXBContextResolverのコンストラクタで下記のよう使用します。
	Map<String, String> ns2json = new HashMap<String, String>();
	ns2json.put("http://www.nec.cn.jersey", "addressesNS");
	this.context = new JSONJAXBContext(
	JSONConfiguration.mapped().xml2JsonNs(ns2json).build(), types);
    
JSONデータ形式を下記に示します。
  {"id":"2","name":"BOb","addressesNS.addresses":{"street":"Long Street 1" ,"town":"Short Village"}}
    
上記のデータ形式では、デフォルトで「.」で名前空間セパレーターとして使用しています。他のセパレーターに変更する場合は、「nsSeparator(Character separator)」を使用して下さい。

例:セパレータに「:」を使用する場合
    JSONConfiguration.mapped().xml2JsonNs(ns2json).nsSeparator(':').build()
    
JSONデータ形式を下記に示します。
    {"id":"2","name":"BOb","addressesNS:addresses":{"street":"Long Street 1","town":"Short Village"}}  
    

    Natural Notation

「Natural Notation」を使用する場合、「MappedNotation」のように設定オプションを配置する必要はありません。自動でJAXB beansの変数の型によって処理します。

例として、上記のContactクラスに変数「id」はInteger、変数「addresses」はListで、「Natural Notation」を使用する場合、自動でその変数の型によって処理します。

「Natural Notation」を使用する場合、JAXBContextResolverの※(1)で「JSONConfiguration.natural().build()」に変更します。JSONデータ形式は下記に示します。
    {"id":2,"name":"BOb","addresses":[{"street":"Long Street 1","town":"Short Village"}]}
   
(1)rootUnwrapping(boolean rootUnwrapping)

上記のMapped Notationの「rootUnwrapping(boolean rootUnwrapping)」メソッドと同じです。「Natural Notation」のrootUnwrapping(boolean rootUnwrapping)メソッドはJSONデータ形式でルート要素を追加するかどうかを設定します。 デフォルトは「true」になり、ルート要素を追加しません。「false」に設定する場合は、JAXBContextResolverの(1)で「JSONConfiguration.natural().rootUnwrapping(false).build()」に変更します。JSONデータ形式を下記に示します。
    {"contact":{"id":2,"name":"BOb","addresses":[{"street":"Long Street 1","town":"Short Village"}]}}
   
(2)usePrefixesAtNaturalAttributes()

「Natural Notation」の場合、JAXB beanにアノテーション「@XmlAttribute」を使用する際、JSONデータ形式に記号「@」を付加しません。 例として、Contactクラスの変数「id」に「@XmlAttribute」を付与した場合、
	……
	@XmlAttribute
	public int id;
	……
   
JSONデータ形式は下記に示します。
    {"id":2,"name":"BOb","addresses":[{"street":"Long Street 1","town":"Short Village"}]}
   
[id]は記号「@」を付与しません。記号「@」で付与したい場合、usePrefixesAtNaturalAttributes()メソッドを利用します。JAXBContextResolverの(1)で「JSONConfiguration.natural().usePrefixesAtNaturalAttributes().build()」に変更します。

JSONデータ形式は下記に示します。
   {"@id":2 ,"name":"BOb","addresses":[{"street":"Long Street 1","town":"Short Village"}]}
   

Mapped NotationとNatural Notationの処理の結果は次のとおりです。
Javaの型Mapped NotationNatural Notation備考
プリミティブとラッパクラス(int,short,long,float,double,byte,booleanを含む) int "2",float "-1.0",Double "1.0",booleanValue:"false" int 2,float -1.0,Double 1.0,booleanValue:false Mapped Notationは引用符で処理します; Natural Notationは引用符なしで処理します
ArrayList {"street":"Long Street 1","town":"Short Village"} [{"street":"Long Street 1","town":"Short Village"}] Natural Notationは”[ ]”の形式の配列で処理します
ArrayObject[]{101,true,'&'}); [{"@type":"xs:int","$":"101"},{"@type":"xs:boolean","$":"true"},{"@type":"xs:unsignedShort","$":"38"}] [{"type":"xs:int","$":"101"},{"type":"xs:boolean","$":"true"},{"type":"xs:unsignedShort","$":"38"}] Natural Notationを利用してもNaturalフォーマットにならない
カスタムオブジェクト {"contact":{"id":"3","doubleValue":"1.0"}} {"contact":{"id":3,"doubleValue":1.0}} Natural Notationはオブジェクト内的fieldに適用
Mapmap.put("name", "id").map.put("id", 1); {"map":{"entry":[{"key":{"@type":"xs:string","$":"id"},"value":{"@type":"xs:int","$":"1"}},{"key":{"@type":"xs:string","$":"name"},"value":{"@type":"xs:string","$":"id"}}]}} {"map":{"entry":{"key":{"type":"xs:string","$":"id"},"value":{"type":"xs:int","$":"1"}},"entry":{"key":{"type":"xs:string","$":"name"},"value":{"type":"xs:string","$":"id"}}}} Natural Notationを利用してもNaturalフォーマットになりません

    Jettison mapped Notation

JAXB beansに複数のXML名前空間がある場合、「Jettison mapped Notation」が使用できます。
「Jettison mapped Notation」の設定は「JSONConfiguration.mappedJettison().build()」です。使用は、JAXBContextResolverの※(1)で「JSONConfiguration.mappedJettison().build()」に変更します。JSONデータ形式は下記に示します。
     {"contact":{"id":2,"name":"BOb","addresses":{"street":"Long Street 1","town":"Short Village"}}}
    
上記のデータ形式で「Jettison mapped Notation」を使用する場合、「number」と「boolean」は「string」に変換しません。また、List型に1つの要素だけ存在する時、JSONデータ形式に配列として表現しません。複数の要素がある時、「Jettison mapped Notation」は自動で配列として表現します。

(1)xml2JsonNs(Map<String, String> jsonXml2JsonNs)

JAXB beansにXML名前空間がある場合、「Jettison mapped Notation」を使用できます。
例:Contactクラスに変数「id」は「XmlElement」アノテーションを付与する場合
	……
	@XmlElement(namespace="http://www.nec.cn.jersey")
	public int id;
	……
    
クライアント側で変数「id」の値にアクセスするには、JSONにXML名前空間の定義が必要です。JSONConfiguration の設定オプションxml2JsonNs(Map<String, String> jsonXml2JsonNs)が使用できます。 上記のJAXBContextResolverのコンストラクタに下記のように実装します。
	Map<String, String> ns2json = new HashMap<String, String>();
	ns2json.put("http://www.nec.cn.jersey", "idNS");
	this.context = new JSONJAXBContext(
	JSONConfiguration.mappedJettison().xml2JsonNs(ns2json).build(), types);
    
JSONデータ形式は下記に示します。
    {"contact":{"idNS.id":2,"name":"BOb","addresses":{"street":"Long Street 1" ,"town":"Short Village"}}
    

    Badgerfish Notation

「Badgerfish Notation」を使用するため、「JSONConfiguration.badgerFish().build()」を使用する必要があります。
JAXBContextResolverの(1)で「JSONConfiguration.badgerFish().build()」に変更します。JSONデータ形式は下記に示します。
   {"contact":{"id":2,"name":"BOb","addresses":{"street":"Long Street 1","town":"Short Village"}}}
  

JSONObject/JSONArray
JSONObjectとJSONArrayクラスを利用して、JSONデータ形式を変換します。

「JSONObject/JSONArray」の方式は上記の「JAXB」の方式より複雑になります。JSONObjectとJSONArrayのAPIは「http://www.json.org/java/index.html」を参照してください。

下記にJSONObjectクラスの使用例で説明します。
(1)POJOを定義します
   public class Contact {
  
       public int id;
       public String name;
        
       public Contact(int id, String name) {
           this.name = name;
           this.id = id;
          
      }
  }
  
(2)リソースを定義します
	 @Path("/JSONObject")
	 public class MyJSONObjectResource {
		@GET
		@Produces("application/json")
		public JSONObject getContact() {
			
			Contact contact = new Contact(2, "BOb");
			JSONObject jsonOb = new JSONObject();
			try {
				jsonOb.put("id", contact.id).put("name", contact.name);
			} catch (JSONException e) {
				e.printStackTrace();
			}
			return jsonOb;
		}
   }
  
クライアント側からそのリソースにアクセスした時に返却されるJSONデータ形式を下記に示します。
  {"id":2,"name":"BOb"}
  
コンテキストプロバイダ
コンテキストプロバイダはリソースクラスあるいはプロバイダのコンテキストを提供します。
カスタムコンテキストプロバイダを作成する時にはContextResolver<T>インターフェイスを実装する必要があります。また、アノテーション@Providerが必要になります。
javax.ws.rs.ext.ContextResolver<T>インタフェースはJAX-RS APIに定義するインタフェースです。
クラス名/インタフェース 説明
public interface ContextResolver<T> インタフェース
メソッド -
T getContext(java.lang.Class<?> type) Get a context of type T that is applicable to the supplied type.
下記はカスタムJAXB beansが使用するJAXBContextの例です。
    @Provider
   public class JAXBContextResolver implements ContextResolver<JAXBContext> {
   
       private JAXBContext context;
       private Class[] types = {MyJaxbBean.class};
   
       public JAXBContextResolver() throws Exception {
           this.context = 
   	  new JSONJAXBContext( 
  	    JSONConfiguration.natural().build(), types); 
      }
  
      public JAXBContext getContext(Class<?> objectType) {
          for (Class type : types) {
              if (type == objectType) {
                  return context;
              }
          }
          return null;
      }
 }
   
上記の例に、ユーザ実装のJavaクラスであるMyJaxbBeanのJAXBContextプロバイダを定義します。getContext(Class<?> objectType)メソッドではクラスを判断してカスタムJAXBContext返却します。
また、そのプロバイダは特定のMIMEタイプのみサポートする場合、クラスレベルでアノテーション「@Produces」を指定します。
     @Provider
     @Produces(“application/json”)
      public class JAXBContextResolver implements ContextResolver<JAXBContext> {
         ……
      }
   
「@Produces」を付与しない時、全てMIMEタイプをサポートすることを意味します。

注:一つのJavaTypeに対して、エンティティプロバイダとコンテキストプロバイダの両方が処理できる場合、エンティティプロバイダを利用します。
コンテキストプロバイダのマッチルール
コンテキストプロバイダを選択する時、プロバイダのMIMEタイプの設定により、処理必要なMIMEタイプがサポートするプロバイダを取得して、 サポートするMIMEタイプが「x/y < x/* < */*」の順でプロバイダをソートします。そのため特定のMIMEタイプで対応するプロバイダは全てMIMEタイプをサポートするプロバイダより判断(使用)を優先します。
例外マッピングプロバイダ
リソースクラスで例外が発生し、その情報をHTTPレスポンスとしてクライアントに返却する場合、HTTPレスポンスメッセージに対応するプロバイダ(例外マッピングプロバイダ)が必要になります。 例外マッピングプロバイダの作成詳細は下記の[「ExceptionMapperの使用」]を参照してください。

1.2.15.13. 異常の処理

リソースクラスはリクエスト処理時に異常が発生した場合、その情報をHTTPレスポンスとしてクライアント側に返却します。

例外クラスには2つの種類があり、1つはWebApplicationExceptionとそのクラスのサブクラス、もう1つはカスタム例外クラスです。下記にその二つの例外をレスポンスに変換するルールを説明します。
WebApplicationException
リソースクラスで異常が発生した時、その情報はHTTPレスポンスとしてクライアント側に返却するに例外クラスMapperを使用します。例えばクライアントで指定するURLにリソースが見つけられない場合、「404 not found」レスポンスを返信します。 その場合、javax.ws.rs.WebApplicationExceptionのサブクラスNotFoundExceptionを使用します。
 
 
 NotFoundExceptionの実装例を下記に示します。  
public class NotFoundException extends WebApplicationException {
   ……
   /**
     * Create a HTTP 404 (Not Found) exception.
     *
     * @param message the String that is the entity of the 404 response.
     */
    public NotFoundException(String message) {
        this(message, null);
    }

    /**
     * Create a HTTP 404 (Not Found) exception.
     *
     * @param message the String that is the entity of the 404 response.
     * @param notFoundUri the URI that cannot be found.
     */
    public NotFoundException(String message, URI notFoundUri) {
        super(Responses.notFound().
                entity(message).type("text/plain").build());
        this.notFoundUri = notFoundUri;
    }
   ……
}
javax.ws.rs.WebApplicationExceptionのサブクラスは以下のとおりです。
 
表1.2.15.13-1
異常クラス 説明
ConflictException Create a HTTP 409 (Conflict) exception.
NotFoundException Create a HTTP 404 (Not Found) exception.
ParamException An abstract extension of WebApplicationException for the class of parameter-based exceptions.
ParamException.PathParamException A URI-parameter-based exception for errors with PathParam.Contain a response with a 404 (Client error) status code.
ParamException.MatrixParamException A URI-parameter-based exception for errors with MatrixParam.Contain a response with a 404 (Client error) status code.
ParamException.QueryParamException A URI-parameter-based exception for errors with QueryParam.Contain a response with a 404 (Client error) status code.
ParamException.HeaderParamException A parameter exception for errors with HeaderParam.Contain a response with a 400 (Client error) status code.
ParamException.CookieParamException A parameter exception for errors with CookieParam.Contain a response with a 400 (Client error) status code.
ParamException.FormParamException A parameter exception for errors with FormParam.Contain a response with a 400 (Client error) status code.

また、javax.ws.rs.WebApplicationExceptionクラスも直接使用できます。
ExceptionMapperの使用
カスタム例外クラスを定義する場合、カスタム例外クラスはHTTPレスポンスに変換するプロバイダの定義が必要です。カスタム例外マッピングプロバイダを作成するには、javax.ws.rs.ext.ExceptionMapper<E extends Throwable>インタフェースを実装してください。また、アノテーション「@Provider」をクラスレベルで付与する必要があります。  
 
「404」レスポンスを返信する例外マッピングプロバイダの例は次のようになります。  
   @Provider
   public class EntityNotFoundMapper implements
           ExceptionMapper<EntityNotFoundException> {
       public Response toResponse(EntityNotFoundException ex) {
          return Response.status(404).
               entity(ex.getMessage()).
               type("text/plain").
              build();
       }
  }
  
 発生例外クラスの型とマッチする例外クラスMapperを使用しますが、一つの例外クラスに対して複数の例外クラスMapperがマッチした場合、以下の選択ルールにより例外クラスMapperを使用します。

1.2.15.14. warファイルの構成

RESTful Webサービスを含むwarファイルの構成について説明します。

warファイルの構成
次の表に示す構成にする必要があります。
表1.2.15.14-1
ディレクトリ 備考
/

META-INF/
MANIFEST.MF
WEB-INF/
web.xml 作成したweb.xmlです。
classes/ コンパイルしたJavaクラスを格納します。
lib/ コンパイルしたJavaクラスを含むJARファイルを格納します。
(凡例)
−:説明や補足事項が特にないことを示します。
ルートリソースクラスの作成
ルートリソースクラスは、コンパイルしたJavaクラスファイル(*.class)として作成します。必要に応じてサブリソースクラスや例外マッピングプロバイダも同様に作成します。

コンパイルしたJavaクラスファイル(*.class)は、warファイルを構成するディレクトリに含めます。次に示すどちらか、または両方に含めてください。 warファイルには、少なくとも一つ以上のルートリソースクラスが含まれる必要があります。
JAX-RS機能の配備
JAX-RS1.1がルートリソースクラスとプロバイダクラスを公開するための抽象クラスjavax.ws.rs.core.Applicationを継承し、カスタムApplicationを実装することができます。
表1.2.15.14-2
クラス名 説明
public class Application Defines the components of a JAX-RS application and supplies additional metadata. A JAX-RS application or implementation supplies a concrete subclass of this abstract class
フィールド -
private static final Set<Object> emptyObjectSet emptyObjectSet = Collections.emptySet()
private static final Set<Class<?>> emptyClassSet emptyClassSet = Collections.emptySet()
メソッド -
public Set<Class<?>> getClasses() Get a set of root resource and provider classes. The default lifecycle for resource class instances is per-request. The default lifecycle for providers is singleton
public Set<Object> getSingletons() Get a set of root resource and provider instances. Fields and properties of returned instances are injected with their declared dependencies Context by the runtime prior to use.

   下記はカスタムApplicationの例です。
      package com.nec.jersey.application;
      @ApplicationPath(“resources”)
      public class MyApplication extends Application {
        public Set<Class<?>> getClasses() {
            Set<Class<?>> s = new HashSet<Class<?>>();
            s.add(HelloWorldResource.class);
            return s;
        }
    }
    
その場合の@ApplicationPathに指定する値はweb.xmlの「url-pattern」の値と同じです。

  (2)、PackagesResourceConfigのサブクラスの場合 javax.ws.rs.core.ApplicationのサブクラスPackagesResourceConfigを実装し、そのクラスに指定するパッケージ名についてルートリソースクラスとプロバイダをスキャンできます。また、自動で指定するパッケージのサブパッケージにルートリソースクラスとプロバイダをスキャンできます。

以下はルートリソースクラスをパッケージ「com.nec.jersey.resource」に、プロバイダクラスをパッケージ「com.nec.jersey.providers」に配置した場合に、PackagesResourceConfigを利用して、ルートリソースクラスとプロバイダクラスをスキャンする例です。
    package com.nec.jersey.application;
    public class MyApplication extends PackagesResourceConfig {
        public MyApplication() {
            super("com.nec.jersey.resource;com.nec.jersey.providers");
        }
    }
    
 また、MyApplicationのコンストラクタに「super("com.nec.jersey");」を使用できます。 パッケージ「com.nec.jersey」のサブパッケージ「com.nec.jersey.resource」と「com.nec.jersey.providers」にルートリソースクラスとプロバイダクラスをスキャンできます。

※ web.xmlの設定は上記の(1)の「※」部分と同じです。

(3)、javax.ws.rs.core.Applicationのサブクラスが存在しない場合

  javax.ws.rs.core.Applicationのサブクラスが存在しない場合、web.xmlファイルの下記の配備設定を参照します。   
   <web-app>
       <servlet>
           <servlet-name>Jersey Web Application</servlet-name>
           <servlet-class>
             com.nec.webotx.jersey.spi.container.servlet.ServletContainer
           </servlet-class>
           <init-param>
               <param-name>
                 com.nec.webotx.jersey.config.property.packages
               </param-name>
               <param-value>com.nec.jersey.resource;com.nec.jersey.providers </param-value>
           </init-param>
           ...
      </servlet>
      ...
  </web-app>
  
  上記の「param-name」は「com.nec.webotx.jersey.config.property.packages」を設定する必要があります。「param-value」にはルートリソースクラスとプロバイダクラスのパッケージ名を設定します。2つ以上のパッケージ名を含む場合、記号「;」で区切ります。

1.2.15.15. WADL

WADLの概要
WADLはWeb Application Description Languageの略称です。対応しているWADLのバージョンは「Web Application Description Language W3C Member Submission 31 August 2009」です。 JAX-RS機能にはWADLファイル生成のみを提供します。リソースのWADLファイルの取得方法は「使用例の説明」を参照して下さい。

W3CのWADL仕様にはユーザが定義したリソースの情報を表示するため、いくつかの要素を定義しています。各要素の詳細は「http://www.w3.org/Submission/wadl/」を参照して下さい。下記はWADLの基本要素の概要の説明です。
表1.2.15.15-1
要素 説明 仕様章節
application the root element of a WADL description 2.2 Application
doc application」element can have one or more child doc elements that can be used to document that element. this element has two attributes: (1):xml:lang (2):title 2.3 Documentation
grammars The grammars element acts as a container for definitions of the format of data exchanged during execution of the protocol described by the WADL document 2.4 Grammars
resources The resources element acts as a container for the resources provided by the application. 2.5 Resources
resource A resource element describes a set of resources, each identified by a URI that follows a common pattern. 2.6 Resource
resource_type A resource_type element describes a set of methods that, together, define the behavior of a type of resource. 2.7 Resource Type
method A method element describes the input to and output from an HTTP protocol method that may be applied to a resource. 2.8 Method
request A request element describes the input to be included when applying an HTTP method to a resource. 2.9 Request
response A response element describes the output that results from performing an HTTP method on a resource. 2.10 Response
representation A representation element describes a representation of a resource's state. 2.11 Representation
param A param element describes a parameterized component of its parent element. 2.12 Parameter
使用例の説明
リソースクラスからWADLファイルが作成できます。
クライアント側で下記のURLでリソースのWADLファイルを取得できます。

URL:http://{server-name}:{port}/{context-root}/{url-pattern}/application.wadl

下記の例で説明します。
  @Path("wadlResource")
  public class WADLResource {
	 @GET
	 public String executeGetRequest() {
		//do something
		return "success";
	 }
	 @POST
	 public String executePostRequest() {
		//do something
		return "success";
	 }
  }
  
web.xmlファイルに関連する設定は下記に示します。
  <web-app ……>
     ……
    <servlet>
  	   <servlet-name>wadlTest</servlet-name>
	   <servlet-class>
         com.nec.webotx.jersey.spi.container.servlet.ServletContainer
       </servlet-class>
  	    ……
    </servlet>
    <servlet-mapping>
  	   <servlet-name>wadlTest</servlet-name>
  	   <url-pattern>/jersey/*</url-pattern>
    </servlet-mapping>
    ……
  </web-app>
  
クライアント側でURL:「http://{server-name}:{port}/{context-root}/jersey/application.wadl」にアクセスする時、下記のWADLファイルを取得できます。
  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
   <application xmlns="http://wadl.dev.java.net/2009/02">
     <doc xmlns:jersey=http://jersey.java.net/ …… />
     <grammars/>
     <resources base="http://{server-name}:{port}/{context-root}/{url-pattern}/">
         <resource path="wadlResource">
             <method id="executeGetRequest" name="GET">
                <response>
                    <representation mediaType="*/*"/>
                </response>
             </method>
             <method id="executePostRequest" name="POST">
                 <response>
                     <representation mediaType="*/*"/>
                 </response>
             </method>
         </resource>
     </resources>
    </application>