JAX-RS仕様に従った代表的なアプリケーション作成方法について説明します。詳細については、JAX-RS仕様およびJava EE仕様を参照してください。
JAX-RSアプリケーションのコーディング
JAX-RSアプリケーションの作成時には、以下の2種類のクラスをコーディングします。
Applicationサブクラス
リソースクラス
1. Applicationサブクラスの作成
Applicationサブクラスはjavax.ws.rs.core.Applicationクラスを継承したクラスで、一つのApplicationサブクラスが一つのJAX-RSアプリケーションを表現します。配備するモジュールにApplicationサブクラスが存在する場合、モジュール内のリソースクラスが検索され、Webリソースとして公開されます。
Applicationサブクラスは以下のように作成します。
javax.ws.rs.core.Applicationクラスを継承します。
クラスに対し@javax.ws.rs.ApplicationPathアノテーションを宣言し、JAX-RSアプリケーションのルートパスをWebアプリケーションのコンテキストルートからの相対パスとして記載します。
(必要な場合) getClassesやgetSingletonsメソッドをオーバーライドし、公開対象のリソースクラスを指定します。指定がない場合や、getClassesやgetSingletonsメソッドをオーバーライドしない場合は、モジュールに含まれるすべてのリソースクラスが公開対象になります。
例
Applicationサブクラスの作成例
@ApplicationPath("samples") public class JAXRSSampleApplication extends Application{ }
上記の例では、JAXRSSampleApplicationクラスはApplicationクラスのメソッドをオーバーライドしていないため、warファイルに含まれるすべてのリソースがこのJAX-RSアプリケーションのリソースとして公開されます。また、Webアプリケーションのコンテキストルート/samples配下のパスへのHTTPリクエストが、公開するリソースクラスに振り分けられます。
2.リソースクラスの作成
リソースクラスはWebリソースを表現したJavaクラスです。以下のようにして作成します。
@javax.ws.rs.Pathアノテーションをクラスに宣言し、JAX-RSアプリケーションのルートパスからの相対パスを指定します。
リソースメソッドを実装します。リソースメソッドはリクエストの処理を行うメソッドで、以下のように実装します。
@javax.ws.rs.GET、@javax.ws.rs.POSTなどのアノテーションを宣言して、HTTPリクエストメソッドと関連付けます。
必要に応じて@javax.ws.rs.Consumesアノテーションを宣言して、メソッドが処理可能なMIME型を宣言します。
必要に応じて@javax.ws.rs.Producesアノテーションを宣言して、メソッドがクライアントに返却するレスポンスデータのMIME型を宣言します。
必要に応じて@Pathアノテーションを宣言します。リソースメソッドに@Pathが宣言されている場合は、リソースクラスに定義した値の後ろにリソースメソッドに定義した値を連結したパスが、メソッドのアクセスURLとなります。
リクエストURLの一部をパラメーターとして利用する場合は、@Pathの値に"{id}"のように中括弧で囲まれた文字列(テンプレート変数)を含めます。テンプレート変数は"/"を含まない任意の文字列を表し、リクエストURLのうち、テンプレート変数に該当する値を@javax.ws.rs.PathParamアノテーションを付与した引数などから参照できます。
例
リソースクラスの作成例
@Path("/resource") public class SampleResource{ @GET @Produces("text/html") public String getResource(){ return "<html><body><p>Hello JAXRS</p></body></html>"; } }
リクエストURLの一部をパラメーターとして扱う場合のリソースクラスの作成例
@Path("/colors") public class ColorResource { @GET @Path("{colorName}") @Produces("text/html") public String getColorInfo(@PathParam("colorName") String name) { return "<html><body><p>Color name: " + name + "</p></body></html>"; } }
JAX-RSアプリケーションのモジュール作成
JAX-RSアプリケーションはWebアプリケーションの一部として、Servlet 3.0形式のWARモジュールに含めて配備します。作成したApplicationサブクラスやリソースクラスをWARファイルに含めて配備してください。
例
JAXーRSアプリケーションを含んだWARモジュールのファイル構成例
/ META-INF/ MANIFEST.MF WEB-INF/ classes/ jaxrssample/ ColorResource.class JAXRSSampleApplication.class SampleResource.class
アクセスURLについて
JAX-RSのリソースのアクセスURLは以下のように決まります。パスの区切り文字"/"は、必要に応じて追加、削除されます。
http://ホスト:ポート/コンテキストルート/Applicationサブクラスの@ApplicationPath値/リソースクラスの@Path値(/リソースメソッドの@Path値) |
「JAX-RSアプリケーションのコーディング」の例のApplicationサブクラスとリソースクラスを用いた場合、以下のURL にHTTP GETメソッドでリクエストを送信することで、SampleResourceクラスのgetResource()メソッドが呼び出されます。
http://ホスト:ポート/コンテキストルート/samples/resource |
また、以下のURL にHTTP GETメソッドでリクエストを送信することで、ColorResourceクラスのgetColorInfo()メソッドが呼び出されます。
http://ホスト:ポート/コンテキストルート/samples/colors/<"/"を含まない任意の文字列> |
注意
上記の例では説明のため簡略化していますが、実業務においてはクロスサイトスクリプティング対策、文字エンコーディング等の考慮を行う必要があります。
同様に、アプリケーション内のリソースへの意図しないURLパターンやHTTPメソッドによるアクセスを許可しないよう、Web application deployment descriptor(web.xml)に適切なセキュリティ設定を行うなどの考慮も行なってください。
デフォルトでは、リソースクラスのインスタンスはリクエスト毎に生成されます。単一のインスタンスですべてのリクエストを処理したい場合は、ApplicationサブクラスでgetSingletons()メソッドを実装し、当該のインスタンスを格納したSetオブジェクトを返却するようにしてください。
@Consumes や@Producesの値として使用可能なMIME型については「JAX-RSアプリケーションで利用できる標準のデータ型」を参照してください。
JAX-RSアプリケーションにはwarファイル内にApplicationサブクラスが存在するか、deployment descriptorにJAX-RSアプリケーションの定義が存在している必要があります。これらが存在しない場合はモジュール内のリソースクラスは無視され、公開されません。deployment descriptorによるJAX-RSアプリケーションの定義方法はJAX-RS仕様を参照してください。
Applicationサブクラスを含むモジュールを配備した場合、asadmin list-sub-componentsコマンドを実行するとApplicationサブクラスのクラス名がコンポーネントとして表示されます。コンポーネントの型は<JSP>と表示されます。
JAX-RSアプリケーションで利用できる標準のデータ型
本製品では、JAX-RS仕様で標準サポートされている以下のJavaクラスとMIMEメディアタイプ(MIME型)の組み合わせが標準で利用できます。
Javaクラス | MIME型 |
---|---|
byte[] | */* |
java.lang.String | */* |
java.io.InputStream | */* |
java.io.Reader | */* |
java.io.File | */* |
javax.activation.DataSource | */* |
javax.xml.transform.Source | text/xml,application/xml,application/*+xml |
java.xml.bind.JAXBElement @XmlRootElementを宣言したクラス | text/xml,application/xml,application/*+xml |
javax.ws.rs.core.MultivaluedMap<String,String> | application/x-www-form-urlencoded |
javax.ws.rs.core.StreamingOutput | */* |
*は任意のMIMEタイプ/サブタイプを表します。
上記以外の組み合わせを利用する場合は、javax.ws.rs.ext.Interface.MessageBodyReaderインターフェースやjavax.ws.rs.ext.Interface.MessageBodyWriterインターフェースを実装したJAX-RSエンティティプロバイダーを作成し、アプリケーションに含めてください。JAX-RSエンティティプロバイダーの詳細については、JAX-RS仕様を参照してください。
注意
javax.ws.rs.core.StreamingOutputクラスはレスポンス返却時のみ利用できます。
javax.xml.transform.Sourceクラスはレスポンス返却時のみ利用できます。リクエスト受信時に利用する場合は、Sourceクラスの代わりに以下のいずれかのクラスをリソースメソッドの引数に指定してください。
javax.xml.transform.stream.StreamSource
javax.xml.transform.sax.SAXSource
javax.xml.transform.dom.DOMSource
javax.xml.bind.JAXBElementクラスはJAXBElement<BeanClass>のように、型パラメーターを指定して利用する必要があります。
javax.xml.bind.JAXBElementクラスをCollection型の型パラメーターとして利用することで、複数の値を含んだXMLを扱うことができます。以下のCollection型が利用可能です。
java.util.ArrayList、または継承したクラス
java.util.LinkedList、または継承したクラス
java.util.HashSet、または継承したクラス
java.util.TreeSet、または継承したクラス
java.util.Stack、または継承したクラス
java.util.Collectionを実装し、かつpublicなコンストラクタを持つクラス
記載例は以下のとおりです。
java.util.ArrayList<JAXBElement<BeanClass>>
@XmlRootElementを宣言したクラスは、JAXBによって適切に変換可能なクラスである必要があります。
@Consumesや@Producesアノテーションを省略した場合は、"*/*"を指定した場合と同等の扱いとなります。
@Consumesに"*/*"が指定された場合、レスポンスメッセージに設定されるContent-Typeヘッダーの値はリクエストメッセージのAcceptヘッダーやメソッドの返り値のオブジェクト型などから決定されます。詳細はJAX-RS仕様を参照してください。
リクエスト受信時にjava.io.Fileクラスを使用する場合は、システムプロパティjava.io.tmpdirにセットされたディレクトリに次の命名規則でファイルが作成され、作成されたファイルを参照するオブジェクトがアプリケーションに渡されます。
rep*****tmp
*****の部分は任意の数字です。
ファイルの作成場所には、呼量とファイルサイズに応じて十分なディスク容量を確保してください。また、アプリケーションでの利用終了後はdeleteメソッドを呼び出すなどしてファイルを削除してください。
JAX-RSランタイムがFileオブジェクトを生成してからアプリケーションがファイルを削除するまでの間に、予期しない例外が発生したりJavaプロセスが異常終了した場合、ファイルは削除されずに残ることがあります。その場合は、上記ファイルがどのプロセスからも使用されていないことを確認後、手動で削除してください。
java.io.tmpdirをデフォルトの値から変更してサーバーインスタンスを運用する場合は、プロセスの実行ユーザに書き込み権限があることを確認してください。
その他の注意事項
クライアントから大きなサイズのデータを受信して処理を行う場合、データ型やヒープのサイズによっては処理中にメモリ不足になる可能性があります。必要に応じてServletFilterなどを実装し、JAX-RSアプリケーションのサーブレットが受信する入力ストリームのサイズを制限するなどの対策を講じてください。