第42章 コンテキストの使用

概要

JAX-WS は、コンテキストを使用して、メッセージングチェーンに沿ってメタデータを渡します。このメタデータは、そのスコープに応じて、実装レベルのコードからアクセスできます。また、実装レベルより下のメッセージを操作する JAX-WS ハンドラーからもアクセスできます。

42.1. コンテキストを理解する

概要

多くの場合、メッセージに関する情報をアプリケーションの他の部分に渡す必要があります。Apache CXF は、コンテキストメカニズムを使用してこれを行います。コンテキストは、送信メッセージまたは受信メッセージに関連するプロパティーを保持するマップです。コンテキストに格納されるプロパティーは、通常、メッセージに関するメタデータと、メッセージの通信に使用される基になるトランスポートです。たとえば、HTTP 応答コードや JMS 相関 ID など、メッセージの送信に使用されるトランスポート固有のヘッダーは、JAX-WS コンテキストに格納されます。

コンテキストは、JAX-WS アプリケーションのすべてのレベルで使用できます。ただし、メッセージ処理スタックのどこでコンテキストにアクセスしているかによって、微妙に異なります。JAX-WS ハンドラーの実装は、コンテキストに直接アクセスでき、コンテキストに設定されているすべてのプロパティーにアクセスできます。サービス実装はコンテキストを注入することでそれらにアクセスし、APPLICATION スコープで設定されたプロパティーにのみアクセスできます。コンシューマーの実装は、APPLICATION スコープに設定されたプロパティーにのみアクセスできます。

図42.1「メッセージコンテキストとメッセージ処理パス」 コンテキストプロパティーが Apache CXF をどのように通過するかを示します。メッセージがメッセージングチェーンを通過すると、関連するメッセージコンテキストも一緒に通過します。

図42.1 メッセージコンテキストとメッセージ処理パス

メッセージコンテキストは、クライアントとサーバーメッセージ処理チェーン全体にわたって利用できます

プロパティーがコンテキストに保存される方法

メッセージコンテキストは、javax.xml.ws.handler.MessageContext インターフェイスのすべての実装です。MessageContext インターフェイスは、java.util.Map<String key, Object value> インターフェイスを拡張します。マップオブジェクトは、情報をキーと値のペアとして格納します。

メッセージコンテキストでは、プロパティーは名前と値のペアとして保存されます。プロパティーのキーは、プロパティーを識別する String です。プロパティーの値は、任意の Java オブジェクトに格納されている任意の値にすることができます。メッセージコンテキストから値が返される場合、アプリケーションは、期待するタイプを認識し、それに応じてキャストする必要があります。たとえば、プロパティーの値が UserInfo オブジェクトに保存される場合、プロパティーの値は UserInfo オブジェクトにキャストする必要がある Object オブジェクトとしてメッセージコンテキストから返されます。

メッセージコンテキストのプロパティーにもスコープがあります。スコープは、メッセージ処理チェーンのどこにプロパティーにアクセスできるかを決定します。

プロパティースコープ

メッセージコンテキストのプロパティーはスコープされます。プロパティーは、次のスコープのいずれかになります。

APPLICATION
APPLICATION としてスコープが設定されたプロパティーは、JAX-WS Handler 実装、コンシューマー実装コード、およびサービスプロバイダー実装コードで利用できます。ハンドラーがサービスプロバイダー実装にプロパティーを渡す必要がある場合は、プロパティーのスコープを APPLICATION に設定します。コンシューマー実装またはサービスプロバイダー実装コンテキストのいずれかで設定されたすべてのプロパティーは、APPLICATION として自動的にスコープが設定されます。
HANDLER
HANDLER としてスコープ設定されたプロパティーは、JAX-WS Handler 実装でのみ利用できます。Handler 実装からメッセージコンテキストに保存されるプロパティーは、デフォルトで HANDLER としてスコープ設定されます。

メッセージコンテキストの setScope() メソッドを使用して、プロパティーのスコープを変更できます。例42.1「MessageContext.setScope() メソッド」 メソッドのシグネチャーを示します。

例42.1 MessageContext.setScope() メソッド

setScopeStringkeyMessageContext.Scopescopejava.lang.IllegalArgumentException

最初のパラメーターは、プロパティーのキーを指定します。2 番目のパラメーターは、プロパティーの新しいスコープを指定します。スコープは次のいずれかになります。

  • MessageContext.Scope.APPLICATION
  • MessageContext.Scope.HANDLER

ハンドラーのコンテキストの概要

JAX-WS ハンドラーインターフェイスを実装するクラスは、メッセージのコンテキスト情報に直接アクセスできます。メッセージのコンテキスト情報は、Handler 実装の handleMessage()handleFault()、および close() メソッドに渡されます。

ハンドラーの実装は、スコープに関係なく、メッセージコンテキストに格納されているすべてのプロパティーにアクセスできます。また、論理ハンドラーは LogicalMessageContext と呼ばれる特別なメッセージコンテキストを使用します。LogicalMessageContext オブジェクトには、メッセージボディーの内容にアクセスするメソッドがあります。

サービス実装のコンテキストの概要

サービス実装は、メッセージコンテキストから APPLICATION としてスコープ設定されたプロパティーにアクセスできます。サービスプロバイダーの実装オブジェクトは、WebServiceContext オブジェクトを介してメッセージコンテキストにアクセスします。

詳細は、「サービス実装でのコンテキストの操作」 を参照してください。

コンシューマー実装のコンテキストの概要

コンシューマー実装は、メッセージコンテキストのコンテンツに間接的にアクセスできます。コンシューマーの実装には、2 つの別個のメッセージコンテキストがあります。

  • リクエストコンテキスト—送信リクエストに使用されるプロパティーのコピーを保持します
  • 応答コンテキスト—着信応答からのプロパティーのコピーを保持します

ディスパッチレイヤーは、コンシューマー実装のメッセージコンテキストとハンドラー実装で使用されるメッセージコンテキストの間でプロパティーを転送します。

要求がコンシューマー実装からディスパッチ層に渡されると、要求コンテキストの内容が、ディスパッチ層で使用されるメッセージコンテキストにコピーされます。サービスから応答が返されると、ディスパッチレイヤーはメッセージを処理し、適切なプロパティーをメッセージコンテキストに設定します。ディスパッチレイヤーが応答を処理すると、メッセージコンテキストの APPLICATION としてスコープ設定されたすべてのプロパティーをコンシューマー実装の応答コンテキストにコピーします。

詳細は、「コンシューマー実装でのコンテキストの操作」を参照してください。