次のチュートリアルでは、Java API for XML Web Services (JAX-WS) を使用して Web サービスにアクセスする方法を示します。
チュートリアルを始める前に、Sun から入手可能な JAX-WS ツールが必要です。このパッケージがシステムにインストールされていない場合は、JAX-WS ツールをダウンロードしてインストールしてください。JAX-WS ツールをダウンロードするには、 http://java.sun.com/webservices/ を参照してください。JAX-WS のリンクをクリックすると、
Java API for XML Web Services のページが開きます。Download Now リンクをクリックします。ソフトウェア・パッケージをダウンロードしたら、それをシステムにインストールします。
このサンプルは、JAX-WS 2.1.3 for Windows を使用して開発されました。
JAX-WS からアクセスできる SQL Anywhere SOAP Web サービスは、CONCRETE フォーマットとして宣言する必要があります。
コマンド・プロンプトで、次のコマンドを実行して、パーソナル Web サーバを起動します。samples-dir をサンプル・データベースの実際のロケーションと置き換えます。-xs http(port=80)
オプションは、HTTP 要求をポート 80 で受け入れるようにデータベース・サーバに指示します。すでにポート 80 で稼働している Web サーバがある場合は、このチュートリアルには 8080 などの別のポート番号を使用し、すべてのポート参照で
80 の代わりに 8080 を使用してください。
dbeng11 -xs http(port=80) samples-dir\demo.db |
Interactive SQL を起動し、DBA として SQL Anywhere サンプル・データベースに接続します。次の文を実行します。
Employees テーブルの一部のカラムをリストするストアド・プロシージャを定義します。
CREATE PROCEDURE ListEmployees() RESULT ( EmployeeID INTEGER, Surname CHAR(20), GivenName CHAR(20), StartDate DATE, TerminationDate DATE ) BEGIN SELECT EmployeeID, Surname, GivenName, StartDate, TerminationDate FROM Employees; END; |
このストアド・プロシージャを呼び出す SOAP サービスを定義します。
CREATE SERVICE "WS/EmployeeList" TYPE 'SOAP' FORMAT 'CONCRETE' EXPLICIT OFF DATATYPE OUT AUTHORIZATION OFF SECURE OFF USER DBA AS CALL ListEmployees(); |
EXPLICIT 句は、CONCRETE 型の SOAP または DISH サービスでのみ使用できます。この例の EXPLICIT OFF は、対応する DISH サービスで汎用の SimpleDataset オブジェクトを記述する XML スキーマを生成することを示します。このオプションの影響を受けるのは、生成される WSDL ドキュメントだけです。EXPLICIT ON の使用例は後で紹介します。チュートリアル:JAX-WS でのデータ型の使用を参照してください。
DATATYPE OUT は、明示的なデータ型情報が XML 結果セットの応答で生成されることを示します。DATATYPE OFF が指定されている場合、すべてのデータは String 型になります。このオプションは、生成される WSDL ドキュメントに影響しません。
認証はオフになっているため、ユーザ名とパスワードを入力せずにだれでもこのサービスを利用できます。このコマンドは、ユーザが DBA の場合に実行できます。この方法は簡単ですが、安全性に優れていません。
SOAP サービスのプロキシとして機能し、WSDL ドキュメントを生成する DISH サービスを作成します。
CREATE SERVICE "WSDish" TYPE 'DISH' FORMAT 'CONCRETE' GROUP "WS" AUTHORIZATION OFF SECURE OFF USER DBA; |
SOAP サービスと DISH サービスは、CONCRETE フォーマットである必要があります。EmployeeList サービスは WS グループであるため、GROUP 句が含まれます。
DISH サービスにより自動的に生成される WSDL を見てみます。そのためには、Web ブラウザを開き、URL http://localhost:80/demo/WSDish にアクセスします。DISH は、ブラウザのウィンドウに表示される WSDL ドキュメントを自動生成します。
特に、SimpleDataset オブジェクトに注目してください。このサービスのフォーマットは CONCRETE で EXPLICIT が OFF になっているため、SimpleDataset オブジェクトは公開されています。この後の手順で、wsimport アプリケーションはこの情報を使用して、このサービス用の SOAP 1.1 クライアント・インタフェースを生成します。
<s:complexType name="SimpleDataset">
<s:sequence>
<s:element name="rowset">
<s:complexType>
<s:sequence>
<s:element name="row" minOccurs="0" maxOccurs="unbounded">
<s:complexType>
<s:sequence>
<s:any minOccurs="0" maxOccurs="unbounded" />
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType> |
この例では、Java API for XML Web Services (JAX-WS) と Sun Java 1.6.0 JDK は C: ドライブにインストールされています。JAX-WS バイナリと JDK バイナリがパスに含まれるように PATH 環境変数を設定します。バイナリは次のディレクトリにあります。
c:\Sun\jaxws-ri\bin c:\Sun\SDK\jdk\bin |
コマンド・プロンプトで、CLASSPATH 環境変数を設定します。
SET classpath=.;C:\Sun\jaxws-ri\lib\jaxb-api.jar ;C:\Sun\jaxws-ri\lib\jaxws-rt.jar |
次の手順では、Web サービスを呼び出すために必要なインタフェースを生成します。
同じコマンド・プロンプトで、新しいプロジェクト・ディレクトリを作成し、これを現在のディレクトリにします。このディレクトリで次のコマンドを実行します。
wsimport -keep -Xendorsed "http://localhost:80/demo/WSDish" |
wsimport ツールは、指定された URL から WSDL ドキュメントを取得し、そのインタフェースを定義する Java ファイルを生成してから、Java ファイルをコンパイルします。
keep オプションは、.java ファイルを削除しないように wsimport に指示します。このオプションが指定されない場合は、対応する .class ファイルの生成後にこれらのファイルは削除されます。これらのファイルを保存すると、インタフェースの構成の検査が簡単になります。
Xendorsed オプションは、JAX-WS 2.1 API を JDK6 と一緒に使用できるようにします。
このコマンドが完了すると、以下の Java ファイルと、各 Java ファイルがコンパイルされた .class ファイルを含む localhost\demo\ws というサブディレクトリ構造が作成されています。
EmployeeList.java EmployeeListResponse.java FaultMessage.java ObjectFactory.java package-info.java SimpleDataset.java WSDish.java WSDishSoapPort.java |
次の Java ソース・コードを SASoapDemo.java として保存します。このファイルが、wsimport ツールで生成された localhost サブディレクトリを含むディレクトリと同じ場所にあることを確認してください。
// SASoapDemo.java illustrates a web service client that // calls the WSDish service and prints out the data. import java.util.*; import javax.xml.ws.*; import org.w3c.dom.Element; import org.w3c.dom.Node; import localhost.demo.ws.*; public class SASoapDemo { @WebServiceRef( wsdlLocation= "http://localhost:8080/demo/WSDish" ) public static void main( String[] args ) { try { WSDish service = new WSDish(); Holder<SimpleDataset> response = new Holder<SimpleDataset>(); Holder<Integer> sqlcode = new Holder<Integer>(); WSDishSoapPort port = service.getWSDishSoap(); // This is the SOAP service call to EmployeeList port.employeeList( response, sqlcode ); localhost.demo.ws.SimpleDataset result = response.value; SimpleDataset.Rowset rowset = result.getRowset(); List<SimpleDataset.Rowset.Row> rows = rowset.getRow(); for ( int i = 0; i < rows.size(); i++ ) { SimpleDataset.Rowset.Row row = rows.get( i ); List<Object> cols = row.getAny(); System.out.println( "Number of columns=" + cols.size() ); for ( int j = 0; j < cols.size(); j++ ) { // Column data is contained as a SOAPElement Element col = (Element)cols.get(j); System.out.print(col.getLocalName() + "=" ); Node node = col.getFirstChild(); if( node == null ) { System.out.println( "(null)" ); } else { System.out.println( node.getNodeValue() ); } } System.out.println(); } } catch (Exception x) { x.printStackTrace(); } } } |
8080 のように別のポート番号を使用して Web サーバを起動する場合は、import localhost
ソース行を次のように変更する必要があります。
import localhost._8080.demo.ws.*; |
SASoapDemo.java をコンパイルします。
javac SASoapDemo.java |
コンパイル済みのクラス・ファイルを実行します。
java SASoapDemo |
アプリケーションは Web サーバに要求を送信すると、XML 結果セット応答を受け取ります。この応答は、複数のロー・エントリを含むローセットを持つ EmployeeListResult から構成されています。この応答には、クエリの実行結果の sqlcode も含まれています。この応答の例を次に示します。
<tns:EmployeeListResponse> <tns:EmployeeListResult xsi:type='tns:SimpleDataset'> <tns:rowset> <tns:row>...</tns:row> . . . <tns:row>...</tns:row> </tns:rowset> </tns:EmployeeListResult> <tns:sqlcode>0</tns:sqlcode> </tns:EmployeeListResponse> |
ローセットの各ローは、次のようなフォーマットで送信されます。
<tns:row> <tns:EmployeeID xsi:type="xsd:int">1751</tns:EmployeeID> <tns:Surname xsi:type="xsd:string">Ahmed</tns:Surname> <tns:GivenName xsi:type="xsd:string">Alex</tns:GivenName> <tns:StartDate xsi:type="xsd:date">1994-07-12-04:00</tns:StartDate> <tns:TerminationDate xsi:type="xsd:date">2008-04-18-04:00 </tns:TerminationDate> </tns:row> |
カラム名とデータ型が含まれていることに注意してください。
XML メッセージ・トラフィックを記録するプロキシ・ソフトウェアを使用して、上記の応答を確認することができます。プロキシは、クライアント・アプリケーションと Web サーバの間に挿入されます。
EmployeeList 結果セットは、SASoapDemo アプリケーションによって「(型)カラム=値」のペアで表示されます。生成される出力は次のようになります。
EmployeeList 結果セットが「カラム名=値」のペアで表示されます。生成される出力は次のようになります。
Number of columns=4 EmployeeID=102 Surname=Whitney GivenName=Fran StartDate=1984-08-28-04:00 Number of columns=4 EmployeeID=105 Surname=Cobb GivenName=Matthew StartDate=1985-01-01-05:00 . . . Number of columns=4 EmployeeID=1740 Surname=Nielsen GivenName=Robert StartDate=1994-06-24-04:00 Number of columns=5 EmployeeID=1751 Surname=Ahmed GivenName=Alex StartDate=1994-07-12-04:00 TerminationDate=2008-04-18-04:00 |
TerminationDate カラムが送信されるのは、その値が NULL でない場合だけです。この例では、終了日に NULL 以外の値が設定され、Employees テーブルの最後のローが変更されました。
また、日付値には UTC (協定世界時) からのオフセットが含まれています。前述のサンプル・データでは、サーバは北米東部のタイムゾーンに属する場所にあります。つまり、標準時間の場合は UTC よりも 5 時間早く (-05:00)、夏時間の場合は UTC よりも 4 時間早い (-04:00) ことになります。
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |