43.5. SOAP ハンドラーでのメッセージの処理
概要
通常のメッセージ処理は、handleMessage()
メソッドによって処理されます。
handleMessage()
メソッドは、SOAPMessage
オブジェクトとしてのメッセージボディーおよびメッセージに関連付けられた SOAP ヘッダーへのアクセスを提供する SOAPMessageContext
オブジェクトを受け取ります。さらに、コンテキストは、メッセージコンテキストに格納されているすべてのプロパティーへのアクセスを提供します。
メッセージ処理の継続方法に応じて、handleMessage()
メソッドは true または false のいずれかを返します。例外を出力することもできます。
メッセージ本文の操作
SOAP メッセージコンテキストの getMessage()
メソッドを使用して SOAP メッセージを取得することができます。これは、メッセージをライブ SOAPMessage
オブジェクトとして返します。ハンドラー内のメッセージへの変更は、コンテキストに格納されているメッセージに自動的に反映されます。
既存のメッセージを新しいメッセージに置き換える場合は、コンテキストの setMessage()
メソッドを使用できます。setMessage()
メソッドは SOAPMessage
オブジェクトを取ります。
SOAP ヘッダーの取得
SOAP メッセージのヘッダーには、SOAPMessage
オブジェクトの getHeader()
メソッドを使用してアクセスできます。これにより、SOAP ヘッダーが SOAPHeader
オブジェクトとして返されます。このオブジェクトを、処理するヘッダー要素を探すために検査する必要があります。
SOAP メッセージコンテキストは、例43.10「SOAPMessageContext.getHeaders()
メソッド」に示される getHeaders()
メソッドを提供します。これは、指定された SOAP ヘッダーの JAXB オブジェクトが含まれる配列を返します。
例43.10 SOAPMessageContext.getHeaders()
メソッド
Ojbect[]
getHeaders
QName
header
JAXBContext
context
boolean
allRoles
要素の QName を使用してヘッダーを指定します。allRoles
パラメーターを false に設定すると、返されるヘッダーをさらに制限することができます。これは、アクティブな SOAP ロールに適用可能な SOAP ヘッダーのみを返すようにランタイムに指示します。
ヘッダーが見つからない場合、メソッドは空の配列を返します。
JAXBContext
オブジェクトのインスタンス化の詳細は、39章JAXBContext
オブジェクトの使用を参照してください。
コンテキストプロパティーの操作
論理ハンドラーに渡される SOAP メッセージコンテキストは、アプリケーションのメッセージコンテキストのインスタンスであり、そこに格納されているすべてのプロパティーにアクセスできます。ハンドラーは、APPLICATION
スコープが設定されたプロパティーと Handler
スコープが設定されたプロパティーの両方にアクセスできます。
アプリケーションのメッセージコンテキストと同様に、SOAP メッセージコンテキストは Java Map のサブクラスです。コンテキストに保存されたプロパティーにアクセスするには、Map インターフェイスから継承された get()
メソッドと put()
メソッドを使用します。
デフォルトでは、論理ハンドラー内からコンテキストで設定したプロパティーには、HANDLER
のスコープが割り当てられます。アプリケーションコードがプロパティーにアクセスできるようにするには、コンテキストの setScope()
メソッドを使用して、プロパティーのスコープを明示的に APPLICATION.
に設定する必要があります。
メッセージコンテキストでのプロパティーの操作の詳細は、「コンテキストを理解する」 を参照してください。
メッセージの方向を決定する
多くの場合、メッセージがハンドラーチェーンを通過する方向を知ることが重要です。たとえば、送信メッセージにヘッダーを追加し、受信メッセージからヘッダーを削除するとします。
メッセージの方向は、メッセージコンテキストのアウトバウンドメッセージプロパティーに保存されます。例43.11「SOAP メッセージコンテキストからのメッセージの方向の取得」 に示すように、MessageContext.MESSAGE_OUTBOUND_PROPERTY キーを使用して、メッセージコンテキストからアウトバウンドメッセージプロパティーを取得します。
例43.11 SOAP メッセージコンテキストからのメッセージの方向の取得
Boolean outbound; outbound = (Boolean)smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
このプロパティーは Boolean
オブジェクトとして保存されます。オブジェクトの booleanValue()
メソッドを使用して、プロパティーの値を決定できます。プロパティーが true に設定されている場合、メッセージはアウトバウンドです。プロパティーが false に設定されている場合、メッセージはインバウンドです。
戻り値の決定
handleMessage()
メソッドがそのメッセージ処理をどのように完了するかが、メッセージ処理の実施方法に直接的な影響を及ぼします。次のいずれかのアクションを実行することで完了できます。
-
true を返す - メッセージ処理を正常に続行する必要があることを示す true シグナルを Apache CXF ランタイムに返します。次のハンドラーがある場合は、その
handleMessage()
が呼び出されます。 false を返す - 通常のメッセージ処理を停止する false シグナルを Apache CXF ランタイムに返します。ランタイムがどのように進行するかは、現在のメッセージ に使用されているメッセージ交換パターンによって異なります。
要求/応答メッセージ交換の場合は、次のことが起こります。
メッセージ処理の方向が逆になります。
たとえば、要求がサービスプロバイダーによって処理されている場合、メッセージはサービスの実装オブジェクトへの進行を停止します。代わりに、リクエストを発信したコンシューマーに返すために、バインディングに向けて送り返されます。
-
新しい処理方向でハンドラーチェーンに沿って存在するメッセージハンドラーには、チェーン内で存在する順序で
handleMessage()
メソッドが呼び出されます。 メッセージがハンドラーチェーンの最後に到達すると、メッセージがディスパッチされます。
一方向のメッセージ交換の場合は、次のことが起こります。
- メッセージ処理が停止します。
-
これまで呼び出されたすべてのメッセージハンドラーには、その
close()
メソッドが呼び出されます。 - メッセージが送信されます。
ProtocolException 例外を出力する -ProtocolException 例外、またはこの例外のサブクラスを出力すると、障害メッセージ処理が開始されることを Apache CXF ランタイムに通知します。ランタイムがどのように進行するかは、現在のメッセージ に使用されているメッセージ交換パターンによって異なります。
要求/応答メッセージ交換の場合は、次のことが起こります。
- ハンドラーがまだ障害メッセージを作成していない場合、ランタイムはメッセージを障害メッセージでラップします。
メッセージ処理の方向が逆になります。
たとえば、要求がサービスプロバイダーによって処理されている場合、メッセージはサービスの実装オブジェクトへの進行を停止します。リクエストを発信したコンシューマーに返すために、バインディングに向けて送り返されます。
-
新しい処理方向でハンドラーチェーンに沿って存在するメッセージハンドラーには、チェーン内で存在する順序で
handleFault()
メソッドが呼び出されます。 障害メッセージがハンドラーチェーンの最後に到達すると、ディスパッチされます。
一方向のメッセージ交換の場合は、次のことが起こります。
- ハンドラーがまだ障害メッセージを作成していない場合、ランタイムはメッセージを障害メッセージでラップします。
- メッセージ処理が停止します。
-
これまで呼び出されたすべてのメッセージハンドラーには、その
close()
メソッドが呼び出されます。 - 障害メッセージが送信されます。
-
その他のランタイム例外を出力する -ProtocolException 例外以外のランタイム例外を出力すると、メッセージ処理が停止することを Apache CXF ランタイムに通知します。これまで呼び出されたすべてのメッセージハンドラーには
close()
メソッドが呼び出され、例外がディスパッチされます。メッセージが要求/応答メッセージ交換の一部である場合、例外がディスパッチされ、要求を発信したコンシューマーに返されます。
例
例43.12「SOAP ハンドラーでのメッセージの処理」に、SOAP メッセージを画面に出力する handleMessage()
の実装を示します。
例43.12 SOAP ハンドラーでのメッセージの処理
public boolean handleMessage(SOAPMessageContext smc) { PrintStream out; Boolean outbound = (Boolean)smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); if (outbound.booleanValue()) { out.println("\nOutbound message:"); } else { out.println("\nInbound message:"); } SOAPMessage message = smc.getMessage(); message.writeTo(out); out.println(); return true; }
例43.12「SOAP ハンドラーでのメッセージの処理」 のコードは、以下を行います。
メッセージコンテキストからアウトバウンドプロパティーを取得します。
メッセージの方向をテストし、適切なメッセージを出力します。
コンテキストから SOAP メッセージを取得します。
メッセージをコンソールに出力します。