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[]getHeadersQNameheaderJAXBContextcontextbooleanallRoles

要素の QName を使用してヘッダーを指定します。allRoles パラメーターを false に設定すると、返されるヘッダーをさらに制限することができます。これは、アクティブな SOAP ロールに適用可能な SOAP ヘッダーのみを返すようにランタイムに指示します。

ヘッダーが見つからない場合、メソッドは空の配列を返します。

JAXBContext オブジェクトのインスタンス化の詳細は、39章JAXBContext オブジェクトの使用を参照してください。

コンテキストプロパティーの操作

論理ハンドラーに渡される SOAP メッセージコンテキストは、アプリケーションのメッセージコンテキストのインスタンスであり、そこに格納されているすべてのプロパティーにアクセスできます。ハンドラーは、APPLICATION スコープが設定されたプロパティーと Handler スコープが設定されたプロパティーの両方にアクセスできます。

アプリケーションのメッセージコンテキストと同様に、SOAP メッセージコンテキストは JavaMap のサブクラスです。コンテキストに保存されたプロパティーにアクセスするには、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() メソッドがそのメッセージ処理をどのように完了するかが、メッセージ処理の実施方法に直接的な影響を及ぼします。次のいずれかのアクションを実行することで完了できます。

  1. true を返す - メッセージ処理を正常に続行する必要があることを示す true シグナルを Apache CXF ランタイムに返します。次のハンドラーがある場合は、その handleMessage() が呼び出されます。
  2. false を返す - 通常のメッセージ処理を停止する false シグナルを Apache CXF ランタイムに返します。ランタイムがどのように進行するかは、現在のメッセージ に使用されているメッセージ交換パターンによって異なります。

    要求/応答メッセージ交換の場合は、次のことが起こります。

    1. メッセージ処理の方向が逆になります。

      たとえば、要求がサービスプロバイダーによって処理されている場合、メッセージはサービスの実装オブジェクトへの進行を停止します。代わりに、リクエストを発信したコンシューマーに返すために、バインディングに向けて送り返されます。

    2. 新しい処理方向でハンドラーチェーンに沿って存在するメッセージハンドラーには、チェーン内で存在する順序で handleMessage() メソッドが呼び出されます。
    3. メッセージがハンドラーチェーンの最後に到達すると、メッセージがディスパッチされます。

      一方向のメッセージ交換の場合は、次のことが起こります。

    4. メッセージ処理が停止します。
    5. これまで呼び出されたすべてのメッセージハンドラーには、その close() メソッドが呼び出されます。
    6. メッセージが送信されます。
  3. ProtocolException 例外を出力する -ProtocolException 例外、またはこの例外のサブクラスを出力すると、障害メッセージ処理が開始されることを Apache CXF ランタイムに通知します。ランタイムがどのように進行するかは、現在のメッセージ に使用されているメッセージ交換パターンによって異なります。

    要求/応答メッセージ交換の場合は、次のことが起こります。

    1. ハンドラーがまだ障害メッセージを作成していない場合、ランタイムはメッセージを障害メッセージでラップします。
    2. メッセージ処理の方向が逆になります。

      たとえば、要求がサービスプロバイダーによって処理されている場合、メッセージはサービスの実装オブジェクトへの進行を停止します。リクエストを発信したコンシューマーに返すために、バインディングに向けて送り返されます。

    3. 新しい処理方向でハンドラーチェーンに沿って存在するメッセージハンドラーには、チェーン内で存在する順序で handleFault() メソッドが呼び出されます。
    4. 障害メッセージがハンドラーチェーンの最後に到達すると、ディスパッチされます。

      一方向のメッセージ交換の場合は、次のことが起こります。

    5. ハンドラーがまだ障害メッセージを作成していない場合、ランタイムはメッセージを障害メッセージでラップします。
    6. メッセージ処理が停止します。
    7. これまで呼び出されたすべてのメッセージハンドラーには、その close() メソッドが呼び出されます。
    8. 障害メッセージが送信されます。
  4. その他のランタイム例外を出力する -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 メッセージを取得します。

メッセージをコンソールに出力します。