連載 DB2でXMLを操作する(最終回)
Webサービス機能を徹底検証する
XMLの普及とともにリレーショナルデータベースにもXMLを格納できる機能が搭載されてきている。しかしその機能は、製品ごとに固有のものだ。この記事では、IBMの製品であるDB2
UDBでどのようにXMLを扱うか、について解説する。 たがわ製作所 2003/10/24 |
今回の主な内容 WebサービスプロバイダとしてのDB2 WORFのインストール WORFを使ってみよう Web Service Consumer UDFの概要 DB2からWebサービスを呼び出してみよう 最後に |
前回まで4回にわたり、XMLの保存および検索を行うための2つの手段、XML ColumnとXML Collectionについて解説しました。今回はDB2のXML関連機能の中でも非常にユニークな、Webサービス機能について取り上げたいと思います。
本連載の第1回で紹介したように、DB2はWebサービスを提供するプロバイダとなることが可能です。さらに、その後にリリースされた「FixPak2」(各種フィックスおよび機能追加のためのサービスモジュール)で、DB2からWebサービスにアクセスするための機能が追加されました。これにより、DB2はWebサービスプロバイダとしてだけでなくサービスリクエスタとしても利用できるようになったのです。
では順に、Webサービスプロバイダとしての機能およびWebサービスリクエスタとしての機能について見ていくことにしましょう。
Webサービスプロバイダとしての機能は、連載の第1回でも紹介したとおり、WORF(Web services Object Runtime Framework)と呼ばれる追加モジュールによって提供されます。WORF自身はWebアプリケーションとして実装されており、WebSphere Application ServerやTomcatといったサーブレットコンテナ上で動作します(図1)。
図1 WORFのアーキテクチャの概要 |
WORFを用いると以下のようなDBアクセス操作を、Webサービスとして簡単に実現することができます。
- 照会SQLの実行
- 更新SQLの実行
- ストアドプロシージャの実行
- XML文書の合成と分解
これらのWebサービスを実現するために必要な作業は、DADX(DAD eXtension)と呼ばれる定義ファイルの記述だけです。サービス名と実際に実行されるSQL文を記述するだけの簡単な作業であり、Javaによるコーディング作業などは一切不要です。
(1)インストール手順の概要
それでは早速WORFをインストールしてみましょう。セットアップの手順の概要は以下のようになります。
- アプリケーションサーバのインストール
- Apache SOAPのインストール
- JDBCドライバのセットアップ
- WORFのインストール
アプリケーションサーバとしてはWebSphere Application ServerもしくはTomcatが利用できます。今回はインストールが簡単なTomcatを使ってみます。また、WORFを利用するにはアプリケーションサーバのほかにApache SOAPが必要です。
(2)Tomcatのインストール
TomcatのアーカイブをJakarta Projectのサイトからダウンロードしてください。今回はバージョン4.1.27を利用します。アーカイブを適当なディレクトリに展開すれば、一応インストールは完了です。なお、以下ではTomcatがインストールされたディレクトリを%TOMCAT_HOME%と表記することにします。
%TOMCAT_HOME%\binに起動のスクリプト(startup.bat)および停止のスクリプト(shutdown.bat)があります。起動スクリプトを実行してTomcatを起動し、動作するかどうか確認します。ここでは動作確認の詳細な方法については省きますが、動作確認が終わったら停止しておいてください。
(3)Apache SOAPのインストール
WORFはApache SOAPを利用してSOAPのリクエストを処理しています。Apache SOAPそのものはDB2のディストリビューションには含まれていませんので、Apacheのサイトから別途ダウンロードしてください。今回はバージョン2.3.1を利用します。
アーカイブに含まれるsoap.jarを、%TOMCAT_HOME%\shared\libディレクトリにコピーします。これでApache SOAPは、Tomcat上で動作するWebアプリケーションから利用できるようになりました。
(4)JDBCドライバのセットアップ
アプリケーションサーバからDB2に接続するためにJDBCドライバをセットアップします。今回はDB2 V8.1のどのバージョンでも利用できるLegacy Type2 JDBCドライバを利用することにします。一般的なType2JDBCドライバを利用する場合と同じく、以下のような手順が必要になります。
- JDBCドライバのライブラリをCLASSPATHに含める
- ネイティブモジュールのインストールされたディレクトリをPATHに含める
アプリケーションサーバ上のWebアプリケーションに対してこれらを正しく設定する方法は、アプリケーションサーバの仕様により異なりますが、ここではTomcatを前提に設定作業を行います。
CLASSPATHの設定
Legacy Type2 JDBCドライバが含まれるファイルは、%DB2HOME%\java\db2java.zipです(%DB2HOME%はDB2をインストールしたディレクトリ)。今回は、このファイルを%TOMCAT_HOME%\shared\libにdb2java.jarという名前でコピーします。こうすることで、すべてのWebアプリケーションからJDBCドライバを利用できるようになります。
PATHの設定
環境変数PATHに%DB2HOME%\binを含めておきます。DB2をインストールすると、通常は自動的に設定されるものです。
(5)WORFのインストール
WORFは%DB2HOME%\samples\java\websphere\dxxworf.zipというアーカイブに含まれています。このアーカイブを適当なディレクトリで展開してください。展開されたアーカイブに含まれるファイルを以下の手順でインストールします(以下では展開したディレクトリを%WORF%と表記しています)。
- %WORF%\lib\worf.jarを、%TOMCAT_HOME%\shared\libにコピーします。
- %WORF%\lib\services.warを、%TOMCAT_HOME%\webappsにコピーします。
以上でWORFのセットアップは完了です。
(6)動作確認
では動作確認を行ってみます。Tomcatを起動し、以下のURLをオープンしてみてください。
http://localhost:8080/services/
図2のようなWORFのサンプルページを確認できれば、取りあえずはOKです。
図2 WORFのサンプルページ(画面をクリックすると全体を表示します) |
(1)グループとDADX
Webサービスの定義は、DADXと呼ばれるファイルに記述します。1つのDADXには複数のサービスを定義することが可能ですので、関連のあるいくつかのサービスをひとまとめに定義するのがよいでしょう。複数のDADXをひとまとめにして、1つのグループとして定義します。このグループ単位でデータベースの接続先を設定します(図3)。
図3 グループとDADXの関係 |
実際の作業手順としては、まずグループを定義し、その次にDADXファイルを定義するという形になります。以下ではこの順で作業を進めてみます。
(2)グループの定義
まずはグループを作成します。WebアプリケーションのWEB-INF/classes/groupsディレクトリの下に、グループ名と同じ名前のディレクトリを作成することによりグループを定義します。いま、servicesという名前でWORFのWebアプリケーションがデプロイされています。ですから、%TOMCAT_HOME%\webapps\services\WEB-INF\classes\groupsというディレクトリにグループ名と同じ名前のディレクトリを作成すればよいことになります。ここでは、sampleという名前のグループを作成してみることにしましょう(図4)。
図4 グループの作成(画面をクリックすると全体を表示します) |
この例は、TomcatがC:\Java\Tomcat\4.1.27にインストールされている場合のものです。
次に、このグループが接続する先のデータベースについての情報を定義します。作成したグループのディレクトリにgroup.propertiesというファイルを定義してください。ここにデータベースの接続先情報をリスト1の形式で定義します。
dbDriver=COM.ibm.db2.jdbc.app.DB2Driver |
リスト1 group.propertiesの定義例(JDBCを用いる場合) |
dbDriver
利用するJDBCドライバ名を指定します。ここではLegacy Type2 JDBCドライバを用いるので、COM.ibm.db2.jdbc.app.DB2Driverを指定しています。
dbURL
接続先のURLを指定します。Legacy Type2 JDBCドライバを用いる場合は、jdbc:db2:データベース名となります。
userID、password
接続に用いるユーザー名およびパスワードを指定します。ここではdb2adminというユーザー名およびパスワードを指定していますが、読者の皆さんが実際に利用されているユーザー名とパスワードに置き換えてください。
autoReload、reloadIntervalSeconds
DADXファイルの変更を自動検出し、動的なサービス変更を可能にするかどうか指定します。変更するかどうかをautoReloadで、変更の検出間隔(秒)をreloadIntervalSecondsで指定します。
以上は、JDBCでの明示的な接続を用いる場合の指定方法です。これ以外にもコネクションプーリングを用いた接続の指定も可能です。今回は利用しませんが、リスト2にサンプルを掲げておきましょう。
initialContextFactory=com.ibm.websphere.naming. → |
リスト2 group.propertiesの定義例(コネクションプーリングを用いる場合、1〜2行目は本来1行です) |
initialContextFactory
JNDIのイニシャルコンテキストのファクトリクラスを指定します。ここではWebSphereを利用しているという前提で、com.ibm.websphere.naming.WsnInitialContextFactoryというファクトリクラスを指定しています。
datasourceJNDI
コンテキストパス上のデータソース名を指定します。ここではjdbc/sampleという名前を指定しています。
(3)サーブレットマッピングの設定
グループを定義したら、これをアプリケーション上のURLと対応付ける作業が必要です。具体的には、グループを処理するためのサーブレットを定義し、そのサーブレットとURLを対応付ける形になります。
サーブレットの定義
%TOMCAT_HOME%\webapps\services\WEB-INF\web.xmlというファイルをエディタで開き、<servlet>タグが並んでいる個所を見つけてください。その並びにリスト3のようなサーブレット定義を追加します。
<servlet> |
リスト3 サーブレットの定義例 |
見れば分かるように、グループ名(sample)と同じサーブレット名でcom.ibm.etools.webservice.rt.dxx.servlet.DxxInvokerというサーブレットを定義しています。グループ名と同じサーブレット名というところがポイントです。
サーブレットとURLの対応付け
同じくweb.xmlにサーブレットとURLの対応付けを定義します。<servlet-mapping>タグが並んでいる個所を見つけてください。その並びにリスト4のようなサーブレットマッピングの定義を追加します。
<servlet-mapping> |
リスト4 サーブレットとURLの対応付けの定義例 |
/sample/という文字列で始まるURLを、sampleという先ほど定義したサーブレットと対応付けています。/sample/の部分はどのような文字列でも構いませんが、ここでは分かりやすくするためにグループ名と同じにしておきました。
(4)DADXの定義
グループが定義できたので、早速DADXにWebサービスを定義してみます。先ほど作成したグループのディレクトリに適当な名前でDADXファイルを作成する必要があるのですが、文法の詳細などは後回しにして、ともかくサンプルを見てみるところから始めましょう(リスト5)。
<?xml version="1.0" encoding="UTF-8"?> |
リスト5 DADXのサンプル(emp.dadx) |
見れば分かるように、DADXもXML形式のファイルになっています。このDADXでは、sampleデータベースのemployee表にアクセスするための、以下の2つのサービスを定義しています。
getEmployee
従業員番号(empno)に基づいてemployee表を検索し、対応する従業員の情報を返します。
getAllEmployees
employee表に登録されているすべての従業員の情報を返します。
エレメント(要素)の名前からなんとなく想像がつくかと思いますが、各サービスの定義には、サービス名、実行するSQL、引数の情報などが含まれています。
<operation>
サービスを定義します。1つのDADXファイルの中でこのエレメントを複数回繰り返し、複数のサービスをまとめて定義することができます。
<query>、<SQL_query>、<parameter>
照会のサービスを定義します。<SQL_query>に実行するSQLを定義し、そこで用いる各パラメータを<parameter>で定義します。使われているSQLを見れば分かるように、パラメータの参照は“:パラメータ名”という形式で行います。
(5)動作確認
定義したWebサービスを実行すると、一体どのような形式の結果が返ってくるのでしょうか? また、どのように呼び出せばよいのでしょうか?
一般的にWebサービスに関するこれらの情報については、WSDLで記述することになっています。WORFでは、DADXで定義したWebサービスについて自動的にWSDLを生成することができます。Tomcatを起動したうえで、以下のURLをオープンしてみてください。
http://localhost:8080/services/sample/emp.dadx/WSDL
見てお分かりのように、"/services/マッピングしたURL/DADXファイル名/WSDL"というURLをリクエストすると、対応するDADXファイルに定義されているWebサービスのWSDLを確認できるようになっています。
図5 WSDLの確認(画面をクリックすると全体を表示します) |
図5のようなWSDLを確認できたでしょうか? ここで、エンドポイント、アクション、入力となる文書の形式などを確認しておいてください。
サービスを実際に呼び出すのには、さまざまなクライントを利用することが可能です。WORFではテスト用ページが用意されているので、今回はそちらを利用してみましょう。以下のURLをオープンしてみてください。図6のようなテストページを確認できるはずです。
http://localhost:8080/services/sample/emp.dadx/TEST
図6 テストページ(画面をクリックすると全体を表示します) |
左上のペーンからメソッド名を選択すると、右上のペーンで引数を入力できるようになります(引数を取るもののみ)。引数を入力した後、Submitボタンを押せばWebサービスが起動します。結果は図7のようにXML文書の形で返ってきます。テーブルのデータがどのような形式でXML文書にマッピングされているか確認してみてください。
図7 getEmployeeを呼び出した結果の例(画面をクリックすると全体を表示します) |
(6)さまざまなサービスの定義
以上は照会のSQLを例に取ってWebサービスを定義してみました。先ほど紹介したとおり、照会以外のSQLについてもサービスを定義することが可能です。ここでは、更新とXML文書の取り出しについてサービスをどのように定義するか紹介しておきましょう。
更新のSQL
更新のSQLをサービスとして定義する例をリスト6に示します。
<operation name="updateEmployee"> |
リスト6 更新のSQLをサービスとして定義する例 |
ここでは、従業員番号と名前を与えて、従業員の名前を更新するサービスを定義しています。見ればお分かりのように、エレメントの名前が<update>および<SQL_update>となっているだけでその定義の仕方は照会のSQLの場合とほとんど同じになっています。この例ではSQLでupdateを用いていますが、もちろんinsertやdeleteも用いることができます。
XML文書の合成
DADファイルによりコレクションを定義しておけば、その定義に基づいてXML文書を合成する操作をWebサービスとして定義できます。こちらの定義も非常に簡単でリスト7のような形式になります。
<operation name="listEmployees"> |
リスト7 XML文書の合成をサービスとして定義する例 |
説明するまでもないかもしれませんが、このサービスは、department.dadというDADファイルに基づいてXML文書の合成を行うものです。上記の定義に加え、DADファイルおよびDTDのファイルをグループのディレクトリに置いておく必要があります。具体的な例については、WORFに含まれる以下のサンプルを参照してみるとよいでしょう。
http://localhost:8080/services/db2sample/department.dadx/TEST
以上がWebサービスプロバイダとしての機能を提供するWORFの概要です。このように、WORFを用いるとコーディングすることなしにWebサービスを非常に簡単に実現できます。
次は、DB2のWebサービスリクエスタとしての機能について見ていきましょう。
DB2の内部からWebサービスにアクセスするための機能は、UDF(User Defined Function)として実装されています。Web Service Consumer UDFと呼ばれるこれらの機能は、FixPak2から追加されたものです。
5つのUDFが提供されていますが、引数や返値の型が少しずつ違うだけであり基本的には同じ機能のものです。いずれも、SOAPリクエストのエンドポイント、アクション、SOAPボディを引数に取ってSOAPのリクエストを発行します。以下ではこのうちの1つを例に取って、実際にWebサービスの呼び出しを行ってみます。
(1)利用するサービス
呼び出すWebサービスとして、今回はNetDictionaryが提供するコンピュータ用語検索サービスを利用してみます。NetDictionaryはデジタルアドバンテージと@ITが共同運営するサイトであり、皆さんおなじみのInsider's Computer DictionaryのデータにアクセスするためのWebサービスを提供しています(NetDictionaryの詳細についてはInsider.NETの記事をご覧ください)。
このWebサービスでは、以下の4つの操作が利用できるようになっています。
利用できる操作の一覧 | ||||||||||
|
今回はDB2のUDFを用いて、全文検索を行うためのFullTextSearchを呼び出してみましょう。FullTextSearchは、単語を説明に含む見出し語の一覧を返すものです。呼び出しの形式の詳細についてはWSDLを確認する必要がありますが、SOAPメッセージはおおむねリスト8のような形になります。
<?xml version="1.0" encoding="utf-8"?> |
リスト8 FullTextSearchを呼び出すためのSOAPメッセージ |
また、レスポンスはリスト9のような形式になります。
<?xml version="1.0" encoding="utf-8"?> |
リスト9 FullTextSearchのレスポンス |
それでは実際にサービスを呼び出してみましょう。
(2)サービスの呼び出し
Web Service Consumer UDFを利用するには、まずデータベースを有効化する必要があります。DB2のコマンドラインから以下のコマンドを実行してください。
db2enable_soap_udf -d データベース名 |
Web Service Consumer UDFには5つ関数があると書きましたが、今回はそのうち、DB2XML.SOAP_HTTPCを用います。
db2xml.soaphttpc ( |
リスト10 DB2XML.SOAP_HTTPCのインターフェイス |
エンドポイント、アクションおよびSOAPボディを引数として指定すると、SOAPのリクエストが発行され、そのレスポンスがCLOB型の返値として取得できるという、非常にシンプルなものです。
では、DB2のコマンドラインプロセッサから実際に呼び出してみましょう。ここでは「PKI」というキーワードで検索してみることにします。
values db2xml.soaphttpc( |
リスト11 呼び出し例(4〜5行目は本来1行です) |
FullTextSearchの呼び出しに必要なエンドポイントとアクションについては先ほど触れませんでしたが、それぞれ'http://www.iwebmethod.net/icd1.0/icd.asmx'および'http://www.iwebmethod.net/FullTextSearch'です。なお、ここでは便宜上改行していますが、コマンドラインから直接入力するときは改行しないように注意してください。
結果は少し見にくいのですが、以下のようなCLOBの値が返ってくるはずです。
<FullTextSearchResponse xmlns="http://www.iwebmethod.net"> |
リスト12 呼び出しの結果 |
(3)結果の加工
さて、返ってきたリクエストはSOAPレスポンスそのものです。この値をそのままCLOBのカラムか何かに格納するというのも1つの手ですが、実際にはレスポンスの文書から値を取り出して使う場合が大半でしょう。
さて、そのような場合はどうすればよいのでしょうか? ここでXML Columnの回を思い出していただきたいのですが、XMLの文書から値を取り出すためのUDFがちゃんとありましたね。リスト13のように、XMLエクステンダーのUDFの1つであるDB2XML.extractVarcharsなどを使えば、SOAPのレスポンスから任意のロケーションの値を取り出し、表として返すことが可能です。
select * from TABLE( |
リスト13 extractVarcharsを利用して値を取り出す (7〜8行目は本来1行です) |
少し難しい表関数というものが出てきてしまいましたが、要はXMLエクステンダーの機能を利用してSOAPのレスポンスを自由に編集できてしまうということが分かっていただければ十分です。もちろん上記のような長いクエリを毎回書くのは現実的ではありませんから、実際にはSQL/PLか何かを用いたUDFもしくはストアドプロシージャとして一度定義し、あとはそれを呼び出すというのが一般的でしょう。
1年と少しにわたって、DB2のXML関連機能について解説してきた連載も今回で最後です。XML関連の機能と一口にいっても、その内容は多岐にわたっておりついつい混乱しがちですが、1つ1つはシンプルで使いやすいものです。これらの機能を理解するために、この連載がガイドとなれば幸いです。
なお、DB2のXML関連の機能はこれがすべてではありません。SQL-XやNet Search Extenderなどについては今回触れることができませんでした。また、将来的にはXQueryもサポートされる予定になっています。余力があればこれらについても解説したいと思いますが、ひとまずはここで終わりにしておきます。
機会があればまたお会いしましょう!
<<前回へ |
Index | |
連載:DB2でXMLを操作する | |
(1) XMLの格納方法を2種類備えるDB2 | |
(2) DB2 UDBのインストールと動作確認 | |
(3) XML Columnを使うための設計・実装 | |
(4) XML ColumnにDocBook文書を格納する | |
(5) XML Collectionを使うための設計・実装 | |
(6) XML Collectionでデータマッピングを実現 | |
(最終回) Webサービス機能を徹底検証する |
- QAフレームワーク:仕様ガイドラインが勧告に昇格 (2005/10/21)
データベースの急速なXML対応に後押しされてか、9月に入って「XQuery」や「XPath」に関係したドラフトが一気に11本も更新された - XML勧告を記述するXMLspecとは何か (2005/10/12)
「XML 1.0勧告」はXMLspec DTDで記述され、XSLTによって生成されている。これはXMLが本当に役立っている具体的な証である - 文字符号化方式にまつわるジレンマ (2005/9/13)
文字符号化方式(UTF-8、シフトJISなど)を自動検出するには、ニワトリと卵の関係にあるジレンマを解消する仕組みが必要となる - XMLキー管理仕様(XKMS 2.0)が勧告に昇格 (2005/8/16)
セキュリティ関連のXML仕様に進展あり。また、日本発の新しいXMLソフトウェアアーキテクチャ「xfy technology」の詳細も紹介する
|
|