第18章 JAX-RS エンドポイントの設定
概要
この章では、Blueprint XML および Spring XML で JAX-RS サーバーエンドポイントをインスタンス化および設定する方法と、XML で JAX-RS クライアントエンドポイント (クライアントプロキシー Bean) をインスタンス化および設定する方法を説明します。
18.1. JAX-RS サーバーエンドポイントの設定
18.1.1. JAX-RS サーバーエンドポイントの定義
基本のサーバーエンドポイント定義
XML で JAX-RS サーバーエンドポイントを定義するには、少なくとも以下の項目を指定する必要があります。
-
XML でエンドポイントを定義するために使用される
jaxrs:server
要素。jaxrs:
namespace 接頭辞は、ブループリントと Spring の異なる名前空間にそれぞれマッピングされることに注意してください。 jaxrs:server
要素のaddress
属性を使用した JAX-RS サービスのベース URL。アドレス URL を指定する方法は 2 つあり、エンドポイントのデプロイ方法に影響を与えることに注意してください。相対 URL(例:
/customers
)。この場合、エンドポイントはデフォルトの HTTP コンテナーにデプロイされ、エンドポイントのベース URL は、CXF サーブレットのベース URL と指定された相対 URL を組み合わせることによって暗黙的に取得されます。たとえば、JAX-RS エンドポイントを Fuse コンテナーにデプロイする場合、指定の
/customers
URL は URLhttp://Hostname:8181/cxf/customers
に解決されます (コンテナーがデフォルトの8181
ポートを使用していることを前提とします)。-
http://0.0.0.0:8200/cxf/customers
のように、絶対 URL を指定 (例: ) として。この場合、JAX-RS エンドポイント用に新しい HTTP リスナーポートが開かれます (まだ開いていない場合)。たとえば、Fuse のコンテキストでは、JAX-RS エンドポイントをホストするために新しい Undertow コンテナーが暗黙的に作成されます。特別な IP アドレス0.0.0.0
は、現在のホストに割り当てられたホスト名のいずれかに一致するワイルドカードとして機能します (マルチホームホストマシンで役に立ちます)。
-
JAX-RS サービスの実装を提供する 1 つ以上の JAX-RS ルートリソースクラス。リソースクラスを指定する最も簡単な方法は、
jaxrs:serviceBeans
要素内にリソースクラスをリスト表示することです。
Blueprint の例
以下の Blueprint XML の例は、(デフォルトの HTTP コンテナーにデプロイするように) 相対アドレス /customers
を指定し、service.CustomerService
リソースクラスによって実装される、JAX-RS エンドポイントを定義する方法を示しています。
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs" xmlns:cxf="http://cxf.apache.org/blueprint/core" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd "> <cxf:bus> <cxf:features> <cxf:logging/> </cxf:features> </cxf:bus> <jaxrs:server id="customerService" address="/customers"> <jaxrs:serviceBeans> <ref component-id="serviceBean" /> </jaxrs:serviceBeans> </jaxrs:server> <bean id="serviceBean" class="service.CustomerService"/> </blueprint>
Blueprint XML 名前空間
ブループリントで JAX-RS エンドポイントを定義するには、通常、少なくとも次の XML 名前空間が必要です。
接頭辞 | Namespace |
---|---|
(デフォルト) | |
| |
|
Spring の例
以下の Spring XML の例は、相対アドレス /customers
(デフォルトの HTTP コンテナーにデプロイされるように) を指定し、service.CustomerService
リソースクラスによって実装される JAX-RS エンドポイントを定義する方法を示しています。
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> <jaxrs:server id="customerService" address="/customers"> <jaxrs:serviceBeans> <ref bean="serviceBean"/> </jaxrs:serviceBeans> </jaxrs:server> <bean id="serviceBean" class="service.CustomerService"/> </beans>
Spring XML 名前空間
Spring で JAX-RS エンドポイントを定義するには、通常、少なくとも次の XML 名前空間が必要です。
接頭辞 | Namespace |
---|---|
(デフォルト) | |
| |
|
Spring XML の自動検出
(Spring only) JAX-RS ルートリソースクラスを明示的に指定する代わりに、Spring XML では自動検出を設定できます。これにより、特定の Java パッケージでリソースクラス (@Path
によりアノテーションが付けられたクラス) が検索され、検出されたすべてのリソースクラスがエンドポイントに自動的に割り当てられます。この場合、jaxrs:server
要素に address
属性と basePackages
属性のみを指定する必要があります。
たとえば、a.b.c
Java パッケージ下のすべての JAX-RS リソースクラスを使用する JAX-RS エンドポイントを定義するには、以下のように Spring XML でエンドポイントを定義できます。
<jaxrs:server address="/customers" basePackages="a.b.c"/>
自動検出メカニズムは、指定された Java パッケージで検出した JAX-RS プロバイダークラスも検出してエンドポイントにインストールします。
Spring XML でのライフサイクル管理
(Spring のみ) Spring XML では、bean
要素の scope
属性を設定することで、Bean のライフサイクルを制御できます。Spring では以下のスコープ値がサポートされます。
singleton
- (デフォルト) 単一の Bean インスタンスを作成します。これはどこでも使用され、Spring コンテナーの存続期間全体にわたって持続します。
prototype
-
Bean が別の Bean に注入されるたびに、または Bean レジストリーで
getBean()
を呼び出して Bean を取得する際に、新しい Bean インスタンスを作成します。 request
- (Web 対応コンテナーでのみ使用可能) Bean で呼び出されるすべての要求に対して新しい Bean インスタンスを作成します。
session
- (Web 対応コンテナーでのみ使用可能) 単一の HTTP セッションの存続期間中、新しい Bean を作成します。
globalSession
- (Web 対応コンテナーでのみ使用可能) ポートレット間で共有される単一の HTTP セッションの存続期間中、新しい Bean を作成します。
Spring スコープの詳細は、Bean スコープ に関する Spring フレームワークのドキュメントを参照してください。
jaxrs:serviceBeans
要素を使用して JAX-RS リソース Bean を指定すると、Spring スコープ が正しく機能しない ことに注意してください。この場合、リソース Bean で scope
属性を指定すると、scope
属性を効果的に無視されます。
Bean スコープを JAX-RS サーバーエンドポイント内で適切に機能させるには、サービスファクトリーによって提供される間接化のレベルが必要です。Bean スコープを設定する最も簡単な方法は、以下のように jaxrs:server
要素で beanNames
属性を使用してリソース Bean を指定することです。
<beans ... > <jaxrs:server id="customerService" address="/service1" beanNames="customerBean1 customerBean2"/> <bean id="customerBean1" class="demo.jaxrs.server.CustomerRootResource1" scope="prototype"/> <bean id="customerBean2" class="demo.jaxrs.server.CustomerRootResource2" scope="prototype"/> </beans>
前述の例では、customerBean1
と customerBean2
の 2 つのリソース Bean を設定します。beanNames
属性は、リソース Bean ID のスペース区切りリストとして指定されます。
最終的な柔軟性を高めるために、jaxrs:serviceFactories
要素を使用して JAX-RS サーバーエンドポイントを設定する際に、サービスファクトリーオブジェクトを 明示的 に定義することができます。このより冗長なアプローチには、デフォルトのサービスファクトリー実装をカスタム実装に置き換えることができるという利点があります。これにより、Bean のライフサイクルを最終的に制御できます。以下の例は、このアプローチを使用して、2 つのリソース Bean (customerBean1
と customerBean2
) を設定する方法を示しています。
<beans ... > <jaxrs:server id="customerService" address="/service1"> <jaxrs:serviceFactories> <ref bean="sfactory1" /> <ref bean="sfactory2" /> </jaxrs:serviceFactories> </jaxrs:server> <bean id="sfactory1" class="org.apache.cxf.jaxrs.spring.SpringResourceFactory"> <property name="beanId" value="customerBean1"/> </bean> <bean id="sfactory2" class="org.apache.cxf.jaxrs.spring.SpringResourceFactory"> <property name="beanId" value="customerBean2"/> </bean> <bean id="customerBean1" class="demo.jaxrs.server.CustomerRootResource1" scope="prototype"/> <bean id="customerBean2" class="demo.jaxrs.server.CustomerRootResource2" scope="prototype"/> </beans>
シングルトン以外のライフサイクルを指定する場合は、org.apache.cxf.service.Invoker Bean を実装および登録することが推奨されます (インスタンスは jaxrs:server/jaxrs:invoker
要素から参照して登録できます)。
WADL ドキュメントの添付
任意で、jaxrs:server
要素の docLocation
属性を使用して、WADL ドキュメントを JAX-RS サーバーエンドポイントに関連付けることができます。以下に例を示します。
<jaxrs:server address="/rest" docLocation="wadl/bookStore.wadl"> <jaxrs:serviceBeans> <bean class="org.bar.generated.BookStore"/> </jaxrs:serviceBeans> </jaxrs:server>
スキーマ検証
外部 XML スキーマがある場合、JAX-B 形式のメッセージコンテンツを記述するため、これらの外部スキーマを jaxrs:schemaLocations
要素を介して JAX-RS サーバーエンドポイントに関連付けることができます。
たとえば、サーバーエンドポイントを WADL ドキュメントに関連付けており、着信メッセージのスキーマ検証も有効にする場合は、次のように関連付けられた XML スキーマファイルを指定できます。
<jaxrs:server address="/rest" docLocation="wadl/bookStore.wadl"> <jaxrs:serviceBeans> <bean class="org.bar.generated.BookStore"/> </jaxrs:serviceBeans> <jaxrs:schemaLocations> <jaxrs:schemaLocation>classpath:/schemas/a.xsd</jaxrs:schemaLocation> <jaxrs:schemaLocation>classpath:/schemas/b.xsd</jaxrs:schemaLocation> </jaxrs:schemaLocations> </jaxrs:server>
あるいは、特定のディレクトリーのスキーマファイル *.xsd
をすべて含める場合は、以下のようにディレクトリー名を指定するだけです。
<jaxrs:server address="/rest" docLocation="wadl/bookStore.wadl"> <jaxrs:serviceBeans> <bean class="org.bar.generated.BookStore"/> </jaxrs:serviceBeans> <jaxrs:schemaLocations> <jaxrs:schemaLocation>classpath:/schemas/</jaxrs:schemaLocation> </jaxrs:schemaLocations> </jaxrs:server>
この方法でスキーマを指定すると、一般に、JAX-B スキーマへのアクセスを必要とするあらゆる種類の機能に役立ちます。
データバインディングの指定
jaxrs:dataBinding
要素を使用して、リクエストおよびリプライメッセージのメッセージボディーをエンコードするデータバインディングを指定できます。たとえば、JAX-B データバインディングを指定するには、次のように JAX-RS エンドポイントを設定できます。
<jaxrs:server id="jaxbbook" address="/jaxb"> <jaxrs:serviceBeans> <ref bean="serviceBean" /> </jaxrs:serviceBeans> <jaxrs:dataBinding> <bean class="org.apache.cxf.jaxb.JAXBDataBinding"/> </jaxrs:dataBinding> </jaxrs:server>>
または、Aegis データバインディングを指定するには、JAX-RS エンドポイントを次のように設定できます。
<jaxrs:server id="aegisbook" address="/aegis"> <jaxrs:serviceBeans> <ref bean="serviceBean" /> </jaxrs:serviceBeans> <jaxrs:dataBinding> <bean class="org.apache.cxf.aegis.databinding.AegisDatabinding"> <property name="aegisContext"> <bean class="org.apache.cxf.aegis.AegisContext"> <property name="writeXsiTypes" value="true"/> </bean> </property> </bean> </jaxrs:dataBinding> </jaxrs:server>
JMS トランスポートの使用
HTTP の代わりに JMS メッセージングライブラリーをトランスポートプロトコルとして使用するように JAX-RS を設定することができます。JMS 自体はトランスポートプロトコルでは ない ため、実際のメッセージングプロトコルは設定する特定の JMS 実装によって異なります。
たとえば、次の Spring XML の例は、JMS トランスポートプロトコルを使用するように JAX-RS サーバーエンドポイントを設定する方法を示しています。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jms="http://cxf.apache.org/transports/jms" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xsi:schemaLocation=" http://cxf.apache.org/transports/jms http://cxf.apache.org/schemas/configuration/jms.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/> <bean id="ConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:${testutil.ports.EmbeddedJMSBrokerLauncher}" /> </bean> <jaxrs:server xmlns:s="http://books.com" serviceName="s:BookService" transportId= "http://cxf.apache.org/transports/jms" address="jms:queue:test.jmstransport.text?replyToName=test.jmstransport.response"> <jaxrs:serviceBeans> <bean class="org.apache.cxf.systest.jaxrs.JMSBookStore"/> </jaxrs:serviceBeans> </jaxrs:server> </beans>
前の例について、次の点に注意してください。
-
JMS 実装: JMS 実装は
ConnectionFactory
Bean によって提供され、Apache ActiveMQ 接続ファクトリーオブジェクトをインスタンス化します。接続ファクトリーをインスタンス化すると、デフォルトの JMS 実装レイヤーとして自動的にインストールされます。 -
JMS コンジットまたはデスティネーションオブジェクト:Apache CXF は、JMS コンジットオブジェクト (JMS コンシューマーを表すため) または JMS デスティネーションオブジェクト (JMS プロバイダーを表すため) を暗黙的にインスタンス化します。このオブジェクトは、属性設定
xmlns:s="http://books.com"
(namespace の接頭辞を定義) とserviceName="s:BookService"
(QName を定義) で定義される QName によって一意に識別される必要があります。 -
Transport ID: JMS トランポートを選択するには、
, the transportId
属性をhttp://cxf.apache.org/transports/jms
に設定する必要があります。 -
JMS アドレス:
jaxrs:server/@address
属性は標準化された構文を使用して、送信する JMS キューまたはトピックを指定します。この構文の詳細は、https://tools.ietf.org/id/draft-merrick-jms-uri-06.txt を参照してください。
拡張マッピングと言語マッピング
JAX-RS サーバーエンドポイントは、ファイル接尾辞 (URL に表示される) を MIME コンテンツタイプヘッダーに自動的にマップし、言語接尾辞を言語タイプヘッダーにマップするように設定できます。たとえば、次の形式の HTTP リクエストについて考えてみます。
GET /resource.xml
以下のように、.xml
接尾辞を自動的にマッピングするように JAX-RS サーバーエンドポイントを設定できます。
<jaxrs:server id="customerService" address="/"> <jaxrs:serviceBeans> <bean class="org.apache.cxf.jaxrs.systests.CustomerService" /> </jaxrs:serviceBeans> <jaxrs:extensionMappings> <entry key="json" value="application/json"/> <entry key="xml" value="application/xml"/> </jaxrs:extensionMappings> </jaxrs:server>
上記のサーバーエンドポイントが HTTP リクエストを受信すると、型 application/xml
の新しいコンテンツ型ヘッダーを自動的に作成し、リソース URL から .xml
接尾辞を除去します。
言語マッピングについては、次の形式の HTTP リクエストを検討してください。
GET /resource.en
以下のように、.en
接尾辞を自動的にマッピングするように JAX-RS サーバーエンドポイントを設定できます。
<jaxrs:server id="customerService" address="/"> <jaxrs:serviceBeans> <bean class="org.apache.cxf.jaxrs.systests.CustomerService" /> </jaxrs:serviceBeans> <jaxrs:languageMappings> <entry key="en" value="en-gb"/> </jaxrs:languageMappings> </jaxrs:server>
上記のサーバーエンドポイントが HTTP リクエストを受信すると、値が en-gb
の新しい受け入れ言語ヘッダーを自動的に作成し、リソース URL から .en
接尾辞を除去します。
18.1.2. jaxrs:server 属性
属性
表18.1「JAX-RS サーバーエンドポイントの属性」jaxrs:server
要素で利用可能な属性を説明します。
Attribute | 説明 |
---|---|
| 他の設定要素がエンドポイントを参照するのに使用できる一意の識別子を指定します。 |
| HTTP エンドポイントのアドレスを指定します。この値は、サービスコントラクトで指定された値を上書きします。 |
| (Spring のみ) JAX-RS ルートリソースクラスや JAX-RS プロバイダークラスを検出するために検索される Java パッケージのコンマ区切りリストを指定することにより、自動検出を有効にします。 |
|
JAX-RS ルートリソース Bean の Bean ID のスペース区切りリストを指定します。Spring XML のコンテキストでは、ルートリソース |
| サービスが使用するメッセージバインディングの ID を指定します。有効なバインディング ID のリストは、23章Apache CXF バインディング ID に提供されています。 |
| サービスエンドポイントの管理に使用されるバスを設定する Spring Bean の ID を指定します。これは、共通の機能セットを使用するように複数のエンドポイントを設定する場合に役立ちます。 |
| 外部の WADL ドキュメントの場所を指定します。 |
|
モデルスキーマをクラスパスリソースとして指定します (例: |
|
サービスを自動的に公開するかどうかを指定します。 |
|
自動生成される WADL インターフェイスの |
|
(Spring のみ) Spring で自動検出するサービスアノテーションクラス名を指定します。 |
|
JAX-RS サービスを実装する JAX-RS ルートリソースクラスの名前を指定します。この場合、クラスは Blueprint や Spring では なく Apache CXF によってインスタンス化されます。Blueprint または Spring でクラスをインスタンス化する場合は、代わりに |
|
JMS トランスポートが使用される特別なケースの JAX-RS エンドポイントのサービス QName を指定します ( |
|
|
|
(HTTP の代わりに) 非標準のトランスポート層を選択する場合。特に、このプロパティーを |
|
(Spring のみ) Bean が抽象 Bean であるかどうかを指定します。抽象 Bean は、具体的な Bean 定義の親として機能し、インスタンス化されません。デフォルトは |
| (Spring のみ) エンドポイントをインスタンス化する前に、エンドポイントがインスタンス化に依存する Bean のリストを指定します。 |
18.1.3. jaxrs:server 子要素
子要素
表18.2「JAX-RS サーバーエンドポイントの子要素」に jaxrs:server
要素の子要素をまとめます。
要素 | 説明 |
---|---|
|
サービスに使用される Java |
| Apache CXF の高度な機能を設定する Bean のリストを指定します。Bean 参照のリストまたは埋め込み Bean のリストのいずれかを提供できます。 |
| 使用されていません。 |
| エンドポイントで使用されるデータバインディングを実装するクラスを指定します。これは、埋め込み Bean 定義を使用して指定されます。詳細は、「データバインディングの指定」 を参照してください。 |
| インバウンド要求を処理するインターセプターのリストを指定します。詳細は、パートVII「Apache CXF インターセプターの開発」 を参照してください。 |
| インバウンド障害メッセージを処理するインターセプターのリストを指定します。詳細は、パートVII「Apache CXF インターセプターの開発」 を参照してください。 |
| アウトバウンド応答を処理するインターセプターのリストを指定します。詳細は、パートVII「Apache CXF インターセプターの開発」 を参照してください。 |
| アウトバウンド障害メッセージを処理するインターセプターのリストを指定します。詳細は、パートVII「Apache CXF インターセプターの開発」 を参照してください。 |
| サービスが使用する org.apache.cxf.service.Invoker インターフェイスの実装を指定します。 [a] |
|
このエンドポイントに関連付けられた JAX-RS ルートリソースのライフサイクルを最大限に制御できます。この要素の子 ( |
| エンドポイントに渡されるプロパティーの Spring マップを指定します。これらのプロパティーを使用して、MTOM サポートの有効化などの機能を制御できます。 |
|
この要素の子は、JAX-RS ルートリソースのインスタンス ( |
|
1 つまたは複数の |
|
このエンドポイントに直接リソースモデルを定義します (つまり、この |
|
1 つ以上のカスタム JAX-RS プロバイダーをこのエンドポイントに登録できます。この要素の子は、JAX-RS プロバイダーのインスタンス ( |
|
REST 呼び出しの URL がファイル拡張子で終わる場合、この要素を使用して、特定のコンテンツタイプに自動的に関連付けることができます。たとえば、 |
|
REST 呼び出しの URL が言語接尾辞で終わる場合、この要素を使用してこれを特定の言語にマップできます。たとえば、 |
|
XML メッセージの内容の検証に使用される 1 つ以上の XML スキーマを指定します。この要素には、1 つまたは複数の |
| カスタムリソースコンパレータを登録できます。これは、着信 URL パスを特定のリソースクラスまたはメソッドに一致させるために使用されるアルゴリズムを実装します。 |
|
(Blueprint のみ) クラス名から複数のリソースを作成する場合には、 |
[a]
Invoker 実装は、サービスの呼び出し方法を制御します。たとえば、各リクエストをサービス実装の新しいインスタンスで処理するかどうか、呼び出し間で状態を保持するかどうかを制御します。
|