IBM®
本文へジャンプ
    Japan [変更]    ご利用条件
 
 
検索範囲検索:    
    ホーム    製品    サービス & ソリューション    サポート & ダウンロード    マイアカウント    
skip to main content

developerWorks Japan  >  SOA and Web services  >

Crispy による Web サービス: 第 1 回: 入門

developerWorks
ページオプション

JavaScript を要するドキュメントオプションは表示されません

原文はこちら

原文はこちら


レベル: 中級

Sachin Mahajan, Software Development, IBM

2009年 5月 07日

この記事では Crispy について説明します。Crispy の目標は、多種多様なトランスポート (RMI、EJB、JAX-RPC、XML-RPC など) に対するリモート呼び出しの単一エントリー・ポイントを提供することです。Crispy では、プロパティーを使用することでサービス・マネージャーを構成し、このサービス・マネージャーを使ってリモートの API を呼び出します。

はじめに

Crispy は、Communication per Remote Invocation for different kinds of Services via ProxYs (プロキシーを介して多種多様なサービスを呼び出すための、リモート呼び出しによる通信) を表します。Crispy はリモート呼び出しのためのフレームワークであり、多種多様なトランスポート・プロトコル (RMI、EJB、JAX-RPC、XML-RPC など) をサポートしています。簡単に言えば、Crispy を使うためには、サービス・マネージャーを (プロパティー・ファイルを使って) 構成し、サポートされているリモート API を呼び出せばよいだけです。

まず、Crispy を構成するためのコード・サンプルを見てみましょう (リスト 1)。


リスト 1. Crispy を構成するためのコード・サンプル

Properties prop = new Properties();
prop.put(Property.REMOTE_URL_AND_PORT, serviceUrl);
prop.put(Property.EXECUTOR_CLASS, typeOfExecutor);

ServiceManager manager = new ServiceManager(prop);
LibraryService library =  (LibraryService) manager.createService(LibraryService.class);
String author = library.findAuthor(myBook);
String isbn = library.findISBN(myBook);
…
			

上記のコードでは、properties オブジェクトを作成し、リモート URL と実行クラスのタイプを設定しています。実行クラスのタイプには、JAX RPC、JBoss Remoting、RMI executor、XML RPC、REST、http executor などがあります。プロパティーを構成したら、Crispy の ServiceManager のインスタンスを作成します。これで、この ServiceManager (Factory パターン) を使ってリモート・サービス・オブジェクト (この場合は OrderService) を作成することができます。




上に戻る


背景

Crispy について簡単に説明したので、今度は典型的なリモート呼び出しを Crispy を使わずに行う場合の例を見てみましょう。


リスト 2. Web サービス (JAX-RPC)

public static final String LIBRARY_SERVICE_ENDPOINT = 
"http://myservicehost:9080/axis/services/LibraryService";
Service service = (Service) ServiceFactory.newInstance().createService(null);
Call call = service.createCall();
call.setTargetEndpointAddress("LIBRARY_SERVICE_ENDPOINT ");
call.setOperationName(new QName("findAuthor"));
QName paramXmlType = new QName(String.class.getName());
call.addParameter("arg0", paramXmlType, String.class, ParameterMode.IN);
call.setReturnType(new QName(String.class.getName()));
String result = (String) call.invoke(new String[] {”Alice in Wonderland”});
System.out.println("Author of Alice in Wonderland: " + result);
			

Web サービスを呼び出すために call オブジェクトが使われています。これを手動で設定することもでき、あるいは WSDL 文書を使うこともできます。ここでは、この call オブジェクトのオペレーション、パラメーター、戻り型を設定し、Web サービスを呼び出して、必要な結果を取得しています。


リスト 3. XML-RPC (Apache XML-RPC)

XmlRpcClient client = new XmlRpcClient("http://myservicehost:9090");
Vector param = new Vector();
param.add(”Alice in Wonderland”);
String result = (String)
client.execute("crispysample.LibraryService.findAuthor", param);
System.out.println("Author of Alice in Wonderland: " + result);	
…
			

XML-RPC クライアントにとって、メインとなるアクセス・ポイントは XmlRpcClient です。execute メソッドと、param として渡されるパラメーターを使って、「calculateTip」というメソッドでリクエストが実行されます。




上に戻る


Crispy の登場

上記のコードは、リモート呼び出しを行う方法のうち、JAX-RPC による方法と XML-RPC による方法という 2 つの例を示したにすぎません。他にも、RMI、EJB、REST、http などを使ってリモート呼び出しを行うことができます。Crispy では、構成された ServiceManager を使うことによって、そうしたさまざまなリモート呼び出しをまとめて扱うことができます。ServiceManager を構成するためには Properties オブジェクトを使います。


