13.5.2. JAX-WS の共通 API リファレンス

一部の JAX-WS 開発概念は Web サービスエンドポイントとクライアントの間で共有されます。これには、ハンドラーフレームワーク、メッセージコンテキスト、フォルトハンドリングなどが含まれます。
ハンドラーフレームワーク

ハンドラーフレームワークは JAX-WS プロトコルバインディングにより、サーバーコンポーネントであるクライアントおよびエンドポイントのランタイムに実装されます。プロキシおよび Dispatch のインスタンスは、バインディングプロバイダー と総称されており、それぞれがプロトコルバインディングを使用して抽象機能を特定のプロトコルにバインドします。

クライアントおよびサーバー側のハンドラーは ハンドラーチェーン として知られる順序付きリストにまとめられます。ハンドラーチェーン内のハンドラーは、メッセージが送受信されるごとに呼び出されます。受信メッセージは、バインディングプロバイダーが処理する前にハンドラーによって処理されます。送信メッセージはバインディングプロバイダーが処理した後にハンドラーによって処理されます。
ハンドラーはメッセージコンテキストとともに呼び出されます。これは、受信メッセージと送信メッセージにアクセスして変更し、プロパティセットを管理するメソッドを提供します。メッセージコンテキストのプロパティは個々のハンドラー間およびハンドラー/クライアント/サービス実装間における通信を円滑化します。ハンドラーのタイプによって、一緒に呼び出されるメッセージコンテキストのタイプが異なります。

メッセージハンドラーのタイプ

論理ハンドラー
論理ハンドラー はメッセージコンテキストプロパティーおよびメッセージペイロードでのみ動作します。論理ハンドラーはプロトコル非依存なので、メッセージのプロトコル固有の部分に影響を与えることはできません。論理ハンドラーはインターフェース javax.xml.ws.handler.LogicalHandler を実装します。
プロトコルハンドラー
Protocol handlers はメッセージコンテキストおよびプロトコル固有のメッセージでのみ動作します。プロトコルハンドラーは特定のプロトコルに固有で、プロトコル固有のメッセージアスペクトにアクセスし、変更することが可能です。 プロトコルハンドラーは javax.xml.ws.handler.Handler except javax.xml.ws.handler.LogicalHandler から派生する任意のインターフェースを実装します。
サービスエンドポイントハンドラー
サービスエンドポイントでは、ハンドラーは @HandlerChain アノテーションを使用して定義されます。ハンドラーチェーンファイルのロケーションは、externalForm 内の絶対 java.net.URL、あるいはソースファイル/クラスファイルからの相対パスで指定することができます。

例13.30 サービスエンドポイントハンドラーの例

@WebService
@HandlerChain(file = "jaxws-server-source-handlers.xml")
public class SOAPEndpointSourceImpl
{
   ...
}

サービスクライアントハンドラー
JAX-WS クライアントでは、ハンドラーは サービスエンドポイント同様に @HandlerChain アノテーションを使用するか、動的に JAX-WS API を使用して定義します。

例13.31 API を使用したサービスクライアントハンドラーの定義

Service service = Service.create(wsdlURL, serviceName);
Endpoint port = (Endpoint)service.getPort(Endpoint.class);
     
BindingProvider bindingProvider = (BindingProvider)port;
List<Handler> handlerChain = new ArrayList<Handler>();
handlerChain.add(new LogHandler());
handlerChain.add(new AuthorizationHandler());
handlerChain.add(new RoutingHandler());
bindingProvider.getBinding().setHandlerChain(handlerChain);					

setHandlerChain メソッドへのコールが必要です。
メッセージコンテキスト

MessageContext インターフェースは、全 JAX-WS メッセージコンテキスト用のスーパーインターフェースです。追加のメソッドと定数を使用して Map<String,Object> を拡張し、ハンドラーチェーン内のハンドラーが処理関連の状態を共有できるようにするプロパティセットを管理します。たとえば、ハンドラーは put メソッドを使用してメッセージコンテキストにプロパティを挿入することができます。その後、ハンドラーチェーン内の単一または複数のハンドラーは、 get メソッドでメッセージを取得できるようになります。

プロパティは、APPLICATION または HANDLER としてスコープ指定されます。すべてのプロパティは、特定のエンドポイントの メッセージ交換パターン (MEP) のインスタンスの全ハンドラーが使用することができます。たとえば、論理ハンドラーがメッセージコンテキストにプロパティを挿入すると、そのプロパティは、MET インスタンスの実行中にチェーン内の任意のプロトコルハンドラーも使用することができます。

注記

非同期メッセージ交換パターン (MEP) により、HTTP 接続レベルでのメッセージの非同期的な送受信が可能となります。これは、要求コンテキストに追加のプロパティーを設定することによって有効にできます。
APPLICATION レベルにスコープ指定されているプロパティはクライアントアプリケーションとサービスエンドポイントの実装でも使用することができます。プロパティの defaultscopeHANDLER です。
論理メッセージと SOAP メッセージでは使用するコンテキストが異なります。
論理メッセージコンテキスト
論理ハンドラーが呼び出される際には、タイプ LogicalMessageContext のメッセージコンテキストを受信します。LogicalMessageContext は、メッセージペイロードを取得/変更するメソッドを使用して MessageContext を拡張します。これは、メッセージのプロトコル固有のアスペクトへのアクセスは提供しません。プロトコルバインディングは、論理メッセージコンテキストを介して使用可能なメッセージコンポーネントを定義します。SOAP バインディングにデプロイされている論理ハンドラーは、SOAP ボディーのコンテンツにアクセス可能ですが、SOAP ヘッダーにはアクセスできません。一方、XML/HTTP バインディングは論理ハンドラーがメッセージの XML ペイロード全体にアクセスできることを定義します。
SOAP メッセージコンテキスト
SOAP ハンドラーが呼び出される際には、SOAPMessageContext を受信します。 SOAPMessageContext は SOAP メッセージペイロードを取得/変更するメソッドを使用して MessageContext を拡張します。
フォルドハンドリング

アプリケーションは SOAPFaultException またはアプリケーション固有のユーザー例外をスローします。後者の場合、必要とされる障害ラッパー (fault wrapper) Bean が既にデプロイメントの一部となっていなければ、ランタイムに生成されます。

例13.32 フォルトハンドリングの例

public void throwSoapFaultException()
{
   SOAPFactory factory = SOAPFactory.newInstance();
   SOAPFault fault = factory.createFault("this is a fault string!", new QName("http://foo", "FooCode"));
   fault.setFaultActor("mr.actor");
   fault.addDetail().addChildElement("test");
   throw new SOAPFaultException(fault);
}
public void throwApplicationException() throws UserException
{
   throw new UserException("validation", 123, "Some validation error");
}
JAX-WS アノテーション

JAX-WS API で使用可能なアノテーションは JSR-224 で定義されています。この定義は http://www.jcp.org/en/jsr/detail?id=224 に記載されています。これらのアノテーションは javax.xml.ws パッケージに含まれています。

JWS API で使用できるアノテーションは、 JSR-181 で定義されています。この定義は http://www.jcp.org/en/jsr/detail?id=181 に記載されています。これらのアノテーションは javax.jws パッケージに含まれています。