連載
» 2001年03月02日 00時00分 公開

SOAPの仕掛け(1):SOAPの仕掛けはどうなっている? (3/3)

[米持幸寿,日本アイ・ビー・エム株式会社]
前のページへ 1|2|3       

Apache-SOAP V2.0を使ってみよう

 Apache-SOAPは、SOAPをJavaで利用するためのライブラリだと思っていただければいいだろう。元はIBMのalphaWorksで扱っていたIBM-SOAP(SOAP4J) V1.2で、それがApacheに出たものである。

Webサービス

 これ以降、サービスという言葉をよく使うので解説しておこう。SOAPの世界ではサーバ側にあるメソッドのことを「サービス」と呼ぶ。サービスはSOAPのサーバ機能(XML-SOAPメッセージを解読してオブジェクトにマッピングしたり、その逆を行う)のプログラムに登録されていないと呼び出すことができない。この登録の作業を「サービスのデプロイ(deploy)」といい、削除することを「アンデプロイ(undeploy)」という。サービスを提供するのは、サーバ側でインスタンス化されたオブジェクトだが、これを「ターゲット・オブジェクト」という。そして、アクセスするのは「クライアント」である。

図4 クライアントとApache-SOAPの関係 図4 クライアントとApache-SOAPの関係

Apache-SOAPの構成と特徴

 Apache-SOAPには、次のものが含まれている。

  1. WebサーバをSOAPサーバにするためのサーバ機能
    JSPファイルとその後ろに動くJavaプログラムである。
  2. サーバの設定を行うための画面(JSP)とコマンドプログラム
    主に、サービスの登録や削除を行う。
  3. サーバにアクセスするためのクライアント用API
  4. デバッグツール「TCPトンネル・モニタ」

 これらの機能はすべてJavaで実装されており、「soap.jar」ファイルにて提供されている。

 また、Apache-SOAPは次のような特徴を持っている。

  1. SOAP V1.1のほとんどの規約をサポート
  2. 3つのエンコーディングをサポート
    SOAPエンコーディング、XMI、リテラルXML
  3. HTTPとSMTPをトランスポートとして利用可能
  4. BSF(Bean Scripting Framework)により、スクリプト言語によるサービスの実装が可能

Apache-SOAPの稼働環境

 Apache-SOAPは、単独では動かない(当たり前だが)。Apache-SOAPは、Java WebアプリケーションサーバをSOAP対応に変身させるためのものなので、それなりのサーバ製品が必要である。また、仕様の紹介でも触れたが、名前空間を使うために、名前空間をサポートしたXMLパーサが必要である。現状では、Apache-SOAPは、同じくApacheが提供しているXerces V1.1.2以上を使わなければならない。以上をまとめると、以下のようになる。

  1. Apache-SOAP
  2. Xerces 1.1.2以降
  3. サーブレット・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アプリケーションは、次の手順で作る。

  1. サービスを提供するコードを準備する
  2. サービスを配置する
  3. サービスにアクセスするクライアントコードを開発する

 サービスを提供するコードには、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」ボタンを押し、先ほどのデータを入力してデプロイを完了する。

画面1 XML-SOAP Adminの画面 画面1 XML-SOAP Adminの画面

 Apache-SOAPでは、デプロイメント・ディスクリプタ(配置記述)というXML文書を準備してバッチプログラムで登録する方法も準備しているが、解説は省略する。

クライアントコードの作成

 クライアントコードでは、以下の手順を行う必要がある。

  1. Callオブジェクトのインスタンス化
    ターゲット・オブジェクト、メソッド名、エンコーディングのセット
  2. Parameterオブジェクトの準備とVectorへの追加
  3. VectorをCallオブジェクトへセット
  4. URLオブジェクトをセットして、invoke()の呼び出し
  5. Responseオブジェクトの取り出し
  6. 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のセキュリティについて概説する予定である。

著者紹介

米持 幸寿
日本アイ・ビー・エム株式会社



前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

編集部からのお知らせ

8月8日10時30分〜16時30分の間、システムメンテナンスのため記事の一部表示や資料のダウンロードができなくなります。ご理解のほどよろしくお願いいたします。

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。