JAX-WS API を使用した動的クライアントの開発
Java™ API for XML-Based Web Services (JAX-WS) は、 サービス・エンドポイント操作の動的呼び出しをサポートします。
このタスクについて
JAX-WS は、新規の動的ディスパッチ・クライアント API を備えています。 これは、既存の Java API for XML-based RPC (JAX-RPC) ベースの動的起動インターフェース (DII) よりも 汎用的で、柔軟性があります。ディスパッチ・クライアント・インターフェースの javax.xml.ws.Dispatch は、XML メッセージング指向クライアントであり、 XML 構成体を使用して XML レベルで作業することを好む上級 XML 開発者向けです。 ディスパッチ・クライアントを作成するには、 ディスパッチ・クライアント API、サポートされるオブジェクト・タイプ、および関連した Web サービス記述言語 (WSDL) ファイルに関するメッセージ表記の知識に習熟している必要があります。
ディスパッチ API は、PAYLOAD モードまたは MESSAGE モードのいずれかでデータを送信できます。 PAYLOAD モードを使用する場合、ディスパッチ・クライアントは <soap:Body> の内容の提供を担当します。さらに、JAX-WS には <soap:Envelope> エレメントの入力ペイロードが含まれています。 MESSAGE モードを使用する場合、 ディスパッチ・クライアントは SOAP エンベロープ全体の提供を担当します。
- javax.xml.transform.Source: ソース・オブジェクトを使用して、クライアントが XML API を直接使用できるようにします。 ソース・オブジェクトは SOAP および HTTP バインディングと一緒に使用できます。
- JAXB オブジェクト: JAXB オブジェクトを使用して、クライアントが、XML スキーマから生成される JAXB オブジェクトを使用できるようにします。これにより、クライアントは、JAX-WS アプリケーションを使用して XML を作成および操作できるようになります。 JAXB オブジェクトは、SOAP および HTTP バインディングと一緒にのみ使用できます。
- javax.xml.soap.SOAPMessage: SOAPMessage オブジェクトを使用して、クライアントが SOAP メッセージを処理できるようにします。 SOAPMessage オブジェクト は、SOAP バージョン 1.1 または SOAP バージョン 1.2 のバインディングと一緒にのみ使用できます。
- javax.activation.DataSource: DataSource オブジェクトを使用して、 クライアントが Multipurpose Internet Mail Extension (MIME) メッセージを処理できるようにします。 DataSource は、HTTP バインディングと一緒にのみ使用してください。
手順
タスクの結果
WebSphere® Application Server バージョン 8.0 以降、サービス・メソッド addPort を使用して追加される JAX-WS 動的ポートでは、追加のメモリー所要量が必要となる場合があります。従来のリリースでは、動的ポートの 1 つのインスタンスを複数のサービス・インスタンスで共有することが可能でした。 バージョン 8.x では、動的ポートの有効範囲はこのサービスが追加したインスタンスだけになりました。JAX-WS クライアントに、同じ名前の動的ポートを参照する複数のサービス・インスタンスがある場合、そうしたインスタンスが共有されることはなくなりました。 これにより、そのクライアントでのメモリー所要量が増える可能性があります。 サービス・インスタンスが有効範囲からはずれると、動的ポートで使用されるメモリーが解放されます。 ただし、メモリー使用量が増加することに関連した問題が生じる場合、元の動作に戻し、動的ポートを複数のサービス・インスタンスで共有できるようにすることも可能です。 そうするためには、システム・プロパティー jaxws.share.dynamic.ports.enable を値 true に設定します。 ただし、このようにすると、共有される動的ポート間で、ポリシー・セットの関連付けが間違って適用されるなどの他の問題が発生する原因となる場合があります。 このフラグを true に設定してこうした問題が発生する場合には、このフラグ設定値を削除してください。
従来のリリースで SOAP Action がディスパッチ・クライアント・アプリケーションで提供されていない場合、アウトバウンド・メッセージで正しい SOAP Action が送信されませんでした。 SOAP Action は、代わりに匿名操作に設定されました。 WebSphere Application Server バージョン 8 以降、ディスパッチ・クライアント・アプリケーションで SOAP Action が提供されないと、JAX-WS ランタイム環境が出力メッセージを解析します。 それにより、呼び出されている操作が判別され、その情報に基づいて SOAP Action に対する適切な値が決まります。 アウトバウンド・メッセージの操作の解決は SOAP 本体とメッセージ・エンコード (Doc/Lit/Bare、Doc/Lit/Wrapped など) に基づいています。 この解析はコストが高くなる場合があるので、プロパティーを設定することができます。 解析を常時使用不可にする場合、このプロパティーをシステム・レベルで設定します。 メッセージ単位で解析を使用不可にするには、JAX-WS 要求メッセージ・コンテキストでこのプロパティーを設定します。 このプロパティーは、定数 org.apache.axis2.jaxws.Constants.DISPATCH_CLIENT_OUTBOUND_RESOLUTION にストリング値 jaxws.dispatch.outbound.operation.resolution.enable を指定して定義します。 このプロパティーのデフォルト値は NULL で、その場合にはストリング true として解釈され、アウトバウンド操作の解決が有効になります。 このプロパティーを false に設定すると、アウトバウンド操作の解決は無効になります。 解析が無効になると、アウトバウンド・メッセージの SOAP Action はこれまでのリリース同様に匿名操作に設定されます。 クライアントが JAX-WS javax.xml.ws.BindingProvider プロパティーの SOAPACTION_USE_PROPERTY と SOAPACTION_URI_PROPERTY を使用して SOAP Action を提供すると、その SOAP Action が使用されます。 そのため、このプロパティーの設定値にかかわりなく、アウトバウンド・メッセージの解析は行われません。 クライアントが明示的に SOAP Action を設定するのが、ベスト・プラクティスであると見なされています。 特に、サービス・プロバイダーのパフォーマンスの観点からはそう言えます。 この方法によってインバウンド・メッセージは解析されずに、適切なエンドポイント操作に経路指定されます。
例
String endpointUrl = ...;
QName serviceName = new QName("http://com/ibm/was/wssample/echo/",
"EchoService");
QName portName = new QName("http://com/ibm/was/wssample/echo/",
"EchoServicePort");
/** Create a service and add at least one port to it. **/
Service service = Service.create(serviceName);
service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, endpointUrl);
/** Create a Dispatch instance from a service.**/
Dispatch<SOAPMessage> dispatch = service.createDispatch(portName,
SOAPMessage.class, Service.Mode.MESSAGE);
/** Create SOAPMessage request. **/
// compose a request message
MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
// Create a message. This example works with the SOAPPART.
SOAPMessage request = mf.createMessage();
SOAPPart part = request.getSOAPPart();
// Obtain the SOAPEnvelope and header and body elements.
SOAPEnvelope env = part.getEnvelope();
SOAPHeader header = env.getHeader();
SOAPBody body = env.getBody();
// Construct the message payload.
SOAPElement operation = body.addChildElement("invoke", "ns1",
"http://com/ibm/was/wssample/echo/");
SOAPElement value = operation.addChildElement("arg0");
value.addTextNode("ping");
request.saveChanges();
/** Invoke the service endpoint. **/
SOAPMessage response = dispatch.invoke(request);
/** Process the response. **/