Menu Close

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 メッセージコンテキストは Java マップのサブクラスです。コンテキストに保存されたプロパティーにアクセスするには、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 メッセージを取得する。

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