このトピックでは、SOAP メッセージ ヘッダ内の Web サービス メッセージ メタデータを抽出および処理する方法について説明します。
Web サービス メッセージに関するメタデータは通常、メッセージのヘッダ内 (SOAP エンベロープ ヘッダ内。転送ヘッダではない) で伝送されます。これらのメタデータは通常、ユーザ資格、コールバックのエンドポイント アドレスなどの情報用に使用されます。
こうしたメッセージを送信するサービスでは、メッセージの受信者がそのヘッダを解釈する必要があることを示す mustUnderstand 属性を使用して各ヘッダにフラグを指定できます。受信者がこのヘッダを解釈しない場合、そのメッセージは失敗します。
クライアント スタックは、あるサービス コントロールについて、処理されていない mustUnderstand ヘッダを検出すると例外を送出します。基底のスタックで確認する前に受信メッセージのヘッダを処理するかどうかはクライアント次第です。
この処理はハンドラを使用して実行します。ハンドラは、基底の JAX-RPC スタブがメッセージを処理する前に実行されます。ハンドラは、特定のヘッダに対して適切な処理を実行してから、ヘッダから mustUnderstand 属性を削除するか、その値を false に変更するように設計する必要があります。
サービス コントロールにハンドラを登録する方法については、「サービス コントロールへのハンドラの登録」を参照してください。
次に、mustUnderstand 属性を false に設定するハンドラの例を示します。
public class ClientHandler extends GenericHandler { ... // (1) handleResponse メソッドが呼ばれる (JAX-RPC によって呼び出されるコールバック) @Override public boolean handleResponse(MessageContext context) { return setUnderstoodHeader(context,"http://services","SomeHeader"); } private boolean setUnderstoodHeader(MessageContext context, String namespace, String local) { // (2) ヘッダを取得する。 SOAPMessageContext smc = (SOAPMessageContext)context; SOAPMessage msg = smc.getMessage(); SOAPPart sp = msg.getSOAPPart(); try { SOAPEnvelope se = sp.getEnvelope(); SOAPHeader sh = se.getHeader(); // (3) 指定されたヘッダ要素を取得する。 Iterator iterator = sh.examineAllHeaderElements(); while (iterator.hasNext()) { SOAPHeaderElement el = (SOAPHeaderElement) iterator.next(); if(namespace.equals(el.getNamespaceURI()) && local.equals(el.getLocalName())) { // (4) ここでヘッダ情報の処理を行う el.setMustUnderstand(false); return true; } } } catch (SOAPException e) { e.printStackTrace(); } return false; } }
(1) 最初に、ハンドラで handleResponse メソッドが呼ばれます。これが JAX-RPC によって呼び出されるコールバック API です。
(2) 次に、SAAJ DOM を反復処理し、ヘッダを取得します。
(3) 次に、特定のヘッダの mustUnderstand 属性を解釈済みとして設定するメソッドがきます。このメソッドは単に DOM 内を調査し、ヘッダ セクションを取得します。次に、メソッドに送信されたローカル名とネームスペースによって指定されている要素をヘッダ内で調査します。
(4) 最後に、そのヘッダにとって適切な処理を実行してから、mustUnderstand を false に設定し、ヘッダを処理したことを示します。または、値を false に設定するのではなく、el.removeAttributeNS(...) を呼び出すことによって mustUnderstand 属性を削除することもできます。
この呼び出しが完了すると、基底の JAX-RPC インフラストラクチャによってそのメッセージの処理が続行され、最終的にサービス コントロール (または JAX-RPC スタブ) クライアントでそのメッセージが利用できるようになります。