Apache-SOAPは、SOAPをJavaで利用するためのライブラリだと思っていただければいいだろう。元はIBMのalphaWorksで扱っていたIBM-SOAP(SOAP4J) V1.2で、それがApacheに出たものである。
これ以降、サービスという言葉をよく使うので解説しておこう。SOAPの世界ではサーバ側にあるメソッドのことを「サービス」と呼ぶ。サービスはSOAPのサーバ機能(XML-SOAPメッセージを解読してオブジェクトにマッピングしたり、その逆を行う)のプログラムに登録されていないと呼び出すことができない。この登録の作業を「サービスのデプロイ(deploy)」といい、削除することを「アンデプロイ(undeploy)」という。サービスを提供するのは、サーバ側でインスタンス化されたオブジェクトだが、これを「ターゲット・オブジェクト」という。そして、アクセスするのは「クライアント」である。
Apache-SOAPには、次のものが含まれている。
これらの機能はすべてJavaで実装されており、「soap.jar」ファイルにて提供されている。
また、Apache-SOAPは次のような特徴を持っている。
Apache-SOAPは、単独では動かない(当たり前だが)。Apache-SOAPは、Java WebアプリケーションサーバをSOAP対応に変身させるためのものなので、それなりのサーバ製品が必要である。また、仕様の紹介でも触れたが、名前空間を使うために、名前空間をサポートしたXMLパーサが必要である。現状では、Apache-SOAPは、同じくApacheが提供しているXerces V1.1.2以上を使わなければならない。以上をまとめると、以下のようになる。
ただし、ここに一覧されていないサーバでも、組み込めば動くと思われる。ただし、Servlet API 2.2をサポートしている必要がある。
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から導入手順のリンクをたどると載っている。
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文書を準備してバッチプログラムで登録する方法も準備しているが、解説は省略する。
クライアントコードでは、以下の手順を行う必要がある。
先ほどのサービス「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.