Apache-SOAP V2.0を使ってみよう
Apache-SOAPは、SOAPをJavaで利用するためのライブラリだと思っていただければいいだろう。元はIBMのalphaWorksで扱っていたIBM-SOAP(SOAP4J) V1.2で、それがApacheに出たものである。
■Webサービス
これ以降、サービスという言葉をよく使うので解説しておこう。SOAPの世界ではサーバ側にあるメソッドのことを「サービス」と呼ぶ。サービスはSOAPのサーバ機能(XML-SOAPメッセージを解読してオブジェクトにマッピングしたり、その逆を行う)のプログラムに登録されていないと呼び出すことができない。この登録の作業を「サービスのデプロイ(deploy)」といい、削除することを「アンデプロイ(undeploy)」という。サービスを提供するのは、サーバ側でインスタンス化されたオブジェクトだが、これを「ターゲット・オブジェクト」という。そして、アクセスするのは「クライアント」である。
■Apache-SOAPの構成と特徴
Apache-SOAPには、次のものが含まれている。
- WebサーバをSOAPサーバにするためのサーバ機能
JSPファイルとその後ろに動くJavaプログラムである。 - サーバの設定を行うための画面(JSP)とコマンドプログラム
主に、サービスの登録や削除を行う。 - サーバにアクセスするためのクライアント用API
- デバッグツール「TCPトンネル・モニタ」
これらの機能はすべてJavaで実装されており、「soap.jar」ファイルにて提供されている。
また、Apache-SOAPは次のような特徴を持っている。
- SOAP V1.1のほとんどの規約をサポート
- 3つのエンコーディングをサポート
SOAPエンコーディング、XMI、リテラルXML - HTTPとSMTPをトランスポートとして利用可能
- BSF(Bean Scripting Framework)により、スクリプト言語によるサービスの実装が可能
■Apache-SOAPの稼働環境
Apache-SOAPは、単独では動かない(当たり前だが)。Apache-SOAPは、Java WebアプリケーションサーバをSOAP対応に変身させるためのものなので、それなりのサーバ製品が必要である。また、仕様の紹介でも触れたが、名前空間を使うために、名前空間をサポートしたXMLパーサが必要である。現状では、Apache-SOAPは、同じくApacheが提供しているXerces V1.1.2以上を使わなければならない。以上をまとめると、以下のようになる。
- Apache-SOAP
- Xerces 1.1.2以降
- サーブレット・JSPをサポートする次のサーバのどれか
Apache Tomcat
IBM WebSphere Application Server V3.5
BEA WebLogic V5.1
Allaire JRun
Microsoft Internet Information Server(IIS)
ただし、ここに一覧されていないサーバでも、組み込めば動くと思われる。ただし、Servlet API 2.2をサポートしている必要がある。
■Apache-SOAPのドキュメント
Apache-SOAPは、zipファイルで提供されており、展開するとsoap-2.0といったディレクトリができる。ドキュメントはReleaseNote.htmlを開くと、そこからリンクが張られているのでそれらを参照していただければいいと思う。残念ながらこのドキュメントは英語であるが、ユーザーズ・ガイド、導入手順、WebSphereでの導入手順などを筆者が日本語に訳したものをIBM-TRL(東京基礎研究所)のサイトに置いたのでご利用いただきたい。
http://www.trl.ibm.co.jp/projects/xml/soap/xml-soap/java/ReleaseNotes-j.html
■導入手順
まず、当然のことながらアプリケーションサーバがセットアップを完了している必要がある。さらに、アプリケーションのXMLパーサがXercesのJARファイル(xerces.jar)を探し出せるようにしておく必要がある。通常、アプリケーションサーバのクラスパスの先頭にxerces.jarがくるように設定する。一部のサーバでは構成ファイルを修正しないといけないものもあるので、注意が必要である。同様にsoap.jarも組み込む。そして、SOAPのサーバ機能(rpcrouter.jsp)をアプリケーションサーバに登録すれば準備完了である。これらの手順は、Apache-SOAPのReleaseNote.htmlから導入手順のリンクをたどると載っている。
■SOAPでRPCアプリケーションを作ってみよう
Apache-SOAPのRPCアプリケーションは、次の手順で作る。
- サービスを提供するコードを準備する
- サービスを配置する
- サービスにアクセスするクライアントコードを開発する
サービスを提供するコードには、SOAPらしいコードは必要ない。既存のオブジェクトでよい。例えば、次のような簡単なコードを考えてみよう。
public class Userinfo { public String getPassword(String userid) { if(userid.equals("Yonemochi")) { return("pass1"); } else if(userid.equals("Pandrbox")) { return("pass2"); } else return("Unknown"); } }
この「Userinfo」クラスは、getPassword(String)というメソッドを持っており、ユーザーIDを引数として渡すとパスワードを返す、というものである。これをコンパイルしてサーバが見つけられるクラスパス上に置く。
■サービスの配置
次に必要なのは、サービスの配置である。分散オブジェクトを行うシステムでは、オブジェクトをサーバが認識している必要がある。SOAPでも、クラスには名前が付けられ、サービスとして登録しておく必要がある。サービスの登録にはいくつかセットしなければいけない項目があるが、今回は次の値を使うことにする。
ID | urn:userinfoservice | |
Scope | Request | |
ProviderType | java | |
ProviderClass | Userinfo | |
Use Static Class | false | |
Methods | getPassword | |
TypeMapping |
IDはこのサービスに付けられる固有の名前で自由に付けてよいが、「urn:xxxx」形式にする。Scopeは、JSPのSCOPEタグと似たようなもので、リクエストを指定するとリクエスト単位でオブジェクトが有効になる。ProviderTypeはJavaであるか、スクリプトであるか、などを指定する。ProviderClassには、クラス名を指定する。Use Static Classは、falseの場合インスタンスを生成してメソッド呼び出しが行われる。trueの場合、staticメソッドと認識され、static呼び出しが行われる。その場合、当然メソッドはstaticである必要がある。そしてmethod名をブランク区切りで一覧記述する。TypeMappingは、カスタム・シリアライザを使うときのみ指定するので、今回は必要ない。
サービスを登録するためには、Apache-SOAPをセットアップしたアプリケーションサーバを起動し、ブラウザで次のURLにアクセスする。
http://localhost/soap
すると、XML-SOAP Adminというページが表示されるはずだ(画面1)。左側に表示される「Deploy」ボタンを押し、先ほどのデータを入力してデプロイを完了する。
Apache-SOAPでは、デプロイメント・ディスクリプタ(配置記述)というXML文書を準備してバッチプログラムで登録する方法も準備しているが、解説は省略する。
■クライアントコードの作成
クライアントコードでは、以下の手順を行う必要がある。
- Callオブジェクトのインスタンス化
ターゲット・オブジェクト、メソッド名、エンコーディングのセット - Parameterオブジェクトの準備とVectorへの追加
- VectorをCallオブジェクトへセット
- URLオブジェクトをセットして、invoke()の呼び出し
- Responseオブジェクトの取り出し
- getReturnValueにて、戻り値の取り出し
先ほどのサービス「urn:userinfoservice」の「getPassword」にアクセスするためのクライアントコードは次のようになる。
import java.io.*; import java.net.URL; import java.util.Vector; import org.apache.soap.Constants; import org.apache.soap.rpc.*; public class GetPassword { // parm1 = userid, parm2 = URL public static void main(String[] args) { String urlString = "http://localhost:8080/soap/servlet/rpcrouter"; if(args.length > 1) urlString = args[1]; Call c = new Call(); c.setTargetObjectURI("urn:userinfoservice"); c.setMethodName("getPassword"); c.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); Vector v = new Vector(); v.addElement( new Parameter("num1", String.class, args[0], null) ); c.setParams(v); try { Response r = c.invoke(new URL(urlString), ""); Parameter result = r.getReturnValue(); System.out.println("PASSWORD:"+result.getValue()); } catch(Exception e) { e.printStackTrace(); } } }
ここで、URLなどは適宜調整していただきたい。
見慣れないクラスとして「Call」、「Parameter」、「Response」がある。これらは、Apache-SOAPのクラスである。Callオブジェクトは、Parameterオブジェクトを、内部でVectorとして維持しており、invoke()メソッドにより、SOAPを通してサーバに送信される。Callオブジェクトはサーバ側で復元されてメソッドの呼び出しに使われ、Responseオブジェクトが作られてSOAPで送り返されてくる。Responseオブジェクトの中には、メソッドの戻り値がParameterオブジェクトとして封入されており、invoke()メソッドの戻り値として返される。これを取り出せば、メソッドの戻り値が得られるという具合である。
これをコンパイルするには、soap.jarをクラスパスに入れておく必要があり、さらに実行時には、Apache-SOAPのランタイムが必要とするxerces.jarも必要になるので気を付けよう。
このプログラムを実行すると、次のように、結果が表示される。
> java GetPassword Yonemochi PASSWORD:pass1
さて、このやりとりを、先に紹介したTCPトンネル・モニタでのぞいてみよう。コマンドプロンプトで次のようにコマンドを入力する。
java org.apache.soap.util.net.TcpTunnelGui 8080 localhost 80
これで、localhost:8080にアクセスすると、トンネル・モニタを通ってlocalhost:80にアクセスすることができ、通過したフレームをのぞくことができる。送信および受信されたフレームを示す。
POST /soap/servlet/rpcrouter HTTP/1.0 Host: localhost:8080 Content-Type: text/xml Content-Length: 418 SOAPAction: "" <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <SOAP-ENV:Body> <ns1:getPassword xmlns:ns1="urn:userinfoservice" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <num1 xsi:type="xsd:string">Yonemochi</num1> </ns1:getPassword> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
HTTP/1.1 200 ok Date: Wed, 17 Jan 2001 15:40:20 GMT Server: IBM_HTTP_Server/1.3.12.1 Apache/1.3.12 (Win32) Set-Cookie: sesessionid=DVVAFIAAAAAABQFIAED2BRI;Path=/ Cache-Control: no-cache="set-cookie,set-cookie2" Expires: Thu, 01 Dec 1994 16:00:00 GMT Content-Length: 434 Connection: close Content-Type: text/xml;; charset=UTF-8 Content-Language: ja <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <SOAP-ENV:Body> <ns1:getPasswordResponse xmlns:ns1="urn:userinfoservice" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <return xsi:type="xsd:string">pass1</return> </ns1:getPasswordResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
今回は、SOAPの仕様の概説、およびJavaの実装であるApache-SOAPの使い方を概説した。次回は、SOAPのセキュリティについて概説する予定である。
Copyright © ITmedia, Inc. All Rights Reserved.