Apache Wink による RESTful な Web サービス: 第 2 回 Apache Wink REST 開発での高度なトピック

アノテーション、統合、その他

この記事では 3 回連載の第 2 回として、REST ベースの Web サービスを実装、利用するための新しい Java™ フレームワーク、Apache Wink 1.0 による開発での高度なトピックについて説明します。

Vishnu Vettrivel , Principal Consultant, PunditLabs

Photo of Vishnu VettrivelVishnu Vettrivelは、企業向けコンサルティングおよび技術を専門とする PunditLabs の主任コンサルタントで、10 年以上にわたり、ミッション・クリティカルなエンタープライズ・アプリケーションの構築、設計、開発に携わっています。フォーチュン 50 社に挙げられたさまざまなクライアントに協力し、多くの新しい技術に対する戦略的技術計画を立ててきました。



2010年 3月 09日

この記事では、Apache Wink バージョン 1.0 による開発に関連する高度なトピックとして、前回説明しなかったアノテーションの使い方、よく使われている Spring フレームワークと Wink サービスとの統合、そして Apache Wink クライアント・フレームワークを使用した RESTful なカスタム・クライアントの実装方法について説明します。

よく使われる頭字語

  • API: Application Programming Interface
  • CSV: Comma-Separated Values
  • HTTP: HyperText Transfer Protocol
  • JSON: JavaScript Object Notation
  • MIME: Multipurpose Internet Mail Extensions
  • RSS: Really Simple Syndication
  • URI: Uniform Resource Identifier
  • XML: Extensible Markup Language

アノテーション

JAX-RS では、アノテーションは受信した HTTP リクエストの情報を Java™ メソッドに注入するための中心的なメカニズムの 1 つです。Apache Wink は JAX-RS 準拠のフレームワークとして、JAX-RS 仕様で必須とされるアノテーションを実装していますが、それ以外にも、例えば @Asset アノテーションや @Scope アノテーションなど、必須ではない多様なアノテーションを提供しています。

@Asset アノテーション

@Asset アノテーションは Java クラスをアセットとして識別するためのマーカーとして使われます。アセットはリソース・メソッドが返すエンティティー・オブジェクトの特別な形式です。Apache Wink のランタイムは、リソース・メソッドの中にパラメーターとしてアセットを注入することもできます。アセットはデータ・モデルのコンテナー・オブジェクトであり、さまざまなコンテンツ・タイプに対する変換メソッドを提供します。アセットはリソースとプロバイダーとの間での情報の受け渡しに使われ、また Apache Wink システムに登録されるプロバイダーの数を減らすのに役立ちます。この点は重要です。プロバイダーの数が増えると Wink システムのパフォーマンスが低下するからです。

リスト 1@Asset アノテーションの使い方を示しています。Transaction Bean は JAXB (Java Architecture for XML Binding) の class.TransactionAsset クラスです。TransactionAsset クラスは Transaction Bean のインスタンスをラップします (リスト 1)。

リスト 1. TransactionAsset クラス
@Asset
public class TransactionAsset {
	public Transaction transaction;   						
	public TransactionAsset(Transaction transaction) {
		this.transaction = transaction;
    }
 	@Produces("application/xml")
    public Transaction getTransaction() {
        return this.transaction;
    }
	@Consumes("application/xml")
	public void setTransaction(Transaction transaction) {
		this.transaction = transaction;
    }
}

TransactionAsset クラスはリソース・メソッドによってレスポンスとして返される場合もあり、またパラメーターとして渡される場合もあります。Apache Wink ランタイムは TransactionAsset クラスを使用して (TransactionAsset クラスの対応するメソッドを呼び出すことで) 実際のレスポンス・エンティティーを作成します。

@Scope アノテーション

JAX-RS の仕様によれば、プロバイダー・クラスとリソース・クラスはデフォルトで、各 JAX-RS アプリケーションごとに 1 度インスタンス化されます。このインスタンス化では、各クラスのデフォルトのコンストラクターが呼び出され、その後で依存関係の注入が行われます。

