13.4.2. JAX-WS クライアントアプリケーションの開発


本トピックでは JAX-WS Web Service クライアントについて説明します。クライアントは JAX-WS エンドポイントと通信し、そこから作業を要求します。 JAX-WS エンドポイントは Java Enterprise Edition 6 コンテナにデプロイされています。以下で説明するクラス、メソッド、およびその他の実装に関する詳しい情報は、「JAX-WS 共通 API の参考資料」 ならびに JBoss EAP 6 に同梱されている Javadocs の該当箇所を参照してください。

サービス

概要
Service は WSDL サービスを表す抽象化です。WSDL サービスは関連ポートの集合で、それぞれには特定のプロトコルおよび特定のエンドポイントアドレスにバインドされたポート型が含まれます。
通常、サービスは既存の WSDL コントラクトから残りのコンポーネントスタブが生成されるときに生成されます。WSDL コントラクトはデプロイされたエンドポイントの WSDL URL を介して利用できます。もしくは EAP_HOME/bin/ ディレクトリーで wsprovide.sh コマンドを使用してエンドポイントソースから作成することもできます。
このようなタイプの使用法は静的ユースケースと呼ばれます。この場合、コンポーネントスタブの 1 つとして作成された Service クラスのインスタンスを作成します。
Service.create メソッドを使用して、手動でサービスを作成することも可能です。このような使用法は 動的ユースケースと呼ばれます。
使用法
静的ユースケース
JAX-WS クライアントの静的ユースケースは WSDL コントラクトがすでに存在することを前提としています。WDSL コントラクトは、外部ツールで生成するか、AX-WS エンドポイントの作成時に正しい JAX-WS アノテーションを使用して生成します。
コンポーネントスタブを生成するには、EAP_HOME/bin/ に格納された wsconsume.sh または wsconsume.bat のスクリプトを使用します。スクリプトは、WSDL URL またはファイルをパラメーターとして取り、ディレクトリーツリー構造の複数のファイルを生成します。 Service を表すソースおよびクラスのファイルはそれぞれ CLASSNAME_Service.javaCLASSNAME_Service.class と名付けられます。
生成された実装クラスには、引数のないパブリックコンストラクターと 2 つの引数を持つパブリックコンストラクターの 2 つがあります。2 つの引数は WSDL の場所 (java.net.URL) とサービス名 (javax.xml.namespace.QName) を表します。
引数のないコンストラクターは最も頻繁に使用されます。この場合、WSDL の場所とサービス名は WSDL に記述された設定となります。これらは、生成されたクラスをデコレートする @WebServiceClient アノテーションから暗黙的に設定されます。

例13.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 インスタンスを作成します。以下のコードフラグメントは、このプロセスの例を示しています。

例13.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 は、ハンドラー として知られるメッセージ処理モジュール向けの柔軟性の高いプラグインフレームワークを提供します。このようなハンドラーにより、JAX-WS ランタイムシステムの機能が拡張されます。Service インスタンスは、サービス、ポート、またはプロトコルバインディングごとにハンドラーのセットを設定できる getHandlerResolver メソッドと setHandlerResolver メソッドのペアを介して HandlerResolver へのアクセスを提供します。
Service インスタンスがプロキシまたは Dispatch インスタンスを作成する際には、現在サービスに登録されているハンドラーリゾルバーによって必要なハンドラーチェーンが作成されます。Service インスタンス用に設定されたハンドラーリゾルバーがそれ以降に変更されても、以前に作成されたプロキシや Dispatch インスタンスには影響を及ぼしません。
エグゼキューター
Service インスタンスは java.util.concurrent.Executor を使用して設定できます。Executor はアプリケーションが要求する任意の非同期コールバックを呼び出します。ServicesetExecutor メソッドと getExecutor のメソッドはサービス用に設定された Executor を変更および取得できます。
動的プロキシ

動的プロキシ とは、Service で提供される getPort メソッドの 1 つを使用するクライアントプロキシのインスタンスです。portName は、サービスが使用する WSDL ポートの名前を指定します。serviceEndpointInterface は、作成された動的プロキシインスタンスのサポートするサービスエンドポイントインターフェースを指定します。

例13.21 getPort メソッド

public <T> T getPort(QName portName, Class<T> serviceEndpointInterface)
public <T> T getPort(Class<T> serviceEndpointInterface)
サービスエンドポイントインターフェース は通常 wsconsume.sh コマンドを使用して生成されます。これにより WSDL が解析されて、Java クラスが作成されます。
ポートを返す、型指定されたメソッドも提供されます。このようなメソッドは、SEI を実装する動的プロキシも返します。以下の例を参照してください。

例13.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

@WebServiceRef アノテーションは Web サービスの参照を宣言します。これは http://www.jcp.org/en/jsr/summary?id=250 で定義されている javax.annotation.Resource アノテーションにより示されるリソースパターンに従います。

@WebServiceRef のユースケース

  • このアノテーションを使用して、型が生成された Service クラスである参照を定義できます。この場合、型要素と値要素はそれぞれ生成された Service クラス型を参照します。また、アノテーションが適用されるフィールドまたはメソッドの宣言によって参照型を推定できる場合、型要素および値要素にデフォルト値の Object.class を使用できますが、必須ではありません。型が推測できない場合は、少なくとも型要素をデフォルトでない値で示す必要があります。
  • このアノテーションを使用して型が SEI の参照を定義できます。この場合、アノテーションが付いたフィールドまたはメソッド宣言から参照型を推定できる場合、型要素にデフォルト値を使用できますが、必須ではありません。ただし、値要素は常に存在する必要があり、javax.xml.ws.Service のサブタイプである生成されたサービスクラス型を参照する必要があります。wsdlLocation 要素がある場合は、参照される生成されたサービスクラスの @WebService アノテーションで指定された WSDL の場所情報をオーバーライドします。

    例13.23 @WebServiceRef の例

    public class EJB3Client implements EJB3Remote
    {
       @WebServiceRef
       public TestEndpointService service4;
    
       @WebServiceRef
       public TestEndpoint port3;
    
Dispatch

XML Web Services は、Java EE コンテナ内にデプロイされたエンドポイントと任意のクライアントとの間の通信に XML メッセージを使用します。XML メッセージは Simple Object Access Protocol (SOAP) と呼ばれる XML 言語を使用します。JAX-WS API は、エンドポイントとクライアントがそれぞれ SOAP メッセージを送受信し、SOAP メッセージから Java (および Java から SOAP メッセージ) へ変換できるようにするメカニズムを提供します。これは marshalling および unmarshalling と呼ばれます。

場合によっては、変換の結果ではなく、raw SOAP メッセージ自体にアクセスする必要があります。Dispatch クラスはこの機能を提供します。Dispatch は、以下の定数の 1 つで特定される 2 つの使用モードの 1 つで動作します。
  • javax.xml.ws.Service.Mode.MESSAGE - このモードは、クライアントアプリケーションがプロトコル固有のメッセージ構造を使用して直接連動するように指示します。SOAP プロトコルバインディングと併用すると、クライアントアプリケーションは SOAP メッセージと直接連動します。
  • javax.xml.ws.Service.Mode.PAYLOAD - このモードを使用すると、クライアントはペイロード自体と連動します。たとえば、 SOAP プロトコルバインディングと併用した場合、クライアントアプリケーションは SOAP メッセージ全体ではなく、SOAP ボディのコンテンツと連動します。
Dispatch は、メッセージまたはペイロードを XML として構築する必要がある低レベルの API で、各プロトコルの標準やメッセージまたはペイロード構造の詳細知識に準拠します。Dispatch は、あらゆるタイプのメッセージまたはメッセージペイロードの入出力をサポートする、汎用クラスです。

例13.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)));
非同期呼び出し

BindingProvider インターフェースはクライアントが使用可能なプロトコルバインディングを提供するコンポーネントを表します。これはプロキシによって実装され、Dispatch インターフェースによって拡張されます。

BindingProvider インスタンスは非同期オペレーション機能を提供することが可能です。非同期オペレーション呼び出しは、呼び出し時に BindingProvider インスタンスから切り離されます。オペレーション完了時には、応答コンテキストは更新されず、その代わりに Response インターフェースを使用して別の応答コンテキストを利用できるようになります。

例13.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 メソッドは、ビジネスメソッドが実行される前に、制御のスレッドを呼び出し元アプリケーションに返します。

例13.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;
   }
}
タイムアウトの設定

HTTP 接続のタイムアウト動作およびメッセージの受信を待つクライアントのタイムアウトは 2 つの異なるプロパティーによって制御されます。HTTP 接続のタイムアウト動作を制御するプロパティーは javax.xml.ws.client.connectionTimeout で、javax.xml.ws.client.receiveTimeout はメッセージの受信を待つクライアントのタイムアウトを制御します。各プロパティーはミリ秒で指定されます。正しい構文は次のとおりです。

例13.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");
}
Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。 最新の更新を見る.

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

Theme

© 2026 Red Hat
トップに戻る