JAX-WS Web サービスでのハンドラーの使用
Java™ API for XML Web Services (JAX-WS) により、相互操作と移植が可能な Web サービスを開発するための標準的な方法が提供されます。JAX-WS ハンドラーを使用して、Web サービス要求または応答処理をカスタマイズします。
始める前に
構成するアプリケーションのエンタープライズ・アーカイブ (EAR) ファイルが必要です。 Thin Client for JAX-WS 環境で実行している場合は、EAR ファイルから開始する必要はありません。 ロギングまたはトレースなどのハンドラーが使用する場合には、 サーバー・アプリケーションまたはクライアント・アプリケーションのみ構成する必要があります。SOAP ヘッダー内の情報の送信などの他のハンドラーが使用する場合には、 クライアント・アプリケーションおよびサーバー・アプリケーションが、シンメトリック・ハンドラーを使用して構成されている必要があります。
SOAPMessage m = context.getMessage();
AttachmentPart ap1 = m.createAttachmentPart();
ap1.setContent("abc", "text/plain");
m.addAttachmentPart(ap1);
context.setMessage(m);
このタスクについて
Java API for XML-based RPC (JAX-RPC) プログラミング・モデルのように、 JAX-WS プログラミング・モデルは、アプリケーション・ハンドラー機能を提供します。 この機能によって、インバウンド・フローまたはアウトバウンド・フローでメッセージを操作できます。 ハンドラーを JAX-WS ランタイム環境に追加して、要求および応答メッセージの追加処理を行うことができます。 ハンドラーは、情報の収集とロギング、セキュリティーまたは他の情報のメッセージへの追加など、さまざまな目的に使用できます。 SOAP ではサポートされない追加プロトコルをサポートするために、 JAX-WS はハンドラーに 2 つの異なる分類をしています。 ハンドラーの 1 つのタイプは、論理ハンドラーです。 この論理ハンドラーは、プロトコルに依存せず、Extensible Markup Language (XML) メッセージとしてフロー内のメッセージを取得することができます。 論理ハンドラーは、メッセージ・コンテキスト・プロパティーおよびメッセージ・ペイロードを操作します。 これらのハンドラーは、javax.xml.ws.handler.LogicalHandler インターフェースを実装している必要があります。 論理ハンドラーは、メッセージ情報の取得元として使用できる LogicalMessageContext オブジェクトを受信します。 論理ハンドラーは、SOAP ベース構成と XML/HTTP ベース構成の両方に存在させることができます。
第 2 のタイプのハンドラーは、プロトコル・ハンドラーです。 プロトコル・ハンドラーは、メッセージ・コンテキスト・プロパティーとプロトコル固有メッセージを操作します。 プロトコル・ハンドラーは、SOAP ベース構成のみを操作することができ、 javax.xml.ws.handler.soap.SOAPHandler インターフェースを実装している必要があります。 プロトコル・ハンドラーは、メッセージ・データを読み取るために、 メッセージを javax.xml.soap.SOAPMessage として受信します。
JAX-WS ランタイムは、サーバー・サイドのハンドラー・クラスとクライアント・サイドのハンドラー・クラスを区別しません。 JAX-WS ランタイムは、特定ハンドラーの handleMessage(MessageContext) メソッドまたは handleFault(MessageContext) メソッドが呼び出される際に、 インバウンド・フローとアウトバウンド・フローを区別しません。 サーバーまたはクライアントのハンドラーを構成し、これらのメソッド内に十分なロジックを実装して、 現行メッセージのインバウンドまたはアウトバウンドの方向を検出する必要があります。
ハンドラーを Web サービス・クライアント・アプリケーションで使用するには、@HandlerChain アノテーションをサービス・エンドポイント・インターフェースまたは生成されたサービス・クラスに追加し、ハンドラー・チェーン構成ファイルを付与する必要があります。@HandlerChain アノテーションには、 作成するハンドラー・チェーン構成ファイルを指すファイル属性も含まれています。 Web サービス・クライアント・アプリケーションの場合、バインディング API を使用して、ハンドラー・チェーンをプログラムで構成することできます。handlerchain クラスをプログラムで変更するには、 HandlerResolver メソッドのデフォルト実装またはカスタム実装のいずれかを使用します。
ハンドラーをサーバー・アプリケーションで使用するには、 @HandlerChain アノテーションをサービス・エンドポイント・インターフェースまたはエンドポイント実装クラスのいずれかに設定し、関連したハンドラー・チェーン構成ファイルを用意する必要があります。 サーバーのハンドラーは、 @HandlerChain アノテーションをサービス・エンドポイント実装または実装クラスに設定することでのみ構成できます。 ハンドラー・クラスは、サーバー・アプリケーションの EAR ファイルに含める必要があります。
@HandlerChain(file="../../common/handlers/myhandlers.xml")
または@HandlerChain(file="http://foo.com/myhandlers.xml")
ハンドラー構成ファイルのスキーマについて詳しくは、
JSR 181 仕様を参照してください。JAX-WS ハンドラーについて詳しくは、 JAX-WS 仕様の第 9 章を参照してください。
手順
タスクの結果
JAX-WS Web サービスまたは Web サービス・クライアントがハンドラーを使用して要求および応答メッセージ交換の追加処理を実行できるようにしました。
例
以下の例は、@HandlerChain アノテーションを使用してサービス・エンドポイント・インターフェースに JAX-WS ハンドラーを構成する際に必要なステップを示しています。
<?xml version="1.0" encoding="UTF-8"?>
<jws:handler-chains xmlns:jws="http://java.sun.com/xml/ns/javaee">
<!-- Note: The '*" denotes a wildcard. -->
<jws:handler-chain name="MyHandlerChain">
<jws:protocol-bindings>##SOAP11_HTTP ##ANOTHER_BINDING</jws:protocol-bindings>
<jws:port-name-pattern
xmlns:ns1="http://handlersample.samples.ibm.com/">ns1:MySampl*</jws:port-name-pattern>
<jws:service-name-pattern
xmlns:ns1="http://handlersample.samples.ibm.com/">ns1:*</jws:service-name-pattern>
<jws:handler>
<jws:handler-class>com.ibm.samples.handlersample.SampleLogicalHandler</jws:handler-class>
</jws:handler>
<jws:handler>
<jws:handler-class>com.ibm.samples.handlersample.SampleProtocolHandler2</jws:handler-class>
</jws:handler>
<jws:handler>
<jws:handler-class>com.ibm.samples.handlersample.SampleLogicalHandler</jws:handler-class>
</jws:handler>
<jws:handler>
<jws:handler-class>com.ibm.samples.handlersample.SampleProtocolHandler2</jws:handler-class>
</jws:handler>
</jws:handler-chain>
</jws:handler-chains>
</jws:handler-chains>
handler.xml ファイルと、handler.xml ファイルに含まれるハンドラー・クラスがクラスパスに追加されている必要があります。
package com.ibm.samples.handlersample;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class SampleProtocolHandler implements
javax.xml.ws.handler.soap.SOAPHandler<SOAPMessageContext> {
public void close(MessageContext messagecontext) {
}
public Set<QName> getHeaders() {
return null;
}
public boolean handleFault(SOAPMessageContext messagecontext) {
return true;
}
public boolean handleMessage(SOAPMessageContext messagecontext) {
Boolean outbound = (Boolean) messagecontext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outbound) {
// Include your steps for the outbound flow.
}
return true;
}
}