今月も引き続き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(); } }
ここで行なっていることをまとめてみると,次のようになります。
- サービスを生成
- サービスからポート(プロキシ)を取得
- ポートに対してサービスをコール
前回,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を用いた方法を紹介します。