プロバイダー・オブジェクトとリソース・オブジェクトのメソッドは、そのオブジェクトの存続中に繰り返し呼び出され、その後ガーベッジ・コレクションによる処理が行われます。Apache Wink ではそれ以外に、@Scope アノテーションを使用することで、プロバイダーとリソースのライフサイクルを指定することができます。リスト 2 はプロトタイプ (リクエストごとの) ライフサイクルを使ってリソースを定義する方法を示しています。

リスト 2. @Scope アノテーションの例
@Scope(ScopeType.PROTOTYPE)
@Path("helloworld")
public class HelloWorldResource {
    ...
}

プロトタイプ・ライフサイクルの場合、Apache Wink のランタイムは受信したリクエストごとに新しいオブジェクトをインスタンス化します。この動作はメモリーとパフォーマンスの点では理想的ではないかもしれませんが、この動作のおかげで、リソース・クラスとプロバイダー・クラスのスレッド処理と並行処理の問題を心配する必要がなくなります。

@Parent アノテーション

この連載の第 1 回では、@Path アノテーションについて詳細に説明し、また JAX-RS では受信したリクエストと突き合わせる URI のパターンを定義するために @Path アノテーションが使われることも説明しました。@Path アノテーションは通常、Java のクラスまたはメソッドの中に置かれます。

@Parent アノテーションは @Path アノテーションと密接に「関係」しており、リソースの中に指定されている URI に対する基底 URI を指定します。Apache Wink ランタイムはリソースの中で @Parent アノテーションを見つけると、リソースの最終的な URI テンプレートを導き出そうとします。そのためにまず、親のリソース・クラスの URI を持つ @Parent アノテーションの値を計算し、続いてリソース・パスの URI を親のリソース・パスの URI と連結しようとします。リスト 3@Parent アノテーションの例を示しています。

リスト 3. @Parent アノテーションの例
@Path("parentservice")
public class ParentResource {
    ...
}

@Parent(ParentResource.class)
@Path("childservice")
public class ChildResource {
    ...
}

この例には ParentResourceChildResource という 2 つのリソースがあります。ParentResource@Path アノテーションによって parentservice という URI を定義しています。ChildResource@Path アノテーションによって childservice という URI を定義しています。また ChildResource は、ParentResource が自分の親であることを @Parent アノテーションを使って定義しています。この例では、Apache Wink ランタイムはChildResource の最終的な URI パスが parentservice/childservice であるとしています。


管理ビュー

RESTful な Web サービスをよく理解できるように、Apache Wink には管理ビューとして、アプリケーション・リソース XML ビューとリソース・レジストリー XML ビューという 2 つのタイプが用意されています。この 2 つのビューはどちらもデフォルトで無効になっており、有効にするためにはアプリケーションの web.xml ファイルに org.apache.wink.server.internal.servlet.AdminServlet クラスを登録する必要があります。

アプリケーション・リソース XML ビューは REST リソースを表示し、またそれらのリソースの URI テンプレート、HTTP メソッド、そして各メソッドがサポートする MIME タイプも表示します。これはユーザーに対してアプリケーションが表示される場合と似ています。このビューは、デプロイされたサービスのドキュメントを自動生成する場合に便利です。

リソース・レジストリー XML ビューはアプリケーション・リソース XML ビューよりも詳細であり、公開されたサービスの実際の実装の詳細を表示します (例えばリソースを実装するクラスの名前、レジストリーの中でのそれらの優先順位など)。このビューはデバッグ用には便利ですが、実装の詳細を表示することがセキュリティー上問題になる可能性があるため、本番環境では有効にすべきではありません。


WebDAV のサポート

WebDAV (Web-based Distributed Authoring and Versioning) は HTTP のコア・プロトコルに対する一連の拡張機能であり、これらの機能を利用することで Apache Web サーバーなどの Web サーバー上でファイルの編集や管理をすることができます。WebDAV プロトコルの主な機能は以下のとおりです。

  • ファイルのロック
  • ファイルのプロパティーやメタデータ
  • ファイルの名前空間の管理

