Menu Close
第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 のプレフィックスは、Blueprint と Spring のそれぞれ 異なる namespace にマッピングされることに注意してください。 jaxrs:server
要素のaddress
属性を使用した JAX-RS サービスのベース URL。アドレス URL を指定する方法は 2 つあり、エンドポイントがどのようにデプロイされるかに影響を及ぼします。相対 URL として (例:
/customers
)。この場合、エンドポイントはデフォルトの HTTP コンテナーにデプロイされます。また、CXF サーブレットベース URL と指定の相対パス URL を組み合わせることで、エンドポイントのベース URL が暗黙的に取得されます。たとえば、JAX-RS エンドポイントを Fuse コンテナーにデプロイする場合、指定の
/customers
URL は URLhttp://Hostname:8181/cxf/customers
に解決されます (コンテナーがデフォルトの8181
ポートを使用していることを前提とします)。-
絶対 URL として (例:
http://0.0.0.0:8200/cxf/customers
)。この場合、新しい HTTP リスナーポートが JAX-RS エンドポイントに対して開きます (まだ開かていない場合は)。たとえば、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 の namespace
Blueprint で JAX-RS エンドポイントを定義するには、通常、少なくとも以下の XML namespace が必要です。
プレフィックス | namespace |
---|---|
(デフォルト) | |
| |
|
Spring の例
以下の Spring XML の例は、(デフォルトの HTTP コンテナーにデプロイするように) 相対アドレス /customers
を指定し、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 の namespace
Spring で JAX-RS エンドポイントを定義するには、通常、少なくとも以下の XML namespace が必要です。
プレフィックス | namespace |
---|---|
(デフォルト) | |
| |
|
Spring XML での自動検出
(Spring のみ) 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 のスペース区切りリストとして指定されます。
JAX-RS サーバーエンドポイントを設定する際に最高の柔軟性を確保するために、jaxrs:serviceFactories
要素を使用してサービスファクトリーオブジェクトを 明示的に 定義するオプションがあります。このより詳細なアプローチには、デフォルトのサービスファクトリーの実装をカスタム実装に置き換えることができるため、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 によって一意に識別される必要があります。 -
トランスポート ID: JMS トランスポートを選択するには、
transportId
属性をhttp://cxf.apache.org/transports/jms
に設定する必要があります。 -
JMS アドレス:
jaxrs:server/@address
属性は標準化された構文を使用して送信する JMS キューまたは JMS トピックを指定します。この構文の詳細については、「URI Scheme for Java(tm) Message Service 1.0 draft-merrick-jms-uri-06」を参照してください。
拡張マッピングおよび言語マッピング
ファイルサフィックス (URL に表示される) を MIME コンテンツ型ヘッダーに、言語サフィックスを言語型ヘッダーに、それぞれ自動的にマッピングするように JAX-RS サーバーエンドポイントを設定することができます。たとえば、以下の形式の 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
要素で利用可能な属性をまとめます。
表18.1 JAX-RS サーバーエンドポイント属性
属性 | 説明 |
---|---|
| エンドポイントの参照に他の設定要素が使用できる一意の識別子を指定します。 |
| HTTP エンドポイントのアドレスを指定します。この値は、サービスのコントラクトで指定された値をオーバーライドします。 |
| (Spring のみ) Java パッケージのコンマ区切りリストを指定して、自動検出を有効にします。パッケージを検索して JAX-RS ルートリソースクラスや JAX-RS プロバイダークラスを検出します。 |
|
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
要素の子要素をまとめます。
表18.2 JAX-RS サーバーエンドポイントの子要素
要素 | 説明 |
---|---|
|
サービスに使用される 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 実装は、サービスがどのように呼び出されれるかを制御します。たとえば、各リクエストがサービス実装の新規インスタンスによって処理されるかどうか、あるいは次回の呼び出し時に状態が保持されるかどうかを制御します。
|