レベル: 初級 米持 幸寿, テクノロジー・エバンジェリスト, IBM
2006年 10月 10日 この記事では、日本アイ・ビー・エム研修サービス株式会社(以下LSJ)が提供する研修情報Webサービスにアクセスし、LSJの研修情報をインターネットから取得する手順を紹介します。
はじめに
日本IBMのWebサービス利用事例として、リコーテクノシステムズ様の「TIPS」が有名です。これは、社内システムに、複数の研修会社から研修情報をため込むシステムのデータ収集にWebサービスを利用している事例で、2002年6月から実際にインターネットで運用されています。2002年12月には、同システムに参加する豆蔵様と共に、このシステムを拡販していくことで協業することが発表されています。
このシステムでは、様々な企業が研修情報を提供します。研修や研修情報を提供する企業がWebサービスをインターネットに公開し、研修情報を取得できるようにしています。ここでは、日本アイ・ビー・エム研修サービス株式会社(以下LSJ)が提供する研修情報Webサービスにアクセスし、LSJの研修情報をインターネットから取得する手順を紹介します。開発にはWebSphereStudio Application Developer - Integration Edition V4.1.1を利用し、Javaプログラムから研修情報を取得します。(WebSphereStudioシリーズであれば、同じ手順で開発ができます。)
研修情報Webサービスのしくみ
研修情報Webサービスは、リコーテクノシステムズ様のプロジェクトにて、日本アイ・ビー・エムのエンジニアとともに設計されました。詳細な情報は、以下のサイトに掲載されています。
http://www.r-ts.co.jp/schemas/EducationSearch/EducationSearch.html
このドキュメントによれば、以下の2つのWebサービス・オペレーション(メソッド)を提供していることがわかります。
| メソッド名 | 引数 | 戻り値 | 機能 | |
getCourse
| String keyword | String ただし、XML courseResult.xsd
| keywordにカテゴリーされる研修の一覧をXML形式で返す | |
getSchedule
| String courseCode | String ただし、XML scheduleResult.xsd
| courseResultの /course/courseCode を渡し、スケジュール一覧をXML形式で返す |
どちらのメソッドも、ストリングを1つ引数に渡し、ストリングが1つ戻り値として受信できます。戻り値はストリングですが、中身がXMLです。このようにメソッドの引数や戻り値をストリングのみとして、中にXMLを入れてSOAPで通信することはSOAPらしい使い方ではありませんが、XMLを簡単に受渡する方法として利用できます。また、現状のSOAP-RPCでは、複数のベンダーを接続相手にするときに複雑なオブジェクトや配列を使うと、うまくいかないときがあります。このメソッドのようにストリング一つとしてXMLを入れるようにすれば、相互接続性が非常によくなります。(ただし、推奨できる方法ではありません。) これらのメソッドは、別々に利用することができますが、getScheduleメソッドには、getCourseメソッドで受信できるXMLに含まれるcourseCode(コースコード)を指定する必要があります。 Webサイトに貼り付けられているWSDLファイルには、<service>要素がありません。このWSDLファイルは「bindingWSDLファイル」とか、「インターフェースWSDLファイル」と呼ばれるもので、アクセスポイントから切り離された定義ファイルとして使われます。同じインターフェース+バインディング(SOAPなど)を持ったWebサービスを複数のサイトから提供するときに便利な使い方です。
LSJ のアクセスポイントは、UDDIから取得できます。
開発手順
このドキュメントでは、以下の手順でLSJの研修情報Webサービスにアクセスしてみます。
- WSDLファイルの入手
- Webサービス・プロキシー・クラスの生成
- UDDIからエンド・ポイント情報の取得
- 接続テスト
- XSDファイルの取得
- マッピングJava beanの生成
- マッピングJava beanファクトリー・クラスの改造
- 呼び出しコードの作成とテスト
接続
まずはWebサービスに接続してXMLを取得しましょう。
WSADでSOAPクライアントを作成する手順に自信の無い方は、同様の手順が、連載「WSADでWebサービスを作ってみよう!」にもありますので、そちらも参考にしてください。
Webプロジェクトの準備
Studioを起動したら、以下の手順を行います。
- Webプロジェクトを作成
- webApplicationフォルダーの下に「wsdl」フォルダーを作成
WSDLのインポート
WSDLファイルは、リコーテクノシステムズのサイトの説明文書にリンクがありますが、目次のリンクは同じページ内をさしているので、「2.定義ファイル」の下にあるリンクを使います。
http://www.r-ts.co.jp/schemas/EducationSearch/EducationSearch.wsdl
このファイルを、先程作成した「wsdl」フォルダーにインポートしてください。インポートするには以下の手順で行います。
- 「ファイル」?「インポート」メニューを選択
- 「インポート・ソースの選択」でHTTPを選択
- WSDLファイルのURLを指定
プロキシーの生成
インポートしたWSDLファイルを指定して、SOAPプロキシー・オブジェクトを生成します。
- ファイルを選択して右クリックし、「新規」?「その他」をクリック
- 左側でWebサービス、右側でWebサービス・クライアントを選択し、「次へ」ボタンをクリック
- 「サンプルの生成」、「サンプルの起動」、「警告なしにファイルを上書き」をチェックして「次へ」をクリック
- WSDLファイル名を確認して「終了」をクリック
エンド・ポイントをUDDIで探す
【生成されたプロキシーとサンプルJSPプログラム】
じつは、このままではプログラムは稼働しません。中身を見ていただけるとわかりますが、こWのSDLファイルには<service>要素が含まれていません。つまり、このWSDLファイルからは、SOAPのエンドポイントのアドレスがわからないのです。試しに、Methodsウィンドウで「getEndPoint」を選択して、Inputsウィンドウで「Invoke」ボタンをクリックして実行してみてください。MalformedURLExceptionが表示されるはずです。これは、エンドポイントがセットされていないからです。
さて、アドレスはどうやって知ったらいいでしょう。
このWebサービスは、UDDIに登録されています。ここで、IBMのUDDIページに行き、LSJを検索してみましょう。
http://www-3.ibm.com/services/uddi/(US)
UDDIページで、「UDDI V2 Business Registry」をクリックし、さらに「SearchUDDI Business Registry」をクリックします。
Search For aの後ろで「Busienss」を選択し、Starting withの後ろに「IBM」と入力し「Find」ボタンを押してください。
「IBM Learning Services Japan Co, Ltd.」がLSJの研修情報サービスの情報です。このエントリーの「Services」リンクをクリックしてください。LSJが提供しているサービスの一覧が表示されます。「EducationSearch」の名前をクリックして、詳細情報を表示してください。
詳細一覧の中に「Access Point」があり、そこにSOAPのエンドポイントが記されています。(ここには書きませんので、実際にUDDIを検索してみてください)
このアドレスを使います。
【サンプル・プログラムを実行する】
UDDIで見つけたアクセスポイントをサンプルJSPにセットして稼働させましょう。
- Methodsウィンドウで「setEndPoint」を選択する
- Inputsウィンドウの「url:」に先程の「Access Point」のURLを貼り付ける
- 「Invoke」ボタンをクリックする
- Methodsウィンドウで「getCourseを選択する
- keyword: に「Java」を指定し、「Invoke」ボタンをクリックする
次に、表示された結果のXMLから適当にコースコードをコピーし、同様の手順でgetScheduleメソッドも実行してみてください。今度は、スケジュール情報が取得できます。
setEndPointメソッドを使えば、簡単にアクセス先を変更できます。UDDIで、互換性のある(同じバインディング)のWebサービスを見つけることができれば、そのアドレスをセットすればいいのです。
XMLを処理するプログラムを生成
このように、Stringを返すメソッドですから、結果がXMLそのものになります。次に、これを簡単にプログラムから読み取ってみます。
【マッピング用Java beanを生成する】
メソッドから戻ってくるXMLドキュメントには、XML Schema(スキーマ定義)が準備されています。これもリコーテクノシステムズ様のサイトにありますので、先程の「wsdl」フォルダーにインポート(ダウンロード)してください。
WSDLファイルを選択して右クリックし、「生成」-「Java Bean」を選択します。「プロジェクトがビルドパスにありません。プロジェクトのJavaソース・フォルダーを選択してください。」というエラーが表示されます。コンテナーに対して、プロジェクトの「source」フォルダーを選択してください。「終了」ボタンをクリックしてください。
Javaパースペクティブのパッケージ・ビューでsourceフォルダーに、XMLをマッピングするためのJavaBeanができています。確認してください。
-
courseResultクラス
<courseResult>以下のXMLをJava Beanとしてマッピングするクラスです。「courseResult.course」という内部クラスがあり、courseそれぞれをマッピングします。「courseResult.course」には、コース情報を読み出すgetCourseName、getCourseCode といったメソッドがあります。
-
courseResultFactory
XMLデータからcourseResultクラスのインスタンスを生成するためのファクトリークラスです。
- ファクトリー・クラスにXMLファイルを読み込ませるとJava Beanのインスタンスができ、簡単にデータにアクセスできます。しかし、このままではファイルから読み込む必要があり、SOAPの通信には不便です。そこで、ストリング・オブジェクトに含まれるXMLからJavaBeanのインスタンスを生成するように改造してみましょう。改造するのはcourseResultFactoryクラスです。
-
まずは、研究
courseResultFactoryクラスのソースコードを除いてみると、com.ibm.etools.xmlschema.beans.Factoryクラスを継承していることがわかります。これはxsdbeans.jarに含まれています。
Factoryクラスでは、loadDocumentメソッドでXMLを読み込んでJava Beanのインスタンスを生成します。
-
次に改造
自動生成されるcourseResultFactoryクラスにはファイルから生成するためのメソッドしか準備されませんので、ストリング・オブジェクトに含まれるXMLからインスタンスを生成するメソッドを準備します。
/** * このメソッドは、米持幸寿が追加しました。
* @param inputText XMLを含んだストリング
* @return courseResult The Java bean representing the root element */
|
public courseResult loadFromTextXML(String inputText) {
org.xml.sax.InputSource in =
new org.xml.sax.InputSource(
new java.io.StringReader(inputText)
);
return (courseResult) loadDocument("courseResult",in);
}
|
-
どのように使うのか
String xmlDocumentにXMLドキュメントが含まれているとすれば、以下のコードでXMLのデータにアクセスできます。
package test; import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import org.apache.soap.encoding.soapenc.BeanSerializer;
import courseResult.*; public class Test {
public static void main(String[] args) throws Exception {
|
// Webサービスの呼び出し
proxy.soap.EducationSearchProxy p =
new proxy.soap.EducationSearchProxy();
p.setEndPoint(
new java.net.URL(
"http://www.lsj.jp.ibm.com/educSearch/servlet/Rpcrouter"));
String resultXML = p.getCourse("Java");
// Java Bean へのマッピング
courseResultFactory crf = new courseResultFactory();
crf.setPackageName("courseResult");
courseResult cr = crf.loadFromTextXML(resultXML);
// 読み出し、表示
for (int i = 0; i < cr.getCourseCount(); i++) {
courseResult.course course =cr.getCourse(i);
System.out.println(
"コースコード:" +
course.getCourseCode() +
" / コース名:" +
course.getCourseName());
}
}
}
|
【実行結果】
ソースコードを見てわかるように、XMLを受け取ったにもかかわらず、DOMやSAXのプログラミングを一切行わずに、データを参照できました。
今回は、手でUDDIを検索し、AccessPointをソースコードに書き込んで使いましたが、UDDI4J、ビジネス・エクスプローラーや、JAX-Rのようなレジストリー検索APIでプログラムで検索し、setEndPointメソッドを呼び出せば、複数の互換性のあるサイトに順次アクセスしてデータを取得することが簡単に行えます。
【サービスを提供するにはどうしたらいいか】
研修情報Webサービスを提供し、この仲間に入るにはどうしたらいいでしょうか。技術的には以下の点を提供すれば良いことになります。
- ここで紹介したのと同じような手順で、互換性のあるWebサービスを提供する。互換性のあるWebサービスとは、WSDLが一致すること、内部のXMLが同じであることが条件である。WebSphereStudioを使えば、これを簡単に行なうことができる。現在対応しているのは、HTTP-SOAPのRPC型のみである。
- インターネットに接続したアドレスでWebサービスを公開する。
- UDDIに、ビジネス、サービス、バインディング・テンプレートを登録する。この時、バインディング・テンプレートに、テクニカル・モデル「EnducationSearch」のtModelKeyをCategoryとして指定する。
ただし、これを行なっただけでは検索されません。なぜなら、TIPSシステムは、UDDIで検索された相手を「接続相手」として採用するためには、担当者が「採用」の処理を行なう必要があるようになっているからです。詳細は下記までお問い合わせください。
リクエスターの実装方法およびTIPSシステムに関するお問い合わせは:
リコーテクノシステムズ株式会社
SI事業センター技術部
部長 清水恒徳 ( tshimizu@r-ts.co.jp )
プロバイダーの設計・実装に関するお問い合わせは
株式会社 豆蔵
取締役副社長 CTO 萩本順三 ( hagimoto@mamezou.com )
著者について  | |  | 1987年に日本アイ・ビー・エム入社。メインフレームOS、ミドルウェアの障害対応、障害解析ソフトウェアの開発、ワークフローシステム開発、オブジェクト指向開発、Web開発など経験。2000年より、ソフトウェアのテクノロジーエバンジェリストとして活動中。 |
記事の評価
|