Apache Wink は拡張モジュールによって WebDAV プロトコルをサポートしています。この Apache Wink の拡張モジュールには、WebDAV レスポンスの作成と処理を支援する WebDAV XML モデルと WebDAV レスポンス・ビルダーが含まれています。


Spring との統合

Spring は一般的に使用されているオープンソースの Java フレームワークであり、元々は EJB (Enterprise JavaBean) 技術などの既存の Java 標準に代わる軽量の手段のはずでした。EJB 標準と同様、Spring フレームワークにも、トランザクション、パーシスタンス、セキュリティー、そして最も重要な、依存性注入のための機能が用意されています。依存性注入の概念は JAX-RS にも採用されています。Spring フレームワークの詳細については「参考文献」を参照してください。

Apache Wink では、コア・フレームワークに付属する追加のモジュールを使用することによって、容易に Spring を統合することができます。Apache Wink の Spring 統合モジュールの主な機能は以下のとおりです。

  • リソースやプロバイダーをクラスまたは Spring Bean として、Spring のコンテキストの中から登録することができます。
  • リソースとプロバイダーのライフサイクルを定義したり、デフォルトのシングルトン・スコープを上書きしたりすることができます。
  • IoC (Inversion of Control: 制御の反転) やポストプロセッサーといった Spring の機能を利用することができます。
  • Spring のコンテキストの中から、容易にカスタマイズ可能なフックを使って Apache Wink をカスタマイズすることができます。

Spring コンテキストのロード

Spring フレームワークでの Spring のコンテキストは Apache Wink アプリケーションと似ており、どの Spring Bean が定義、ロードされるよりも前にロードされなければなりません。いったん Spring のコンテキストがロードされると、リソースやプロバイダーを Spring Bean として容易に登録することができます。

Spring のコンテキストをロードするためには、まず Web アプリケーションの web.xml ファイルにコンテキスト・ロード・リスナーを定義して追加する必要があります。また、Apache Wink のコア・コンテキスト・ファイルとアプリケーション専用のコンテキスト・ファイルの場所を contextConfigLocation という context-param で指定する必要があります。リスト 4 は Spring のコンテキストを定義してロードする web.xml ファイルの例を示しています。

リスト 4. Spring のコンテキストをロードする web.xml の例
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:META-INF/server/winkCoreContext-server.xml
	classpath:mySpringcontext.xml
</param-value>
</context-param>
<listener>
<listener-class>
	org.springframework.web.context.ContextLoaderListener
  	</listener-class>
</listener>

リソースとプロバイダーの登録

Spring のコンテキストがロードされると、Apache Wink に用意された org.apache.wink.spring.Registrar クラスを使ってリソースとプロバイダーを登録することができます。この Registrar クラスはおなじみの WinkApplication クラスの拡張であり、最初に Spring Bean として定義する必要があります。

org.apache.wink.spring.Registrar クラスを使用すると以下のプロパティーを定義することができます。

  • instances: リソースとプロバイダーのインスタンスは通常、Spring Bean として定義され、IoC その他の Spring の機能を自動的に持ちます。
  • classes: リソースとプロバイダーのクラス名を定義することができます。このプロパティーは Wink Application クラスの getClasses メソッドのプロパティーと同じです。
  • priority: このプロパティーは WinkApplication の優先度を定義します。

リスト 5 は Spring Bean の構成ファイルの例であり、Apache Wink のリソースとプロバイダーを Spring Bean として定義しています。

リスト 5. Spring の構成ファイルの例 (mySpringcontext.xml)
<bean class="org.apache.wink.spring.Registrar">
  <property name="classes">
    <set value-type="java.lang.Class">
      <value>org.openengine.example.TransactionResource</value>
    </set>
  </property>
  <property name="instances">
    <set>
      <ref bean="resources.TransactionResource"/>
      <ref bean="providers.myprovider"/>
    </set>
  </property>
</bean>

クライアントとしての Wink

Apache Wink は JAX-RS 準拠のサーバー・フレームワークですが、それとは別に、Apache Wink には高度なクライアント・フレームワークが用意されています。この Apache Wink クライアント・フレームワークの単純な Java API を使用すると、HTTP ベースの RESTful な Web サービスを利用するクライアントを容易かつ単純に実装することができます。また Apache Wink クライアント・フレームワークには HTTP リクエストと HTTP レスポンスを扱うためのカスタマイズ可能なハンドラー・メカニズムもあります。Apache Wink クライアントは JAX-RS の基本原則に基づいて構築されており、REST ベースの概念や標準を取り込んでいます。こうした REST が持つさまざまな概念を Java クラスに対応させると、Apache Wink ベースのサービスに対するクライアントを作成する際に役立つだけではなく、HTTP を利用する RESTful な任意の Web サービスを作成する際にも役立ちます。そのため、Apache Wink クライアントは REST をベースにしたスタンドアロンの Java クライアント・フレームワークとして、非常に有用です。

下記は Apache Wink クライアント・フレームワークの主な機能を挙げたものです。

  • 構成可能な JAX-RS プロバイダーを使用して、リソースをシリアライズ、デシリアライズすることができます。
  • さまざまなコンテンツ・タイプ (Atom、JSON、RSS、APP、CSV、Multipart など) や、それらに対応する Java のオブジェクト・モデルを組み込みでサポートしています。
  • SSL (Secure Sockets Layer) と HTTP プロキシーをサポートしています。
  • Apache Wink クライアント・フレームワークはサーバー・サイド・フレームワークと同様、HTTP リクエストとレスポンスを操作するための構成可能なハンドラー・チェーンを備えています。
  • HTTP のコア・トランスポートとしてデフォルトで java.net.HttpUrlConnection クラスを使用します。
  • HTTP のコア・トランスポート・メカニズムを容易にカスタマイズすることができます。

図 1 は Apache Wink クライアント・フレームワークのアーキテクチャーを示したものです。

図 1. Apache Wink クライアントのアーキテクチャー
左側の 4 つのボックスには「Resources (リソース)」というラベルが付いています。この 4 つのボックスから出た矢印はすべて、「Handler (ハンドラー)」というラベルの付いたボックスを指しており、「Invoke method (メソッドの呼び出し)」というラベルが付いています。これらのボックスの上には「RestClient」というラベルの付いたボックスがあります。下には 2 つのボックスがあり、それぞれ「Provider registry (プロバイダーのレジストリー)」と「Configuration (構成)」というラベルが付いています。

これを見るとわかるように、Apache Wink クライアント・フレームワークは主に「RestClient」クラスで構成されています。RestClient クラスは中心的なエントリー・ポイントとして動作し、さまざまな構成、そしてプロバイダーのレジストリーを保持しています。Apache Wink クライアント・フレームワークを扱うためには、RestClient オブジェクトを新たにインスタンス化する必要があります。次に、接続先となるサービスの URI を使って RestClient クラスのインスタンスから Resource クラスのインスタンスを作成します。Resource クラスは特定の URI に関連付けられた RESTful な Web リソースの Java 版であり、そのリソースに対して HTTP ベースの操作を実行するために使われます。HTTP メソッドの呼び出しはすべて、カスタマイズ可能なハンドラー・チェーンによってフィルタリングされます (ハンドラー・チェーンによって HTTP リクエストと HTTP レスポンスを扱うのが容易になります)。

GET リクエスト

リスト 6 は Apache Wink クライアントを使用する場合の HTTP GET リクエストの使い方を示しています。

リスト 6. GET リクエストの例
// create the rest client instance
RestClient client = new RestClient();

// create the resource instance to interact with
Resource resource = client.resource("http://localhost:8080/HelloWorld");

// perform a GET on the resource. The resource will be returned as plain text
String response = resource.accept("text/plain").get(String.class);