リスト 4. JAX-RPC の場合

MiniAxisServer server = new MiniAxisServer();
try {
	server.addService(LibraryService.class.getName(), 
    LibraryServiceImpl.class.getName());
	server.start();	
Properties properties = new Properties();
properties.put(Property.REMOTE_URL_AND_PORT, "LIBRARY_SERVICE_ENDPOINT");
properties.put(Property.EXECUTOR_CLASS, JaxRpcExecutor.class.getName());
} catch (Exception e) {
	e.printStackTrace();
}
finally {
	server.stop();
}
…
			


リスト 5. XML-RPC の場合

MiniXmlRpcServer server = new MiniXmlRpcServer();
try {

server.addService(LibraryService.class.getName(), LibraryServiceImpl.class.getName());
	server.start();
Properties properties = new Properties();
properties.put(Property.REMOTE_URL_AND_PORT, " http://myservicehost:9090");
properties.put(Property.EXECUTOR_CLASS, XmlRpcExecutor.class.getName());
} catch (Exception e) {
	e.printStackTrace();
}
finally {
	server.stop();
}
…

			

ServiceManager が構成できると、ServiceManager をインスタンス化することができ、またリモート・メソッドを呼び出すことができます。下記はその一例です。


リスト 6. ServiceManager の例

ServiceManager manager = new ServiceManager(properties);
Library library =  (LibraryService) manager.createService(LibraryService.class);
System.out.println("Author of Alice in Wonderland: " + result);
			

上記のコードから、Crispy を使うとリモート呼び出しが非常に容易になることがわかります。サービス・マネージャーを構成すると非常に便利で、リモート呼び出しとローカル呼び出しが同じように扱えるようになります。しかも、クライアントは呼び出し対象のリモート技術について詳しく知る必要がありません。




上に戻る


Crispy の実際

Crispy の内部動作

Crispy フレームワークは、クライアント (サービス・コンシューマー)、内部サービス・プロバイダー、そして外部サービス・プロバイダー、という 3 つのコンポーネントで構成されています。この 3 つのコンポーネントにはすべて通信ライブラリーが必要ですが、サーバー・コンポーネントのみにサービスの実装が必要になります。またクライアントにはサービス・インターフェースが必要です。


図 1. Crispy (クライアントとサーバー) のコンポーネント (Crispy のドキュメントより引用)

下記の図 2 は、クライアント・コンポーネントとサーバー・コンポーネントの間の通信の様子を示しています。この図からわかるように、これはクライアントとサーバーとの間の典型的な通信です。メモリー上に表現された (パラメーターや結果などを含む) データは、サーバーへの送信に適したフォーマットに変換されます。これはマーシャリングと呼ばれます。逆の変換はサーバー上でメソッドの実行前に行われ、アンマーシャリングと呼ばれます。


図 2. Crispy のコンポーネント間での通信 (Crispy のドキュメントより引用)

クライアント・サイドでは、ServiceManager オブジェクトが動的または静的なプロキシーを作成してサーバーと通信し、プロキシー・オブジェクトのメソッドを呼び出します。サーバーへの呼び出しをマーシャリングする前に、パラメーターを変換するための、オプションとしての呼び出しが行われます。図 3 に示すように、このプロセスは net.sf.crispy.util.Converter.makeSimple を使って行われます。サーバーがリクエストを受信すると、アンマーシャリングが行われ、サーバーは変換されたオブジェクトを net.sf.crispy.util.Converter.makeComplex を使って返送します。


図 3. Crispy でのオブジェクトの変換 (Crispy のドキュメントより引用)

先ほど触れたように、これはオプションのステップであり、オブジェクトを転送するために java.io.Serializable インターフェースを実装したくない場合には、このステップを呼び出すことができます。上記の図で示したように、複雑な Java オブジェクトは Java の HashTable (java.util.HashTable) オブジェクトに変換されます。この場合のキーは Java オブジェクトの属性名であり、値はその属性の値です。関係は Java の Vector オブジェクト (java.util.Vector) を使ってマッピングされます。




上に戻る


Crispy を同期型または非同期型で実行する

このフレームワークでは同期型または非同期型で実行するために、主にクライアントがそれに対応する呼び出しを行います。テストは、等価なサーバーが既に起動しているという前提で、MiniServer オブジェクト (net.sf.crispy.impl.MiniServer) を使って行います。下記は実行のタイプ (同期型または非同期型) を設定する方法の一例です。


