Apache CXF と Aegis を使用した Web サービスの開発

CXF と Aegis のデータ・バインディングを使用した Web サービスの開発方法を学ぶ

Aegis は、Apache CXF Web サービス・フレームワークが標準でサポートしているデータ・バインディング・ツールの 1 つです。データ・バインディングは Java オブジェクトと XML 文書とをマッピングする機能です。この記事では、Aegis を使用して CXF ベースの Web サービスを作成する方法と、その Web サービスのデータ・バインディング要求をカスタマイズする方法について説明します。また、Aegis を使用するメリットについて、さらには Aegis の外部マッピング・ファイルを使用してバインディングをカスタマイズする方法について、特に重点的に説明します。

Rajeev Hathi, Java Architect, Writer

Rajeev HathiRajeev Hathi は J2EE プラットフォームに関するソフトウェア・コンサルタントです。彼はアーキテクチャーの設計、J2EE ベースのアプリケーションの設計や開発に専門的な関心を持っており、Java 技術と J2EE 技術 (コア Java、Web、EJB、アーキテクト) で SUN 認定を取得しています。また、IBM の developerWorks ポータルに何本かの技術記事を寄稿しているとともに、『Apache CXF Web Service Development』の共著者でもあります。彼の趣味は音楽鑑賞とスポーツ観戦です。彼の公式な Web サイトは技術ブログのサイト、http://www.rajeevhathi.comです。



2011年 7月 01日

Aegis とは何か

Apache CXF Web サービス・フレームワークはさまざまなデータ・バインディング・ツールをサポートしており、その 1 つが Aegis です。Aegis は Java オブジェクトと XML 文書とをマッピングするためのデータ・バインディング API です。CXF フレームワークは XFire プロジェクトから派生したものですが、この XFire プロジェクトが Aegis の基礎となっています。XFire は、現在は CXF と呼ばれています。開発者は Aegis を使用すると、アノテーションの使用の如何によらず、外部マッピング・ファイルを使用してデータ・バインディングを実行することができます。外部マッピング・ファイルを使用すれば、データのマッピングをカスタマイズすることができるため、マッピングの方法をより詳細に制御することができます。また、外部マッピング・ファイルを構成することで、非常に柔軟にデータ・バインディング要求を作成することができます。Web サービスの用語では、データはメッセージと呼ばれ、メソッドのパラメーターや戻り型の一部を構成しています。マッピング・ファイルを使用すると、Bean やメソッドの名前をカスタマイズできるだけではなく、メソッドのパラメーターや戻り型もカスタマイズすることができます。また CXF 環境以外のスタンドアロンのアプリケーションにも Aegis を使用することができます。

Aegis を使用するメリット

  • Aegis では外部マッピング・ファイルを使用できるため、開発者はマッピングを詳細に制御することや、柔軟にデータ・バインディング要求を作成することができ、プロジェクトの要求に応じたマッピングのカスタマイズが可能になります。
  • Java クラスが簡潔になります。JAXB とは異なり、データ・バインディング要求に対してアノテーションを付ける必要がまったくなく、外部マッピング・ファイルを使用してバインディングを制御することができます。
  • Aegis により、受信したメッセージやリクエストをスキーマに対して妥当性検証することができます。この妥当性検証機能は CXF の最新リリースに含まれている Woodstox 4.x Stax パーサーの一部です。
  • Aegis ではアノテーションを使用することもできます。そのため、外部マッピング・ファイルを使用したくない場合には、データ・バインディング要求に対してアノテーションを使用することができます。
  • Aegis は CXF 環境の外部で、単独で使用することができます。Aegis は XFire プロジェクトの一部に基礎を置く、独立したデータ・バインディング・ツールです。
  • Aegis を使用した Web サービスは、Aegis を使用していないクライアントからも利用することができます。クライアント・アプリケーションは JAXB をはじめとする任意のデータ・バインディング・ツールを使用することができ、その場合でも Aegis ベースのサービスを呼び出すことができます。
  • Aegis を使用すると、サービスのレベルでバインディングを規定することができます。JAXB ではプロパティーやパラメーターのレベルでバインディングを規定しますが、それとは異なり、Aegis では汎用のバインディングを規定することができます。例えばサービスのレベルで nillable=false を定義すると、すべてのプロパティーまたはパラメーターにヌルが許容されなくなります。

コード・サンプルを用いた説明

Aegis の使い方を説明するために、オンライン教育システム「Create Course (コースの作成)」の例を取り上げます。ご存知の通り、どの教育システムにも、学生が履修するように定められたコースがあります。これらのコースは、経営、芸術、科学、数学など、さまざまな分野に分類することができます。この記事では、コース作成者がコースを作成するための Web サービス機能を定義します。単純にするために、この機能はコースの属性をコンソールに表示するだけのものにします。この機能をとおして、Aegis の適用方法と、データ・バインディングの制御方法あるいはカスタマイズ方法について説明します。カスタマイズの内容としては、サービス・メソッドのパラメーター名や Bean のプロパティーを変更します。

わかりやすくするために、addCourse という関数を持つ、CourseManager という Web サービスを作成します。addCourse メソッドはパラメーターとして Course という Bean をとります。Course Bean には、2 つのプロパティー、つまりコードと名前が定義されます。Aegis の外部マッピング・ファイルを使用してメソッドのパラメーターと Bean のプロパティーをリネームし、その結果を SOAP ペイロードとして表示します。

動作環境は Windows とし、ビルドと実行には Apache Maven を使用します。Maven の pom ファイルには以下の依存関係が必要です。

リスト 1. Maven に必要な依存関係
<dependencies>
	<!-- Embedded Jetty server -->
	<dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-rt-transports-http-jetty</artifactId>
		<version>${cxf.version}</version>
	</dependency>
	<!-- Aegis databinding JAR -->
	<dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-rt-databinding-aegis</artifactId>
		<version>${cxf.version}</version>
	</dependency>
</dependencies>

完全なワークフローは以下のステップに分けられます。

  • 環境をセットアップする
  • Web サービスのインターフェースと実装クラスを作成する
  • クライアントとサーバーを作成する
  • ビルドして実行する
  • マッピング・ファイルを作成してデータ・バインディング要求をカスタマイズする
  • ビルドして実行し、データ・バインディングの適用による変更を確認する

環境をセットアップする

最初のステップとして、Windows プラットフォーム用の Apache CXF ディストリビューションが必要です。このディストリビューションは http://cxf.apache.org/download.html からダウンロードすることができます。おそらく最新の CXF リリースであるバージョン 2.4.0 がダウンロードされるはずです。ディストリビューションのアーカイブをダウンロードしたら、それを適当な場所、例えば C:\apache-cxf-2.4.0 に解凍します。次に Java バージョン 6.0 が必要になりますが、これは http://java.com/ja/download/index.jsp からダウンロードすることができます。ビルドに使用する Apache Maven は、http://maven.apache.org/download.html からダウンロードすることができます。Maven では JAVA_HOME 環境変数が JDK のインストール・フォルダーを指すように設定する必要があります。最後に、各インストールの bin フォルダーを PATH 環境変数に設定します。

Web サービスのインターフェースと実装クラスを作成する

単純な POJO クラス CourseManagerImpl とインターフェース CourseManager を作成します。このインターフェースは、パラメーターとして Course Bean をとる addCourse メソッドを定義します。実装クラスは以下のようになります。

リスト 2. CourseManagerImpl 実装クラス
public class CourseManagerImpl implements CourseManager {

	public void addCourse(Course course) {
		System.out.println("Course code: " + course.getCode());
		System.out.println("Course name: " + course.getName());
	}
}

上記のコードを見るとわかるように、@Webservice というアノテーションはありません。これはつまり、CXF の単純なフロントエンドを使用して CourseManager Web サービスを公開、利用するということです。開発者はこの単純なフロントエンドにより、アノテーションを使用せずに純粋な POJO として Web サービスのクラスをコーディングすることができます。addCourse メソッドは単純に course 属性をコンソールに出力します。もちろん実際には、course を実際にデータベースに追加するためのロジックを提供することもできますが、先ほど触れたように、ここでは Web サービスのメッセージ部分を Aegis のバインディングを使用してカスタマイズすることが大きな目的なので、単純なコードにとどめておきます。

Apache CXF のフロントエンド

CXF のフロントエンドは Web サービスを作成、公開、利用するためのさまざまなプログラミング API またはプログラミング・モデルとなっています。CXF でサポートされているフロントエンドには、アノテーション、動的クライアント、JAX-WS、そして単純なフロントエンドがあります。詳細については http://cxf.apache.org/docs/frontends.html を参照してください。

クライアントとサーバーを作成する

まず、CourseManager Web サービスを公開するサーバーを作成します。このサーバーのコードは以下のようなものです。

リスト 3. サーバー・コード
public final class Server {

    public static void main(String args[]) throws Exception {
		CourseManagerImpl implementor = new CourseManagerImpl();
		ServerFactoryBean svrFactory = new ServerFactoryBean();
		svrFactory.setAddress("http://localhost:9000/CourseManager");
		svrFactory.setServiceBean(implementor);
		svrFactory.create();
		System.out.println("Server ready...");
    }
}

上記のサーバー・コードは極めて単純です。このサーバーは、CXF の単純なフロントエンド API の一部である ServerFactoryBean クラスによって表現されています。このクラスにより、Web サービスの実装クラスやエンドポイントの URL など、必要なプロパティーを設定します。サービスの実装クラスは CourseManagerImpl であり、エンドポイントの URL は http://localhost:9000/CourseManager です。このエンドポイントの URL で CourseManager Web サービスが公開されます。組み込みの Jetty サーバーは、create メソッドによってポート 9000 で起動されます。

次のステップでは、CourseManager Web サービスを利用するクライアント・コードを作成します。

リスト 4. クライアント・コード
public final class Client {

    public static void main(String args[]) throws Exception {
		ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
		factory.setServiceClass(CourseManager.class);
		factory.setAddress("http://localhost:9000/CourseManager");
		factory.getOutInterceptors().add(new LoggingOutInterceptor());
		CourseManager client = (CourseManager) factory.create();
		Course course = new Course();
		course.setCode("C01");
		course.setName("English Grammer");
		client.addCourse(course);
    }
}

クライアント・コードはサーバー・コードとほとんど同じです。ただしクライアント・コードでは LoggingOutInterceptor インターセプター・クラスを使用して SOAP メッセージのログをコンソールに出力します。このようにしている理由は、Aegis のバインディングを適用したときに SOAP メッセージの変更を確認できるようにするためです。

ビルドして実行する

上で説明したコードを Maven を使用してビルドします。サーバー・クラスとクライアント・クラスはメインの Java アプリケーションであり、別のコマンド・ウィンドウで実行されます。もちろん、それらを Maven の java:exec goal を使用して実行することができます。最初にサーバーを起動し、次にクライアント・プログラムを実行します。クライアントからサーバーに対して、以下の SOAP メッセージが渡されるのがわかります。

図 1. SOAP ペイロード
SOAP ペイロード

この SOAP メッセージを注意深く見てみましょう。メソッド名 addCourse は SOAP ボディーのなかに 1 つの要素としてラップされています。メソッドのパラメーター Course Bean は <addCourse> 要素の子要素として作成されています。この子要素の名前は <arg0> です。<arg0> 要素の子要素は Course Bean の属性、つまり <code> と <name> です。

ここで、この SOAP メッセージを変更します。これらの要素名をリネームし、要素の意味が明確になるようにします。そして、CourseManager Web サービスに Aegis のバインディングを適用します。これについては、次のステップで説明します。

マッピング・ファイルを作成してデータ・バインディング要求をカスタマイズする

このステップでは、Aegis のデータ・バインディングを使用して SOAP 要素をカスタマイズします。<arg0> 要素は Course Bean を表しているので、<arg0> ではなく <course> にリネームすることにします。また、<code> 要素と <name> 要素もそれぞれ <courseCode> と <courseName> にリネームします。このような要素のカスタマイズを行うために、Aegis の外部マッピング・ファイルを使用します。Aegis には外部マッピング・ファイルという概念があり、この外部マッピング・ファイルを使用することで、バインディング要求に応じて多様なカスタマイズを指定することができます。

最初のステップとして、<arg0> 要素を <course> にリネームします。<arg0> 要素は Course Bean を表しており、Course Bean はサービスの addCourse メソッドのパラメーターなので、CourseManager サービスに対するマッピング・ファイルを作成します。マッピング・ファイルの命名方法は <classname>.aegis.xml となっています。このマッピング・ファイルは、マッピング元のクラスと共に同じパッケージの中に配置する必要があります。つまり下記の CourseManager.aegis.xml は demo.cxf.aegis パッケージの一部になります。

リスト 5. CourseManager.aegis.xml マッピング・ファイル
<mappings>
    <mapping name="CourseManager">
        <method name="addCourse">
            <parameter index="0" mappedName="course" nillable='false' />
        </method>
    </mapping>
</mappings>

上記のマッピング・ファイルは容易に理解することができます。マッピングの名前 CourseManagerCourseManager という Web サービスをマッピングすることを示しています。addCourse メソッドには 1 つのパラメーター (Course Bean) があり、そのパラメーターのインデックスは 0 です。つまりマーシャリングを実行する際に、この 0 番目のインデックス・パラメーターを course にリネームします。そうすることで <arg0> 要素が必ず <course> にリネームされることになります。nillable=false はパラメーターがヌルであってはならないことを意味します。

今度は、<arg0> 要素の一部であった SOAP 要素 <code> と <name> をリネームします。そのために、Course Bean をマッピングする別のマッピング・ファイルを作成します。Course Bean の属性もバインディングの際にリネームする必要があるからです。下記の Course.aegis.xml ファイルは demo.cxf.aegis パッケージの一部になります。

リスト 6. Course.aegis.xml マッピング・ファイル
<mappings>
    <mapping name="Course">
		<property name="code" mappedName="courseCode" nillable='false' />
		<property name="name" mappedName="courseName" nillable='false' />
    </mapping>
</mappings>

上記のマッピング・ファイルは Course Bean をマッピングし、マーシャリングされた code パラメーターと name パラメーターをそれぞれ courseCodecourseName にリネームします。これで、CourseManager Web サービスと Course Bean に対するバインディング・ルールを無事に定義することができました。

最後に、クライアント・コードとサーバー・コードに Aegis の機能を追加する必要があります。

リスト 7. サーバー・コードに Aegis のデータ・バインディング機能を追加する
. . .
		CourseManagerImpl implementor = new CourseManagerImpl();
		ServerFactoryBean svrFactory = new ServerFactoryBean();
		svrFactory.setAddress("http://localhost:9000/CourseManager");
		svrFactory.setServiceBean(implementor);
svrFactory.getServiceFactory().setDataBinding(new AegisDatabinding());
		svrFactory.create();
		System.out.println("Server ready...");
    }
}
リスト 8. クライアント・コードに Aegis のデータ・バインディング機能を追加する
. . .
		ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
		factory.setServiceClass(CourseManager.class);
		factory.setAddress("http://localhost:9000/CourseManager");
factory.getServiceFactory().setDataBinding(new AegisDatabinding());
. . .		
    }
}

ビルドして実行し、データ・バインディングの適用による変更を確認する

変更されたコードをビルドすると、以下のような出力が生成されます。

図 2. Aegis のデータ・バインディングを適用した後の SOAP ペイロード
Aegis のデータ・バインディングを適用した後の SOAP ペイロード

これで、上記の SOAP ペイロードの意味は先ほどよりも明確になりました。Aegis のデータ・バインディングを適用した結果、<arg0> 要素は <course> に変更され、その子要素の <code> と <name> はそれぞれ <courseCode> と <courseName> に変更されています。

Aegis のバインディングを使用すると、単に SOAP ペイロードの要素をリネームする以外にも、以下に挙げるようなさまざまなことができます。例えば、ある要素を属性にしたり、メソッドのパラメーターや Bean のプロパティーを nillable または非 nillable にしたりすることができます。要素や属性に名前空間を追加することもできます。また、Bean の特定のプロパティーをシリアライズするかどうかを指定することもできます。それらとはまったく別に、Aegis のデフォルト・タイプに対するカスタム・タイプを指定し、マッピングを実行することもできます。

参考文献

学ぶために

製品や技術を入手するために

  • 皆さんの目的に最適な方法で IBM 製品を評価してください。製品の試用版をダウンロードする方法、オンラインで製品を試す方法、クラウド環境で製品を使う方法、あるいは SOA Sandbox で数時間を費やし、サービス指向アーキテクチャーの効率的な実装方法を学ぶ方法などがあります。

議論するために

  • My developerWorks コミュニティーに加わってください。開発者向けのブログ、フォーラム、グループ、ウィキなど利用しながら、他の developerWorks ユーザーとやり取りしてください。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=SOA and web services
ArticleID=682417
ArticleTitle=Apache CXF と Aegis を使用した Web サービスの開発
publish-date=07012011