今月も引き続きJAX-WSについて紹介していきます。

前回からちょっと間が開いてしまったので,少しおさらいをしましょう。

JAX-WS (Java API for XML-Based Web Services)はWebサービスを扱うためのAPIです。JAX-WSで提供しているのはサーバとクライアントの両方ですが,Java SEではクライアントをメインにしたサブセットが採用されています。とはいうものの,テスト用にサーバ機能も若干含まれています。

前回前々回と,簡単なWebサービスのサンプルを構築しました。クライアントではjava.lang.reflect.Proxyクラスを使用した動的プロキシにより,ほとんどWebサービスということを意識せずにサービスを使用することが可能です。

さて,今週はもう少し低レベルなAPIを使ってWebサービスのクライアントを作ってみましょう。

なお,Webサービスのサーバ側は前回と同じHelloサービスを使用します。サーバの構築方法については前々回の記事を参照してください。

プロキシを使用せずにクライアントを構築する

前回まで使用したクライアントのソースをもう一度示します。

import net.javainthebox.ws.Hello;
import net.javainthebox.ws.HelloService;
 
public class HelloClient {
    public HelloClient() {
        // Web サービスのポートを取得
        HelloService service = new HelloService();
        Hello port = service.getHelloPort();
 
        // Web サービスの実行
        String result = port.sayHello("World");
        System.out.println(result);
    }
 
    public static void main(String[] args) {
        new HelloClient();
    }
}

ここで行なっていることをまとめてみると,次のようになります。

  1. サービスを生成
  2. サービスからポート(プロキシ)を取得
  3. ポートに対してサービスをコール

前回,HelloServiceクラスはjavax.xml.ws.Serviceクラスの派生クラスだということは前回示しました。また,port変数はjava.lang.reflect.Proxyクラスの派生クラスのオブジェクトになります。この派生クラスはHelloインタフェースをインプリメントしていますが,それ以外にjavax.xml.ws.BindingProviderインタフェースをインプリメントしています。

このBindingProviderインタフェースがWebサービスを呼び出すときに中心になっているクラスなのです。

プロキシを扱わずにクライアントを構築する場合,このBindingProviderインタフェースをインプリメントしたクラスを自作する必要があります。

とはいうものの,BindingProviderインタフェースを直接扱うのはちょっと大変です。このインタフェースを直接扱う代わりに,JAX-WSではjavax.xml.ws.Dispatchインタフェースが提供されています。DispatchインタフェースはBindingProviderインタフェースの派生インタフェースです。

「でも,やっぱり実装クラスを作らなければいけないんじゃないの?」と思われるかもしれません。

でも,大丈夫。

ServiceクラスにはDispatchオブジェクトを生成するためのファクトリメソッドcreateDispatchが定義されています。このメソッドを使えば,Dipatchオブジェクトを取得することができます。

そして,Dispatchインタフェースにはinvokeメソッドが定義されています。このメソッドがWebサービスをコールする本体になります。

ここまで分かれば,後はサービスをコールするときの引数と戻り値をどうすればいいかというだけです。

この引数と戻り値の与え方には複数の方法があります。今週は,もっとも簡単なJAXBを用いた方法を紹介します。