27 動的プロキシ・クライアントの開発

この章では、静的プロキシ・クライアントと動的プロキシ・クライアントの違いを明確にするとともに、Java API for XML Web Services (JAX-WS)を使用したWebLogic Webサービスの動的プロキシ・クライアントを開発するステップについて説明します。

この章の内容は次のとおりです:

静的プロキシ・クライアントと動的プロキシ・クライアントの概要

表27-1は、静的プロキシ・クライアントと動的プロキシ・クライアントの違いを示しています。

表27-1 静的プロキシ・クライアントと動的プロキシ・クライアントの比較

プロキシ・クライアントのタイプ 説明

静的プロキシ・クライアント

開発時にWebサービス・クライアントをコンパイルしてバインドします。これにより、Webサービス・クライアント・プロキシの静的スタブが生成されます。生成される静的スタブ・クライアントのソース・コードは、特定のサービス実装に依存します。そのため、このオプションには柔軟性がほとんどありません。

静的プロキシ・クライアントの例は、次を参照してください。

動的プロキシ・クライアント

開発時には何もコンパイルしません。実行時にアプリケーションがWSDLの取得および解析を行い、動的に呼出しを構成します。動的プロキシ・クライアントを使用すると、実行時にclientgenを使用することなく、サービス・エンドポイント・インタフェース(SEI)に基づいて、Webサービス・クライアントからWebサービスを動的に呼び出すことが可能になります。このオプションは、特定のサービス実装に依存しないため柔軟性は増しますが、パフォーマンス・ヒットも大きくなります。

動的プロキシ・クライアントの開発ステップは、「動的プロキシ・クライアントの開発ステップ」を参照してください

動的プロキシ・クライアントの開発ステップ

動的プロキシ・クライアントを作成するステップを次の表に示します。詳細は、javax.xml.ws.ServiceのJavadoc (http://docs.oracle.com/javase/8/docs/api/javax/xml/ws/Service.html)を参照してください。

表27-2 動的プロキシ・クライアントの作成ステップ

# ステップ 説明

1

javax.xml.ws.Serviceインスタンスの作成

Service.createメソッドを使用してServiceインスタンスを作成します。

サービス名と、必要に応じてWSDLドキュメントの格納場所を渡す必要があります。メソッドの詳細は次のとおりです。

public static Service create (QName serviceName) throws javax.xml.ws.WebServiceException {}
public static Service create (URL wsdlDocumentLocation, QName serviceName) throws javax.xml.ws.WebServiceException {}

たとえば:

URL wsdlLocation = new URL("http://example.org/my.wsdl");
QName serviceName = new QName("http://example.org/sample", "MyService");
Service s = Service.create(wsdlLocation, serviceName);

使用方法に関するその他の情報は、「WSDLの場所を指定する際のその他の考慮事項」を参照してください。

2

プロキシ・スタブを作成します。

Service.getPortメソッドを使用してプロキシ・スタブを作成します。このスタブを使用すると、ターゲット・サービス・エンドポイント上の操作を呼び出すことができます。

サービス・エンドポイント・インタフェース(SEI)と、必要に応じてWSDLサービス記述内のポートの名前を渡す必要があります。メソッドの詳細は次のとおりです。

public <T> T getPort(QName portName, Class<T> serviceEndpointInterface) throws javax.xml.ws.WebServiceException {}
public <T> T getPort(Class<T> serviceEndpointInterface) throws javax.xml.ws.WebServiceException {}

たとえば:

MyPort port = s.getPort(MyPort.class);

WSDLの場所を指定する際のその他の考慮事項

HTTPSを使用してWSDLからWebサービスを取得する際に、WebLogic Server SSL証明書のホスト名定義がピアHTTPSサーバーのホスト名と同一ではない場合、または次のいずれかではない場合には、ホスト名検証エラーが発生して処理が失敗します。

  • localhost

  • 127.0.0.1

  • localhostのホスト名

  • localhostのIPアドレス

ホスト名検証エラーは次のとおりです。

EchoService service = new EchoService(https-wsdl, webservice-qName);
:
:
javax.xml.ws.WebServiceException: javax.net.ssl.SSLKeyException:  
Security:090504 Certificate chain received from host.example.com - 192.0.2.1
failed hostname verification check. Certificate contained {....} but
check expected host.example.com

推奨される回避策は、サービスを作成する際にHTTPSではなくHTTPを使用してWSDLからWebサービスを取得すること、そしてサービスの作成後に独自のホスト名検証コードを使用してホスト名を検証することです。

EchoService service = Service.create(http_wsdl, qname);
//get Port
EchoPort port = service.getPort(...);
//set self-defined hostname verifier
((BindingProvider) port).getRequestContext().put(
      com.sun.xml.ws.developer.JAXWSProperties.HOSTNAME_VERIFIER,
      new  MyHostNameVerifier());
/*
*/  

必要に応じて、バインディング・プロバイダ・プロパティを設定してホスト名検証を無視することもできます。

((BindingProvider) port).getRequestContext().put(
      BindingProviderProperties.HOSTNAME_VERIFICATION_PROPERTY,
      "true");

ただし、HTTPSを使用してWSDLからWebサービスを取得する必要がある場合は、いくつかの回避策が考えられます。

  • WebLogic Server HTTPS接続を使用している場合は、ホスト名検証を無効にします。これを行うには、ホスト名検証を無視するグローバル・システム・プロパティを設定します。

    weblogic.security.SSL.ignoreHostnameVerification=true
    

    接続がJDK接続またはその他の非WebLogic Server接続の場合、このシステム・プロパティはサービスの作成には使用できません。

  • WSDLからWebサービスを取得する前に接続に対する独自のホスト名検証を設定し、その後HTTPSを使用してWSDLからWebサービスを取得します。

    //set self-defined hostname verifier
    URL url = new URL(https_wsdl);
    HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
    connection.setHostnameVerifier(new MyHostNameVerifier());
     
    //then initiate the service
    EchoService service = Service.create(https_wsdl, qname);
     
    //get port and set self-defined hostname verifier to binding provider
    ... 

回避策として独自のホスト名検証を設定する場合のホスト名検証の例を次に示します。

public class MyHostnameVerifier implements HostnameVerifier {
    public boolean verify(String hostname, SSLSession session) {
            if (hostname.equals("the host you want"))
          return true;
           else
               return false;
    }
}