16.5.2. JAX-WS クライアントアプリケーションの開発
サービス
- 概要
- A
Service
WSDL サービスを表す抽象化です。WSDL サービスは、一連の関連ポートです。それぞれには、特定のプロトコルとエンドポイントアドレスに結合したポートタイプが含まれます。通常、サービスの生成は、残りのコンポーネントのスタブが、既存の WSDL コントラクトから生成されると行われます。WSDL コントラクトは、デプロイされたエンドポイントの WSDL URL 経由で利用できます。または、EAP_HOME/bin/
ディレクトリーのwsprovide.sh
コマンドを使用してエンドポイントソースから作成できます。このタイプの使用は、static ユースケースと呼ばれます。この場合、コンポーネントのスタブのいずれかとして作成されたService
クラスのインスタンスを作成します。を使用して、サービスを手動で作成することもできます。Service.create
方法。これは、dynamic ユースケースと呼ばれます。 - 用途
- 静的ユースケース
- JAX-WS クライアントの static ユースケースでは、すでに WSDL コントラクトが存在することを前提としています。これは外部ツールで生成されるか、JAX-WS エンドポイントの作成時に適切な JAX-WS アノテーションを使用して生成される可能性があります。コンポーネントスタブを生成するには、
wsconsume.sh
またwsconsume.bat
EAP_HOME/bin/
に含まれているスクリプト。このスクリプトは、WSDL URL またはファイルをパラメーターとして受け取り、ディレクトリーツリーで構造化された複数のファイルを生成します。を表すソースファイルとクラスファイルService
名前が付けられていますCLASSNAME_Service.java
とCLASSNAME_Service.class
、それぞれ。生成された実装クラスには、引数のないパブリックコンストラクターと、2 つの引数を持つコンストラクターがあります。2 つの引数は、WSDL の場所を表します (java.net.URL
) およびサービス名 (ajavax.xml.namespace.QName
) それぞれ。引数なしのコンストラクターは最もよく使用されます。この場合、WSDL の場所とサービス名は WSDL にあるものです。これらは、から暗黙的に設定されます@WebServiceClient
生成されたクラスを装飾するアノテーション。例16.19 生成されたサービスクラスの例
@WebServiceClient(name="StockQuoteService", targetNamespace="http://example.com/stocks", wsdlLocation="http://example.com/stocks.wsdl") public class StockQuoteService extends javax.xml.ws.Service { public StockQuoteService() { super(new URL("http://example.com/stocks.wsdl"), new QName("http://example.com/stocks", "StockQuoteService")); } public StockQuoteService(String wsdlLocation, QName serviceName) { super(wsdlLocation, serviceName); } ... }
- 動的ユースケース
- 動的の場合、スタブは自動的に生成されません。代わりに、Web サービスクライアントは
Service.create
作成する方法Service
インスタンス。以下のコードはこのプロセスを示しています。例16.20 手動でサービスを作成する
URL wsdlLocation = new URL("http://example.org/my.wsdl"); QName serviceName = new QName("http://example.org/sample", "MyService"); Service service = Service.create(wsdlLocation, serviceName);
- ハンドラー解決
- JAX-WS は、handlers と呼ばれるメッセージ処理モジュールに柔軟なプラグインフレームワークを提供します。これらのハンドラーは JAX-WS ランタイムシステムの機能を拡張します。A
Service
インスタンスはへのアクセスを提供しますHandlerResolver
のペアを介してgetHandlerResolver
とsetHandlerResolver
サービスごと、ポートごと、またはプロトコルごとのバインディングに基づいて一連のハンドラーを設定できるメソッド。いつService
インスタンスはプロキシーまたはDispatch
たとえば、現在サービスに登録されているハンドラーリゾルバーは、必要なハンドラーチェーンを作成します。に設定されたハンドラーリゾルバーへのその後の変更Service
インスタンスは、以前に作成されたプロキシーのハンドラーに影響を与えません。Dispatch
インスタンス。 - エグゼキューター (Executor)
Service
インスタンスは、java.util.concurrent.Executor
。TheExecutor
アプリケーションによって要求された非同期コールバックを呼び出します。ThesetExecutor
とgetExecutor
の方法Service
変更および取得できますExecutor
サービス用に設定されています。
動的プロキシー
動的プロキシー は、次のいずれかを使用するクライアントプロキシーのインスタンスです。getPort
で提供されるメソッドService
。TheportName
サービスが使用する WSDL ポートの名前を指定します。TheserviceEndpointInterface
作成された動的プロキシーインスタンスでサポートされるサービスエンドポイントインターフェイスを指定します。
例16.21 getPort
Methods
public <T> T getPort(QName portName, Class<T> serviceEndpointInterface) public <T> T getPort(Class<T> serviceEndpointInterface)
wsconsume.sh
ツールを使用して生成されます。これは、WSDL を解析し、そこから Java クラスを作成します。
例16.22 サービスのポートを返す
@WebServiceClient(name = "TestEndpointService", targetNamespace = "http://org.jboss.ws/wsref", wsdlLocation = "http://localhost.localdomain:8080/jaxws-samples-webserviceref?wsdl") public class TestEndpointService extends Service { ... public TestEndpointService(URL wsdlLocation, QName serviceName) { super(wsdlLocation, serviceName); } @WebEndpoint(name = "TestEndpointPort") public TestEndpoint getTestEndpointPort() { return (TestEndpoint)super.getPort(TESTENDPOINTPORT, TestEndpoint.class); } }
@WebServiceRef
The@WebServiceRef
アノテーションは、Web サービスへの参照を宣言します。これは、で定義される javax.annotation.Resource
アノテーションで示されるリソースパターンに http://www.jcp.org/en/jsr/summary?id=250 従います。
のユースケース @WebServiceRef
- これを使用して、生成されたタイプの参照を定義できます
Service
クラス。この例では、type および value 要素はそれぞれ、生成されたService
クラスタイプを参照します。さらに、リファンレンスタイプがアノテーションが適用されるフィールドまたはメソッド宣言によって推定される場合、type および value 要素にはデフォルト値のObject.class
が設定されることがあります。これは必須ではありません。タイプを推定できない場合、type 要素がデフォルト以外の値を持つ必要があります。 - これは、タイプが SEI のリファンレスを定義するのに使用できます。この場合、リファレンスのタイプが annotated フィールドまたは method 宣言から推測される場合、type 要素はデフォルト値で存在することがあります (ただし、必須ではありません)。ただし、value 要素は常に存在し、生成されたサービスクラスターイプを参照する必要があります。これは、
javax.xml.ws.Service
。ThewsdlLocation
要素が存在する場合は、で指定された WSDL ロケーション情報をオーバーライドします。@WebService
参照された生成されたサービスクラスのアノテーション。例16.23
@WebServiceRef
例:public class EJB3Client implements EJB3Remote { @WebServiceRef public TestEndpointService service4; @WebServiceRef public TestEndpoint port3;
Dispatch
XML Web サービスは、Java EE コンテナーおよびすべてのクライアントにデプロイされる、エンドポイント間の通信に XML メッセージを使用します。XML メッセージは、Simple Object Access Protocol (SOAP) と呼ばれる XML 言語を使用します。JAX-WS API は、エンドポイントとクライアントのメカニズムを提供し、各エンドポイントが SOAP メッセージを送受信できるようにします。マーシャリングは、Java オブジェクトを SOAP XML メッセージに変換するプロセスです。マーシャリング解除とは、SOAP XML メッセージを Java オブジェクトに変換するプロセスのことです。
Dispatch
クラスはこの機能を提供します。Dispatch
は、以下の定数のいずれかによって識別される、2 つの使用モードのいずれかで動作します。
javax.xml.ws.Service.Mode.MESSAGE
- このモードは、クライアントアプリケーションがプロトコル固有のメッセージ構造を直接操作するように指示します。SOAP プロトコルバインディングを使用すると、クライアントアプリケーションは SOAP メッセージで直接機能します。javax.xml.ws.Service.Mode.PAYLOAD
- このモードでは、クライアントはペイロード自体を操作します。たとえば、SOAP プロトコルバインディングと使用すると、クライアントアプリケーションは SOAP メッセージ全体ではなく SOAP ボディーのコンテンツで動作します。
Dispatch
は低レベルの API で、クライアントはメッセージまたはペイロードを XML として構成する必要があります。これは、個別のプロトコルの標準と、メッセージまたはペイロード構造の詳細な知識とメッセージに忠実に従った状態を意味します。Dispatch
は、メッセージの入出力または、任意のタイプのメッセージペイロードに対応した汎用クラスです。
例16.24 Dispatch
用途
Service service = Service.create(wsdlURL, serviceName); Dispatch dispatch = service.createDispatch(portName, StreamSource.class, Mode.PAYLOAD); String payload = "<ns1:ping xmlns:ns1='http://oneway.samples.jaxws.ws.test.jboss.org/'/>"; dispatch.invokeOneWay(new StreamSource(new StringReader(payload))); payload = "<ns1:feedback xmlns:ns1='http://oneway.samples.jaxws.ws.test.jboss.org/'/>"; Source retObj = (Source)dispatch.invoke(new StreamSource(new StringReader(payload)));
非同期呼び出し
TheBindingProvider
インターフェイスは、クライアントが使用できるプロトコルバインディングを提供するコンポーネントを表します。これはプロキシーによって実装され、Dispatch
インターフェイス。
BindingProvider
インスタンスは非同期操作機能を提供する場合があります。非同期操作の呼び出しは、BindingProvider
呼び出し時のインスタンス。操作が完了しても、応答コンテキストは更新されません。代わりに、別の応答コンテキストが使用可能になりますResponse
インターフェイス。
例16.25 非同期呼び出しの例
public void testInvokeAsync() throws Exception { URL wsdlURL = new URL("http://" + getServerHost() + ":8080/jaxws-samples-asynchronous?wsdl"); QName serviceName = new QName(targetNS, "TestEndpointService"); Service service = Service.create(wsdlURL, serviceName); TestEndpoint port = service.getPort(TestEndpoint.class); Response response = port.echoAsync("Async"); // access future String retStr = (String) response.get(); assertEquals("Async", retStr); }
@Oneway
呼び出し
@Oneway
アノテーションは、指定の web メソッドが入力メッセージを取得し、出力メッセージを返しないことを示します。通常、@Oneway
メソッドは、ビジネスメソッドの実行前に、制御のスレッドを呼び出しアプリケーションに戻します。
例16.26 例@Oneway
呼び出し
@WebService (name="PingEndpoint") @SOAPBinding(style = SOAPBinding.Style.RPC) public class PingEndpointImpl { private static String feedback; @WebMethod @Oneway public void ping() { log.info("ping"); feedback = "ok"; } @WebMethod public String feedback() { log.info("feedback"); return feedback; } }
タイムアウトの設定
2 種類のプロパティーが HTTP 接続のタイムアウトの動作と、メッセージの受信を待機しているクライアントのタイムアウトを制御します。最初はjavax.xml.ws.client.connectionTimeout
そして 2 番目はjavax.xml.ws.client.receiveTimeout
。それぞれはミリ秒単位で示され、正しい構文を以下に示します。
例16.27 JAX-WS タイムアウト設定
public void testConfigureTimeout() throws Exception { //Set timeout until a connection is established ((BindingProvider)port).getRequestContext().put("javax.xml.ws.client.connectionTimeout", "6000"); //Set timeout until the response is received ((BindingProvider) port).getRequestContext().put("javax.xml.ws.client.receiveTimeout", "1000"); port.echo("testTimeout"); }