レベル: 中級 Tyler Anderson (tyleranderson5@yahoo.com), Freelance writer
2007年 3月 20日 XML は、ほとんど何についてでも定義できるという意味で強力です。しかも、大部分のアプリケーションにとって、特にこのシリーズの目的である Axis2 と JiBX にとっては、外部から読み取り可能なフォーマットの基本でもあります。それに加え、Web サービスがより一般的になってきたため、レガシーの Java® プロジェクトを完全機能の Web サービスに変換することの緊急度が次第に高まっています。これまで、Web サービスの自動生成は 1 つのサービスや1 つのクラスに限定されていましたが、現在では、既存のプロジェクトの中にあるさまざまな Java クラスから 1 つ以上のサービスを生成するという選択肢があります。この記事は 2 回シリーズの第 1 回として、XML を使って既存の Java クラスから Web サービスを定義します。
はじめに
Web サービスは、日々の開発作業にとってますます重要なものになりつつあります。そして、Web サービスを開発するためのオープンソース・プラットフォームの選択肢として人気の高いものの 1 つが Axis2 です。Axis2 は Java 言語で書かれており、XML を Java にバインドするためのフレームワークである JiBX の自由さを大いに活用することができます。皆さんは既に膨大な Java クラスやデータ構造を含んだ Java プロジェクトを持っており、そうしたクラスやデータを混乱させたり変更したりすることは絶対に避けたいはずです。JiBX は、Axis2 が使う XML データを皆さんの Java クラスにバインドすることによって、それを実現します。この方法の利点はコードの維持管理が容易になることです。なぜなら Web サービスは、既に開発され、使用された、真の Java クラスしか使わないからです。
この記事では、この 2 回シリーズの記事で使用する Java クラスを導入し、そうした Java クラスを正確に記述する WSDL (Web Services Description Language) と JiBX 定義を生成する方法を説明します。このシリーズの第 2 回では、この WSDL と JiBX XML 文書を使って、データ・バインディングとして皆さんの Java クラスを使う Web サービスの Java 実装を作ります。
システム要件
この 2 回シリーズでは、下記が必要です。
- Axis2 のバイナリーと WAR ディストリビューション。これは Axis2 のホームページからダウンロードすることができます (「参考文献」を参照)。
- JiBX 1.1。これは JiBX SourceForge ページからダウンロードすることができます (「参考文献」を参照)。
- Geronimo 1.1.1。これは Geronimo のホームページからダウンロードすることができます (「参考文献」を参照)。
これらをすべて入手したら、Geronimo を解凍し、java -jar <geronimo-home>/bin/server.jar と入力します。
次に、axis2.war ファイルをデプロイするために、axis2 を <geronimo-home>/deploy ディレクトリーにコピーします。
Axis2 バイナリーを解凍し、AXIS2_HOME 環境変数を、Axis2 バイナリーを解凍したディレクトリー (私の場合は c:\apps\axis2-1.1) に設定します。次に JiBX を解凍し、<jibx-home>/lib にあるすべての JAR (ただし Axis2 は既に stax-api.jar を持っているため、stax-api.jar は除きます) を、<axis2-home>/lib ディレクトリーにコピーします。
これで環境がすべて整いました。
Java クラス
ここでは、単純な Web サービス Java プロジェクトを構成する、いくつかの Java クラスを用意しました。実際の Java クラスはそれほど重要ではないので、皆さんがこれまでに作成した任意の Java クラスを使うことができます。このプロジェクトには、OneWayRequest と TwoWayRequest、そして TwoWayResponse という 3 つのクラスがあります。これらを順番に見てみましょう。まず OneWayRequest です (リスト 1)。
リスト 1. OneWayRequest Java クラス
package com.ibm.devWorks.xml.simpleService;
public class OneWayRequest {
protected String requestData;
public String getRequestData() {
return this.requestData;
}
public void setRequestData(String requestData) {
this.requestData = requestData;
}
}
|
これを見ると、リクエストのデータを含む、requestData という 1 つのフィールドがあることがわかります。このクラスは 2 つのメソッドを持っており、1 つはこのフィールドを設定し、もう 1 つはそのフィールドの値を取得します。
次に TwoWayRequest クラスを見てみます (リスト 2)。
リスト 2. TwoWayRequest Java クラス
package com.ibm.devWorks.xml.simpleService;
public class TwoWayRequest {
protected String echoString;
protected boolean booolean;
public boolean getBooolean() {
return this.booolean;
}
public void setBooolean(boolean booolean) {
this.booolean = booolean;
}
public String getEchoString() {
return this.echoString;
}
public void setEchoString(String echoString) {
this.echoString = echoString;
}
}
|
このクラスは少し大きく、echoString と booolean という 2 つのフィールドを含んでいます。この前のクラスと同じく、このクラスは各フィールドに対して getter メソッドと setter メソッドを持っています。
今度は最後のクラス、TwoWayResponse を見てみましょう (リスト 3)。
リスト 3. TwoWayResponse Java クラス
package com.ibm.devWorks.xml.simpleService;
public class TwoWayResponse {
protected String echoString;
protected boolean invertedBoolean;
public boolean getInvertedBoolean() {
return this.invertedBoolean;
}
public void setInvertedBoolean(boolean invertedBoolean) {
this.invertedBoolean = invertedBoolean;
}
public String getEchoString() {
return this.echoString;
}
public void setEchoString(String echoString) {
this.echoString = echoString;
}
}
|
このクラスは、この前のクラス TwoWayRequest とよく似ていますが、似ている必要はありません。皆さんのレスポンス・クラスはデータベースのレコードからのデータ項目をいくつか含んでいるかもしれません。これで Java クラスは終わりです。次は、こうしたクラスを Web サービスとして公開する WSDL を見てみましょう。
WSDL を使ってサービスとして Java クラスを公開する
このシリーズの第 2 回では、このセクションで作成する WSDL を Axis2 を使って読み取り、Web サービスの Java 実装を作成します。
先に進む前に、ここで意図している Web サービスについて少し知っておく必要があります。OneWayRequest クラスは、リクエスト・データをフィールド requestData に入れて送信する、リクエストのみの片方向の Web サービス操作を表します。TwoWayRequest クラスと TwoWayResponse クラスはリクエストとレスポンスという両方向の Web サービス操作を表し、レスポンスの echoString フィールドはリクエストの echoString フィールドと同じ値を持ちます。またレスポンスの invertedBoolean フィールドは、リクエストの booolean フィールドの値を反転したものです (リクエストの booolean が false の場合は、レスポンスの invertedBoolean フィールドの値として true が送信されます)。
今度は WSDL に移りましょう。まず名前空間を設定します (リスト 4)。
リスト 4. WSDL の名前空間を定義する
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="http://ibm.com/developerWorks/xml/SimpleService"
xmlns:intf="http://ibm.com/developerWorks/xml/SimpleService"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://ibm.com/developerWorks/xml/SimpleService">
...
|
これらは基本的に WSDL を準備しており、後で、この WSDL の中で名前空間を参照します。Axis2 がこの WSDL ファイルを読み取る際、Axis2 は参照されている名前空間の値を知る必要があります。
次に、スキーマを定義します (リスト 5)。
リスト 5. スキーマを定義する
targetNamespace="http://ibm.com/developerWorks/xml/SimpleService">
<wsdl:types>
<schema
elementFormDefault="qualified"
targetNamespace="http://ibm.com/developerWorks/xml/SimpleService"
xmlns="http://www.w3.org/2001/XMLSchema">
<!-- ELEMENTS -->
<element name="OneWayRequest">
<complexType>
<sequence>
<element name="requestData" type="xsd:string"/>
</sequence>
</complexType>
</element>
<element name="TwoWayRequest">
<complexType>
<sequence>
<element name="echoString" type="xsd:string"/>
<element name="booolean" type="xsd:boolean"/>
</sequence>
</complexType>
</element>
<element name="TwoWayResponse">
<complexType>
<sequence>
<element name="echoString" type="xsd:string"/>
<element name="invertedBoolean" type="xsd:boolean"/>
</sequence>
</complexType>
</element>
</schema>
</wsdl:types>
... |
これは皆さんにおなじみのはずです。これらは基本的に、あるスキーマで定義された Java クラスです。Java クラスのフィールドが、上記のスキーマの要素のサブ要素と一致することに注意してください。また、名前空間 (http://ibm.com/developerWorks/xml/SimpleService) にも注意してください。この名前空間は、後で JiBX 定義記述を作成する際に重要になります。
今度は、WSDL のメッセージとポート・タイプ、バインディング、そしてサービスを定義します (リスト 6)。
リスト 6. WSDL の定義を完成させる
...
</wsdl:types>
<!-- MESSAGES -->
<wsdl:message name="OneWayRequestMessage">
<wsdl:part name="input" element="impl:OneWayRequest"/>
</wsdl:message>
<wsdl:message name="TwoWayRequestMessage">
<wsdl:part name="input" element="impl:TwoWayRequest"/>
</wsdl:message>
<wsdl:message name="TwoWayResponseMessage">
<wsdl:part name="output" element="impl:TwoWayResponse"/>
</wsdl:message>
<!-- Port type (operations) -->
<wsdl:portType name="SimpleServicePortType">
<wsdl:operation name="OneWay" parameterOrder="input">
<wsdl:input name="OneWayRequestMessage"
message="impl:OneWayRequestMessage"/>
</wsdl:operation>
<wsdl:operation name="TwoWay" parameterOrder="input">
<wsdl:input name="TwoWayRequestMessage"
message="impl:TwoWayRequestMessage"/>
<wsdl:output name="TwoWayResponseMessage"
message="impl:TwoWayResponseMessage"/>
</wsdl:operation>
</wsdl:portType>
<!-- BINDING (bind operations) -->
<wsdl:binding
name="SimpleServiceSoapBinding"
type="impl:SimpleServicePortType">
<wsdlsoap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="OneWay">
<wsdlsoap:operation soapAction="OneWay"/>
<wsdl:input>
<wsdlsoap:body use="literal"/>
</wsdl:input>
</wsdl:operation>
<wsdl:operation name="TwoWay">
<wsdlsoap:operation soapAction="TwoWay"/>
<wsdl:input>
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<!-- SERVICE -->
<wsdl:service name="SimpleService">
<wsdl:port binding="impl:SimpleServiceSoapBinding"
name="SimpleService">
<wsdlsoap:address location="http://localhost:8080/axis2/services/SimpleService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
|
定義されるメッセージはスキーマの中のリクエスト要素とレスポンス要素にマップされ、各操作の入出力がメッセージにマップされるポート・タイプ定義で使われます。バインディング・セクションは基本的に、ある操作を SOAP アクションにマップし、バインドされるサービスとそれに付随する操作のプロトコルとトランスポート方法を厳密に定義します。最後に、サービス・セクションは、利用可能なサービスを指定し、それぞれのサービス・エンドポイント (サービスにアクセスするための URL) を示します。
これで Web サービスの定義は終わりです。次に、XML を Java クラスにマップします。これによって、次回の記事でデータ・バインディングのオプションとして JiBX を使うことができます。
JiBX 定義記述を作成する
JiBX 定義記述の主な目的は、Java クラスを (必要なフィールドを含めて) 名前空間にマップすることです。その意味は、このセクションで作成されるファイルを見るともっとよくわかるはずです。まず、OneWayRequest クラスがどのようにマップされているかを見てください (リスト 7)。
リスト 7. OneWayRequest Java クラスをマップする
<?xml version="1.0" encoding="UTF-8"?>
<binding>
<mapping name="OneWayRequest"
class="com.ibm.devWorks.xml.simpleService.OneWayRequest">
<namespace uri="http://ibm.com/developerWorks/xml/SimpleService"
default="elements"/>
<value name="requestData" field="requestData" usage="required"/>
</mapping>
...
|
mapping タグの name 属性は、リスト 5 で作成した WSDL スキーマの OneWayRequest 要素に直接関連付けられる要素の名前を指定します。class 属性は、この要素を要素の Java クラス (リスト 1 に示した Java クラス) にマップします。namespace タグの uri 属性は、このマッピングを名前空間 http://ibm.com/developerWorks/xml/SimpleService (リスト 5 で示した OneWayRequest 要素と同じ名前空間) に置きます。最後にvalue タグの中で、リスト 5 の WSDL に示した requestData サブ要素が、リスト 1 に示した Java クラスの requestData フィールドにマップされていることがわかります。name 属性は WSDL の中のサブ要素を指定し、そしてフィールド属性は Java クラスの中のフィールド名を指定します。
次に、これ以外の 2 つの Java クラスがどのようにマップされているかを見てみましょう (リスト 8)。
リスト 8. TwoWayRequest Java クラスと TwoWayResponse Java クラスをマップする
...
<mapping name="TwoWayRequest"
class="com.ibm.devWorks.xml.simpleService.TwoWayRequest">
<namespace uri="http://ibm.com/developerWorks/xml/SimpleService"
default="elements"/>
<value name="echoString" field="echoString" usage="required"/>
<value name="booolean" field="booolean" usage="required"/>
</mapping>
<mapping name="TwoWayResponse"
class="com.ibm.devWorks.xml.simpleService.TwoWayResponse">
<namespace uri="http://ibm.com/developerWorks/xml/SimpleService"
default="elements"/>
<value name="echoString" field="echoString" usage="required"/>
<value name="invertedBoolean" field="invertedBoolean"
usage="required"/>
</mapping>
</binding>
|
リスト 8 を見ると、OneWayRequest クラスがマップされている様子と、TwoWayRequest クラスと TwoWayResponse クラスがマップされている様子とが似ていることがわかります。しかし今回は、名前とクラス、フィールドは、TwoWayRequest 要素と TwoWayResponse 要素の適当なデータを指しています。そして 1 つの違いは、これら 2 つの要素が 2 つのサブ要素あるいはフィールドを持っていることです。もし mapping タグがサブ要素を何も持たない場合は、その mapping タグは value タグを持つ子を持ちません。もし mapping タグが複数のサブ要素を持つ場合には、リスト 8 に示したように value タグが順次リストされます。
まとめ
素晴らしい!これで半分完成しました。ここでは、既存の Java クラスをとりあげ、そのクラスに対して XML スキーマを定義し、そして WSDL を使って Web サービスの操作でこのクラスを公開しました。また、Java クラスをスキーマの要素にマップする JiBX 定義記述を作成しました。それによって、Axis2 JiBX データ・バインディングは Web サービスの SOAP データを Java クラスに適切にバインドすることができました。
第 2 回では、Axis2 が JiBX 定義記述を使ってサービス・スケルトンとクライアント・スタブを生成します。そして最終的な Apache Axis2 Web サービスを Apache Geronimo にデプロイし、デプロイしたサービスと通信するクライアントを作成して、このサービスのテストを行います。
ダウンロード | 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|
| Part 1 sample code | x-jibx1-source.zip | 3KB | HTTP |
|---|
参考文献 学ぶために
製品や技術を入手するために
議論するために
著者について  | |  | Tyler Andersonは2004年にBrigham Young Universityにてコンピューター・サイエンスの学位を取得しており、現在はコンピューター・エンジニアリングの修士取得に向けての最終学期を送っています。これまで、DPMG.COMのデータベース・プログラマーとして働いたことがあり、現在はオレゴン州BeavertonにあるStexar Corp.のエンジニアです。 |
記事の評価
|