この項では、SOAP サービスの使用で説明した単純な Web サービスを拡張して、SOAP ヘッダを処理します。
前項の手順を実行済みの場合は、手順 1 ~ 4 を省略して、手順 5 に進んでください。
データベースを作成します。
dbinit ftc |
このデータベースを使用してサーバを起動します。
dbsrv11 -xs http(port=8082) -n ftc ftc.db |
Interactive SQL を使用してサーバに接続します。
dbisql -c "UID=DBA;PWD=sql;ENG=ftc" |
Interactive SQL を使用して Web サービスを作成します。
CREATE SERVICE FtoCService TYPE 'SOAP' FORMAT 'XML' AUTHORIZATION OFF USER DBA AS CALL FToCConvertor( :temperature ); |
このサービスが呼び出す、華氏表現の温度を摂氏に変換するために必要な計算を実行するストアド・プロシージャを定義します。前項の例とは異なり、このストアド・プロシージャには特別な SOAP ヘッダを処理するための文が追加されています。前項の例を使用してきた場合は、ストアド・プロシージャを変更することになるので、次の中の CREATE を ALTER に変更します。
CREATE PROCEDURE FToCConvertor( temperature FLOAT ) BEGIN DECLARE hd_key LONG VARCHAR; DECLARE hd_entry LONG VARCHAR; DECLARE alias LONG VARCHAR; DECLARE first_name LONG VARCHAR; DECLARE last_name LONG VARCHAR; DECLARE xpath LONG VARCHAR; DECLARE authinfo LONG VARCHAR; DECLARE namespace LONG VARCHAR; DECLARE mustUnderstand LONG VARCHAR; header_loop: LOOP SET hd_key = NEXT_SOAP_HEADER( hd_key ); IF hd_key IS NULL THEN -- no more header entries LEAVE header_loop; END IF; IF hd_key = 'Authentication' THEN SET hd_entry = SOAP_HEADER( hd_key ); SET xpath = '/*:' || hd_key || '/*:userName'; SET namespace = SOAP_HEADER( hd_key, 1, '@namespace' ); SET mustUnderstand = SOAP_HEADER( hd_key, 1, 'mustUnderstand' ); BEGIN -- parse the XML returned in the SOAP header DECLARE crsr CURSOR FOR SELECT * FROM OPENXML( hd_entry, xpath ) WITH ( alias LONG VARCHAR '@*:alias', first_name LONG VARCHAR '*:first/text()', last_name LONG VARCHAR '*:last/text()' ); OPEN crsr; FETCH crsr INTO alias, first_name, last_name; CLOSE crsr; END; -- build a response header -- based on the pieces from the request header SET authinfo = XMLELEMENT( 'Authentication', XMLATTRIBUTES( namespace as xmlns, alias, mustUnderstand ), XMLELEMENT( 'first', first_name ), XMLELEMENT( 'last', last_name ) ); CALL SA_SET_SOAP_HEADER( 'authinfo', authinfo ); END IF; END LOOP header_loop; SELECT ROUND((temperature - 32.0) * 5.0 / 9.0, 5) AS answer; END; |
SOAP 要求のヘッダは、NEXT_SOAP_HEADER 関数と SOAP_HEADER 関数を組み合わせて使用することによって取得できます。NEXT_SOAP_HEADER 関数は、要求に含まれる SOAP ヘッダに対して反復され、次の SOAP ヘッダ名を返します。NULL を指定して呼び出すと、最初のヘッダの名前が返されます。後続のヘッダは、NEXT_SOAP_HEADER 関数に前のヘッダの名前を渡すことによって取得されます。最後のヘッダの名前を指定して呼び出すと、NULL が返されます。この例で SOAP ヘッダを取得する SQL コードは次の部分です。NULL が返されるとループを抜けます。
SET hd_key = NEXT_SOAP_HEADER( hd_key ); IF hd_key IS NULL THEN -- no more header entries LEAVE header_loop; END IF; |
この関数を繰り返し呼び出すと、すべてのヘッダ・フィールドが一度だけ返されます。ただし、必ずしも SOAP 要求での表示順に表示されるとはかぎりません。
SOAP_HEADER 関数は、名前付きの SOAP ヘッダ・フィールドの値を返します。SOAP サービスから呼び出されていない場合は NULL を返します。Web サービスを介して SOAP 要求を処理する場合に使用します。指定したフィールド名のヘッダが存在しない場合、戻り値は NULL です。
この例は、Authentication という SOAP ヘッダを探します。このヘッダが見つかると、SOAP ヘッダ全体の値を抽出し、さらに @namespace
属性とmustUnderstand
属性の値を抽出します。SOAP ヘッダの値は、次の XML 文字列のようになります。
<Authentication xmlns="SecretAgent" mustUnderstand="1"> <userName alias="99"> <first>Susan</first> <last>Hilton</last> </userName> </Authentication> |
このヘッダの場合、@namespace
属性値は SecretAgent
になります。
また、mustUnderstand
属性値は 1
になります。
この XML 文字列の内部構造を、XPath 文字列に /*:Authentication/*:userName
を設定した OPENXML 関数を使用して解析します。
SELECT * FROM OPENXML( hd_entry, xpath ) WITH ( alias LONG VARCHAR '@*:alias', first_name LONG VARCHAR '*:first/text()', last_name LONG VARCHAR '*:last/text()' ); |
上記のサンプル SOAP ヘッダ値を使用した場合、SELECT 文は次のような結果セットを作成します。
alias | first_name | last_name |
99 | Susan | Hilton |
この結果セットに対してカーソルが宣言され、3 つのカラム値が 3 つの変数にフェッチされます。この時点で、Web サービスに渡された関連性のある情報すべてが手中にあります。華氏表現された温度が取得され、Web サービスに渡されたいくつかの追加属性が SOAP ヘッダから取得されています。この情報を使用して何ができるでしょうか。
たとえば、取得した名前と別名 (alias) を照会して、該当人物が Web サービスの使用を許可されているかどうかを確認できます。ただし、この演習でその例は取り上げていません。
ストアド・プロシージャでの次の処理は、SOAP フォーマットで応答を作成することです。XML 応答は、次のようにして構築します。
SET authinfo = XMLELEMENT( 'Authentication', XMLATTRIBUTES( namespace as xmlns, alias, mustUnderstand ), XMLELEMENT( 'first', first_name ), XMLELEMENT( 'last', last_name ) ); |
これにより、次の XML 文字列が構築されます。
<Authentication xmlns="SecretAgent" alias="99" mustUnderstand="1"> <first>Susan</first> <last>Hilton</last> </Authentication> |
最後に、SA_SET_SOAP_HEADER ストアド・プロシージャを使用して、SOAP 応答を呼び出し側に返します。
CALL SA_SET_SOAP_HEADER( 'authinfo', authinfo ); |
前項の例のように、最後の手順は華氏から摂氏への変換計算です。
この時点で、前項と同様に、華氏から摂氏への温度変換を行う SQL Anywhere Web サービスが実行されています。ここでの大きな違いは、Web サービスが呼び出し側からの SOAP ヘッダを処理して、SOAP 応答を呼び出し側に返送できることです。
これはまだ全体像の半分にしか達していません。次のステップは、SOAP 要求を送信し、SOAP 応答を受信する、サンプル・クライアントの開発です。
前項の手順を実行済みの場合は、手順 1 ~ 3 を省略して、手順 4 に進んでください。
第 2 のサーバで使用するデータベースを新たに作成します。
dbinit ftc_client |
このデータベースを使用してパーソナル・サーバを起動します。
dbeng11 ftc_client.db |
Interactive SQL の別のインスタンスを使用してパーソナル・サーバに接続します。
dbisql -c "UID=DBA;PWD=sql;ENG=ftc_client" |
Interactive SQL を使用してストアド・プロシージャを作成します。
CREATE PROCEDURE FtoC( temperature FLOAT, INOUT inoutheader LONG VARCHAR, IN inheader LONG VARCHAR ) URL 'http://localhost:8082/FtoCService' TYPE 'SOAP:DOC' SOAPHEADER '!inoutheader!inheader'; |
URL 句は、SOAP Web サービスを参照するために使用されます。文字列 'http://localhost:8082/FtoCService'
は、使用される Web サービスの URI を指定します。これは、ポート 8082 で受信する Web サーバを指しています。
Web サービス要求作成時のデフォルト・フォーマットは 'SOAP:RPC' です。この例で使用されているフォーマットは 'SOAP:DOC' です。これは 'SOAP:RPC' と似ていますが、より多くのデータ型を使用できます。SOAP 要求は必ず XML ドキュメントとして送信されます。SOAP 要求の送信メカニズムは 'HTTP:POST' です。
SQL Anywhere クライアント・プロシージャ (inoutheader、inheader) の代入変数は英数字である必要があります。Web サービス・クライアントが関数として宣言された場合、すべてのパラメータは IN モードのみになります (呼び出された側の関数では代入できません)。したがって、SOAP 応答ヘッダ情報を抽出するには、OPENXML またはその他の文字列関数を使用する必要があります。
FtoC ストアド・プロシージャのラッパが必要なので、次のような 2 つ目のストアド・プロシージャを作成します。前項の例とは異なり、このストアド・プロシージャには、特別な SOAP ヘッダを作成し、それを Web サービス呼び出しに含めて送信し、Web サーバからの応答を処理する文が追加されています。前項の例を使用してきた場合は、ストアド・プロシージャを変更することになるので、次の中の CREATE を ALTER に変更します。
CREATE PROCEDURE FahrenheitToCelsius( temperature FLOAT ) BEGIN DECLARE io_header LONG VARCHAR; DECLARE in_header LONG VARCHAR; DECLARE result LONG VARCHAR; DECLARE err INTEGER; DECLARE crsr CURSOR FOR CALL FtoC( temperature, io_header, in_header ); SET io_header = '<Authentication xmlns="SecretAgent" ' || 'mustUnderstand="1">' || '<userName alias="99">' || '<first>Susan</first><last>Hilton</last>' || '</userName>' || '</Authentication>'; SET in_header = '<Session xmlns="SomeSession">' || '123456789' || '</Session>'; MESSAGE 'send, soapheader=' || io_header || in_header; OPEN crsr; FETCH crsr INTO result, err; CLOSE crsr; MESSAGE 'receive, soapheader=' || io_header; SELECT temperature, Celsius FROM OPENXML(result, '//tns:answer', 1, result) WITH ("Celsius" FLOAT 'text()'); END; |
このストアド・プロシージャは、Web サービスの呼び出しを隠すプロシージャとして機能します。このストアド・プロシージャは、前項の例から拡張されており、2 つの SOAP ヘッダを作成します。最初のヘッダは次のとおりです。
<Authentication xmlns="SecretAgent" mustUnderstand="1"> <userName alias="99"> <first>Susan</first> <last>Hilton</last> </userName></Authentication> |
2 番目のヘッダは次のとおりです。
<Session xmlns="SomeSession">123456789</Session> |
カーソルが開かれると、SOAP 要求は Web サービスに送信されます。
<Authentication xmlns="SecretAgent" alias="99" mustUnderstand="1"> <first>Susan</first> <last>Hilton</last> </Authentication> |
FtoC ストアド・プロシージャは、このストアド・プロシージャによって処理される結果セットを返します。結果セットは次のようになります。
<tns:rowset xmlns:tns="http://localhost/ftc/FtoCService"> <tns:row> <tns:answer>100</tns:answer> </tns:row> </tns:rowset> |
OPENXML 関数を使用して、返された XML を解析し、摂氏単位の温度を示す値を抽出します。
ストアド・プロシージャを呼び出して、要求を送信し、応答を取得します。
CALL FahrenheitToCelsius(212); |
華氏温度 (temperature) とその摂氏 (Celsius) 換算値が表示されます。
temperature | Celsius |
212.0 | 100.0 |
SQL Anywhere Web サービス・クライアントは、関数またはプロシージャとして宣言できます。SQL Anywhere クライアント関数宣言は、実質的に、すべてのパラメータを in モードのみに制限します (パラメータは呼び出された側の関数で代入できません)。SQL Anywhere Web サービスの関数を呼び出すと未加工の SOAP エンベロープ応答が返され、プロシージャを呼び出すと結果セットが返されます。
CREATE/ALTER PROCEDURE/FUNCTION 文には SOAPHEADER 句が追加されています。SOAP ヘッダは、静的定数として宣言したり、代入パラメータ・メカニズムを使用して動的に設定したりできます。Web サービス・クライアント関数は in モード代入パラメータを 1 つまたは複数定義でき、Web サービス・クライアント・プロシージャも inout または out 代入パラメータを 1 つ定義できます。したがって、Web サービス・クライアント・プロシージャは、応答 SOAP ヘッダを out (または inout) 代入パラメータに含めて返すことができます。Web サービス関数は、応答 SOAP エンベロープを解析して、ヘッダ・エントリを取得する必要があります。
次の例は、クライアントが、いくつかのヘッダ・エントリをパラメータを使用して送信し、応答 SOAP ヘッダ・データを受信するよう指定する方法を示しています。
CREATE PROCEDURE SoapClient( INOUT hd1 VARCHAR, IN hd2 VARCHAR, IN hd3 VARCHAR ) URL 'localhost/some_endpoint' SOAPHEADER '!hd1!hd2!hd3'; |
'Expression has unsupported data type' SQLCODE=-624, ODBC 3 State-"HY000"
」が発生します。
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |