29.4. コントラクトリゾルバーの使用

概要

実行時に WSDL ドキュメントの場所を解決するための最も複雑なメカニズムは、独自のカスタムコントラクトリゾルバーを実装することです。これには、Apache CXF 固有の ServiceContractResolver インターフェイスの実装を提供する必要があります。また、カスタムリゾルバーをバスに登録する必要があります。

適切に登録されると、カスタムコントラクトリゾルバーを使用して、必要な WSDL およびスキーマドキュメントの場所が解決されます。

コントラクトリゾルバーの実装

コントラクトリゾルバーは、org.apache.cxf.endpoint.ServiceContractResolver インターフェイスの実装です。例29.3「ServiceContractResolver Interface」 で示されているように、このインターフェイスには getContractLocation() の単一のメソッドがあります。このメソッドは実装する必要があります。getContractLocation() はサービスの QName を受け取り、サービスの WSDL コントラクトの URI を返します。

例29.3 ServiceContractResolver Interface

public interface ServiceContractResolver
{
   URI getContractLocation(QName qname);
}

WSDL コントラクトの場所を解決するために使用されるロジックは、アプリケーション固有です。UDDI レジストリー、データベース、ファイルシステム上のカスタムの場所、または選択したその他のメカニズムからコントラクトの場所を解決するロジックを追加できます。

コントラクトリゾルバーをプログラムで登録

Apache CXF ランタイムがコントラクトリゾルバーを使用する前に、コントラクトリゾルバーレジストリーに登録する必要があります。コントラクトリゾルバーレジストリーは、org.apache.cxf.endpoint.ServiceContractResolverRegistry インターフェイスを実装します。ただし、独自のレジストリーを実装する必要はありません。Apache CXF は、org.apache.cxf.endpoint.ServiceContractResolverRegistryImpl クラスでデフォルトの実装を提供します。

コントラクトリゾルバーをデフォルトのレジストリーに登録するには、次の手順を実行します。

  1. デフォルトのバスオブジェクトへの参照を取得します。
  2. バスの getExtension() メソッドを使用して、バスからサービスコントラクトレジストリーを取得します。
  3. コントラクトリゾルバーのインスタンスを作成します。
  4. レジストリーの register() メソッドを使用して、コントラクトリゾルバーをレジストリーに登録します。

例29.4「コントラクトリゾルバーの登録」 は、デフォルトのレジストリーにコントラクトリゾルバーを登録するためのコードを示しています。

例29.4 コントラクトリゾルバーの登録

BusFactory bf=BusFactory.newInstance();
Bus bus=bf.createBus();

ServiceContractResolverRegistry registry = bus.getExtension(ServiceContractResolverRegistry);

JarServiceContractResolver resolver = new JarServiceContractResolver();

registry.register(resolver);

例29.4「コントラクトリゾルバーの登録」 のコードは、以下を行います。

バスインスタンスを取得します。

バスのコントラクトリゾルバーレジストリーを取得します。

コントラクトリゾルバーのインスタンスを作成します。

コントラクトリゾルバーをレジストリーに登録します。

設定を使用したコントラクトリゾルバーの登録

コントラクトリゾルバーを実装して、設定を通じてクライアントに追加することもできます。コントラクトリゾルバーは、ランタイムが設定を読み取り、リゾルバーをインスタンス化するときに、リゾルバーがそれ自体を登録するように実装されます。ランタイムが初期化を処理するため、クライアントがコントラクトリゾルバーを使用する必要があるかどうかを実行時に決定できます。

設定を通じてクライアントに追加できるようにコントラクトリゾルバーを実装するには、次の手順を実行します。

  1. コントラクトリゾルバー実装に init() メソッドを追加します。
  2. 例29.4「コントラクトリゾルバーの登録」に示すように、コントラクトリゾルバーをコントラクトリゾルバーのレジストリーに登録する init() メソッドにロジックを追加します。
  3. @PostConstruct アノテーションで init() メソッドを切り離します。

例29.5「設定を使用して登録できるサービスコントラクトリゾルバー」 は、設定を使用してクライアントに追加できるコントラクトリゾルバーの実装を示しています。

例29.5 設定を使用して登録できるサービスコントラクトリゾルバー

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.xml.namespace.QName;

import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;

public class UddiResolver implements ServiceContractResolver
{
  private Bus bus;
  ...

  @PostConstruct
  public void init()
  {
    BusFactory bf=BusFactory.newInstance();
    Bus bus=bf.createBus();
    if (null != bus)
    {
      ServiceContractResolverRegistry resolverRegistry = bus.getExtension(ServiceContractResolverRegistry.class);
      if (resolverRegistry != null)
      {
        resolverRegistry.register(this);
      }
    }
  }

  public URI getContractLocation(QName serviceName)
  {
    ...
  }
}

クライアントにコントラクトリゾルバーを登録するには、クライアントの設定に bean 要素を追加する必要があります。bean 要素の class 属性は、コントラクトリゾルバーを実装するクラスの名前です。

例29.6「Bean によるコントラクトリゾルバーの設定」 に、org.apache.cxf.demos.myContractResolver クラスによって実装される設定リゾルバーを追加する Bean を示します。

例29.6 Bean によるコントラクトリゾルバーの設定

<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  ...
  <bean id="myResolver" class="org.apache.cxf.demos.myContractResolver" />
  ...
</beans>

コントラクト解決命令

新しいプロキシーが作成されると、ランタイムはコントラクトレジストリーリゾルバーを使用してリモートサービスの WSDL コントラクトを見つけます。コントラクトリゾルバーレジストリーは、リゾルバーが登録される順序で、各コントラクトリゾルバーの getContractLocation() メソッドを呼び出します。登録されたコントラクトリゾルバーの 1 つから返された最初の URI を返します。

よく知られている共有ファイルシステムで WSDL コントラクトを解決しようとするコントラクトリゾルバーを登録した場合、それが使用される唯一のコントラクトリゾルバーになります。ただし、UDDI レジストリーを使用して WSDL の場所を解決するコントラクトリゾルバーを後で登録した場合、レジストリーは両方のリゾルバーを使用してサービスの WSDL コントラクトを見つけることができます。レジストリーは、最初に共有ファイルシステムコントラクトリゾルバーを使用してコントラクトを見つけようとします。そのコントラクトリゾルバーが失敗した場合、レジストリーは UDDI コントラクトリゾルバーを使用してそれを見つけようとします。