既に触れたように、RestClient オブジェクトは Apache Wink クライアント・フレームワークのエントリー・ポイントです。RESTful な Web サービス・クライアントを作成するためには、RestClient オブジェクトの新しいインスタンスをインスタンス化する必要があります。それを終えた後、RestClient#resource() メソッドを呼び出すと、呼び出し対象のサービスの URI を持つ新しい Resource オブジェクトが作成されます。HTTP GET リクエストを発行するためには、Resource#get() メソッドを呼び出します。このメソッドによって HTTP レスポンスが返されます。次に、適切なプロバイダーを呼び出すと、クライアントはレスポンスをデシリアライズします。

POST リクエスト

リスト 7 は Apache Wink クライアントを使用する場合の HTTP POST リクエストの使い方を示しています。

リスト 7. POST リクエストの例
// create the rest client instance
RestClient client = new RestClient();

// create the resource instance to interact with
Resource resource = client.resource("http://localhost:8080 ");

// issue the request
String response = resource.contentType("text/plain").
			accept("text/plain").
				post(String.class, "foo");

これを見るとわかるように、POST リクエストの発行は GET リクエストの発行と似ています。GET リクエストの例とまったく同じように、RestClient を使って Resource の新しいインスタンスを作成します。唯一異なる点は、リクエストとレスポンスのメディア・タイプ、そしてレスポンスのエンティティー・タイプを指定した後、POST ストリング自体がメソッド・パラメーターとして resource.post メソッドに渡されている点です。この場合も、レスポンスはストリングとして返されます。

Atom クライアント・リクエスト

上で触れたように、Apache Wink クライアント・フレームワークは複数のコンテンツ・タイプでリクエストを発行することもできます。リスト 8 は Atom エントリーを送受信する HTTP POST リクエストを発行する例を示しています。

リスト 8. Atom リクエストの例
// create the rest client instance
RestClient client = new RestClient();

// create the resource instance to interact with
Resource resource = client.resource("http://services.co");
AtomEntry request = getAtomEntry();

// issue the request
AtomEntry response = resource.contentType("application/atom+xml").
			accept("application/atom+xml").
				post(AtomEntry.class, request);

Apache Wink クライアントには Atom のフィードやエントリーの送受信を行える Atom 用のオブジェクト・モデルが用意されているため、Atom リクエストの発行とレスポンスの解析は AtomEntry オブジェクトを使って簡単に行うことができます。


まとめ

この記事では、Apache Wink 1.0 フレームワークに関する高度な話題として、アノテーション、管理ビュー、WebDAV のサポートなどについて概要を説明しました。また Apache Wink が組み込みの拡張モジュールによってどのように Spring の統合をサポートしているかを学び、Apache Wink のクライアント・フレームワークと、そのベースにあるアーキテクチャーを詳細に調べました。この連載の第 3 回にご期待ください。第 3 回では JAX-RS 準拠の他のフレームワークと Apache Wink とを比較対照し、それぞれの相対的な強みと弱みについて説明します。REST、JAX-RS、Apache Wink 1.0 フレームワークについてさらに詳しく学ぶためには、この記事の「参考文献」を参照してください。

参考文献

学ぶために

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

  • Apache Wink: Apache Wink をダウンロードして、最新バージョンのソース・コードとバイナリー、そしてその他のサンプル・プロジェクトを入手してください。
  • Apache Tomcat Web Server バージョン 6.x: Tomcat をダウンロードしてください。
  • IBM Java JDK: IBM の JDK をダウンロードしてください。
  • 製品評価用 IBM 試用版ソフトウェア: developerWorks から直接ダウンロードできる試用版ソフトウェアで、次のプロジェクトを構築してください。DB2®、Lotus®、Rational®、Tivoli®、および WebSphere® によるアプリケーション開発ツールおよびミドルウェア製品の試用版が揃っています。

議論するために

コメント

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=Web development
ArticleID=480435
ArticleTitle=Apache Wink による RESTful な Web サービス: 第 2 回 Apache Wink REST 開発での高度なトピック
publish-date=03092010