リスト 7. MiniServer オブジェクト

MiniRmiServer server = new MiniRmiServer();
try {
		server.addService(LibraryServiceImpl.LOOKUP_NAME, 
        LibraryServiceImpl.class.getName());
	server.start();	
Properties properties = new Properties();
properties.put(Property.REMOTE_URL_AND_PORT, "rmi://localhost:1098");
prop.put(Property.DYNAMIC_PROXY_CLASS, Property.VALUE_FOR_CGLIB_DYNAMIC_PROXY);
properties.put(Property.EXECUTOR_CLASS, RmiExecutor.class.getName());
//Register the interface implementation mapping
prop.put(LibraryService.class.getName(), LibraryServiceImpl.class.getName());
ServiceManager manager = new ServiceManager(prop);
LibraryService library = manager.createService(LibraryService.class);
System.out.println("Author of Alice in Wonderland: " + 
        library.findAuthor(“Alice in Wonderland”));
} catch (Exception e) {
	e.printStackTrace();
}
finally {
		server.stop();
}
...
			

上記の例では、デフォルトでは同期型で実行されます。一方、非同期型で実行するためには、ServiceManager オブジェクトによって AsynchronousCallback オブジェクト (net.sf.crispy.concurrent.AsynchronousCallback) の実装を登録する必要があります。この例では、登録されたコールバックと、非同期に実行するためのメソッド名、そして実行スレッドの最大数を使って LibraryService オブジェクトが作成されています。


リスト 8. LibraryService オブジェクト

Properties properties = new Properties();
properties.put(Property.REMOTE_URL_AND_PORT, "rmi://localhost:1098");
prop.put(Property.DYNAMIC_PROXY_CLASS, Property.VALUE_FOR_CGLIB_DYNAMIC_PROXY);
properties.put(Property.EXECUTOR_CLASS, RmiExecutor.class.getName());
//Register the interface implementation mapping
prop.put(LibraryService.class.getName(), LibraryServiceImpl.class.getName());
AsynchronousCallback callback = new AsynchronousCallbackForTests();
ServiceManager manager = new ServiceManager(prop);
 LibraryService library = manager.createService
(LibraryService.class,callback,new String[]{“findAuthor”},INT_MAX_NO_THREADS);
...
			




上に戻る


謝辞

多忙なスケジュールの中でこの記事を校閲してくださり、また専門家としてのコメントをくださった、Crispy フレームワークの作成者である Mario Linke 氏に深く感謝いたします。




上に戻る


まとめ

この記事では、Crispy の内部動作について、さらにリモート呼び出しを行う上での Crispy の便利さと使いやすさについて説明しました。また JAX-RPC と XML-RPC を使ってリモート呼び出しを行う方法と、同期型で実行する場合と非同期型で実行する場合の両方について、Crispy を利用するための詳細をいくらかも説明しました。この記事は Crispy について説明する 2 回シリーズの記事の第 1 回です。次回の記事では、Crispy を使う RESTful アプリケーションの例について、また他のフレームワークを使って Crispy を拡張する方法について説明する予定です。



参考文献

  • Crispy Sourceforge の Web サイトで Crispy についての資料を読んでください。

  • SOA での Crispy の重要さを知るために、new to SOA を調べてみてください。SOA の紹介記事や、IT やビジネスにとっての SOA の重要性を理解するための記事が豊富に用意されています。

  • JAX-RPC に関するヒントを紹介した記事として、「Web サービスのヒント: JAX-RPC と JAX-WS」を読んでください。

  • XML-RPC を使った Web サービスを紹介した記事として、「PerlでXML-RPCを始めよう 第2回:XML-RPC Middleware」を読んでください。


著者について

Sachin Mahajan

Sachin Mahajan は技術的な業務や監督者としての業務を含め、ソフトウェア開発に 9 年を超える経験があります。現在は IBM が提供する SaaS である LotusLive の開発チームで業務を行っています。




記事の評価


サイト改善のため、ご意見をお寄せください。こちらのフォームからお願いいたします。



 


 


不充分・不完全である大変素晴らしい
 


この記事を共有する

del.icio.us del.icio.us newsing newsing FC2ブックマーク FC2ブックマーク
Choix! Choix! ニフティクリップ ニフティクリップ Yahoo!ブックマーク Yahoo!ブックマーク
MM/memo MM/memo CZブックマーク CZブックマーク livedoorクリップ livedoorクリップ
はてなブックマーク はてなブックマーク Buzzurl(バザール) Buzzurl(バザール)




上に戻る


    日本IBMについて プライバシー お問い合わせ