Menu Close

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

概要

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

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

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

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

例29.3 ServiceContractResolver インターフェース

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. init() メソッドに @PostConstruct アノテーションを付けます。

例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() メソッドを呼び出します。登録したコントラクトリゾルバーのいずれかから返された最初の URI を返します。

既知の共有ファイルシステムにある WSDL コントラクトの解決を試みるコントラクトリゾルバーを登録した場合、使用するコントラクトリゾルバーはそれだけです。ただし、その後 UDDI レジストリーを使用して WSDL の場所を解決するコントラクトリゾルバーを登録した場合、レジストリーは両方のリゾルバーを使用してサービスの WSDL コントラクトを探すことができます。レジストリーは、始めに共有ファイルシステムのコントラクトリゾルバーを使用してコントラクトの特定を試みます。そのコントラクトリゾルバーが失敗すると、レジストリーは UDDI コントラクトリゾルバーを使用して特定を試みます。