目次


Ajax と Apache Geronimo による非同期メッセージ・フレームワークの作成

応答性の高いエンタープライズ・クラスの Web アプリケーション・フレームワークを作り上げる

Comments

フレームワークのコンポーネントの概要

サービス指向ビジネス層を適切に設計すれば、疎結合サービスからプロセスおよび複合アプリケーションを構成しやすくなります。このような構成をサービス指向アーキテクチャー (SOA) 内で行うと、それぞれの環境の詳細を知ることなく、異なる環境のサービスを用いてアプリケーションおよびプロセスを作成することが可能になります。SOA を使用することによってどれだけのメリットを受けられるかは、汎用の粒度の粗いインターフェースを使って設計および実装するサービスによって左右されます。

Ajax プログラミングは、ブラウザー・ベースの UI を開発する上で多くの機能と柔軟性を提供してくれます。この UI の機能をサービス指向ビジネス層と組み合わせれば、一層優れた柔軟性がもたらされます。Ajax プログラミングは元々、非同期のリクエストおよびレスポンスに大いに役立つものです。Ajax が持つこの非同期の性質を非同期をベースとするメッセージング・システムと組み合わせることで、デスクトップ・アプリケーションに一層近く、リアルタイム感覚の増したユーザー・エクスペリエンスを実現するブラウザー・ベースのアプリケーションの構築が可能になります。

Apache Geronimo は J2EE (Java™ 2 Platform, Enterprise Edition) 準拠のモジュール式アプリケーション・サーバー・プラットフォームで、IoC (Inversion of Control) アーキテクチャーをベースにコンポーネントとサービスを分離してエンタープライズ・クラスのアプリケーションおよびサービスを構築します。

この記事では、メッセージ・ベースのフレームワークまたはバスを使用してクライアントからの非同期ビジネス・リクエストを処理する、Ajax ベースの複数のクライアントと Geronimo ベースのサーバーとの対話動作について説明します。ブラウザーとサーバー間で Ajax ベースのクライアント・リクエストがどのようにやりとりされるか、そしてサーバー側ではメッセージ指向サービス・バスによってクライアント・リクエストが対象ビジネス・サービスにどのように渡されるかを学んでください。

Ajax の紹介

Ajax は、XML ベースのリクエスト/レスポンス・サーバー呼び出しモデルに従った UI 機能および概念のフレームワークです。これらの概念の多くは基本的に任意ですが、慣例では標準となっています。Ajax アプリケーション開発で標準として浮上してきたものの大部分は、主要な Web ブラウザーの機能による結果です。

Ajax UI が依存するのは、Web ページを任意の時点で解析および表示するために使用しているブラウザーの DOM (Document Object Model) 機能と JavaScript コンポーネントです。すべてではありませんが、これらの機能とコンポーネントの多くは主要な Web ブラウザーのほとんどで共通しています。このことによって思い通りにいかない可能性があるので、この記事では DOM および Ajax 指向の JavaScript コードが持つ最も基本的な機能だけを説明します。

Ajax をベースとするほとんどすべてのアプリケーションにとっての基本は、XMLHttpRequest オブジェクトとして知られるコンポーネントを作成することです。ブラウザーとサーバー間を行き来するリクエストは、この JavaScript オブジェクトを使用して作成および送信されます。リスト 1 のスニペットでは、Mozilla Firefox ブラウザーまたは Microsoft® Windows® Internet Explorer® ブラウザーとサーバーとの間で使用できる XMLHttpRequest オブジェクトのインスタンスを作成しています。

リスト 1. XMLHttpRequest オブジェクトの作成
function getHTTPObject()
{
   var xmlhttp = null;
   var success = false;
   
   // List of MS XMLHTTP versions - newest first
   var MSXML_XMLHTTP_PROGIDS = new Array(
       'MSXML2.XMLHTTP.5.0',
       'MSXML2.XMLHTTP.4.0',
       'MSXML2.XMLHTTP.3.0',
       'MSXML2.XMLHTTP',
       'Microsoft.XMLHTTP'
   );

   for (var i = 0; i < MSXML_XMLHTTP_PROGIDS.length && !success; i++)
   {
      try
      {
         xmlhttp = new ActiveXObject(MSXML_XMLHTTP_PROGIDS[i]);
         success = true;
         return xmlhttp;
      }
      catch (e)
      {
         xmlhttp = false;
      }
   }

   if (!xmlhttp && typeof XMLHttpRequest != 'undefined')
   {
      try
      {
         xmlhttp = new XMLHttpRequest();
      }
      catch (e)
      {
         xmlhttp = false;
      }
   }

   return xmlhttp;
}

XMLHttpRequest オブジェクトのインスタンスを作成したら、このインスタンスを使って、Java サーブレットなどの HTTP サーバー・コンポーネントとの間で HTTP リクエストの送受信を実行できます。リスト 2 は、XMLHttpRequest オブジェクトを使用して HTTP サーバー・コンポーネントに HTTP GET リクエストを送信するスニペットです。

リスト 2. XMLHttpRequest オブジェクトによる HTTP GET リクエストの送信
function callService(url)
{
  if (!isWorking)
  {
    httpObj.open("GET", url, true);
    try
    {
       httpObj.setRequestHeader("Content-type", "text/plain");
    }
    catch(e)
    {
       // setRequestHeader is missing in versions of Opera
    }
    isWorking = true;
    httpObj.onreadystatechange = handleServiceResponse;
    httpObj.send(null);
    return true;
  }
}

HTTP レスポンスは、XMLHttpRequest オブジェクトの onreadystatechange フィールド値として指定された JavaScript コールバック関数によって非同期で処理されます。リスト 2 では、このコールバック関数を handleServiceResponse と指定しています。リスト 3 のスニペットは、onreadystatechange コールバック関数の典型的な実装例です。

リスト 3. コールバック関数での XMLHttpRequestインスタンスのレスポンスの処理
function handleServiceResponse()
{
  if (httpObj.readyState == 4) // a value of 4 represents a request-completed state
  {
    isWorking = false;
    if (httpObj.status == 200)
    {
	   var contentType = httpObj.getResponseHeader("Content-type");
      var xmlDoc = httpObj.responseXML.documentElement;
      var textResponse = httpObj.responseText;
      // do something with either xmlDoc or textResponse or with both
    }
  }
}

これで Ajax ベースのブラウザー・ページで HTTP リクエストの送受信を行えるようになったので、次は HTTP リクエストを処理してレスポンスを送信するようにサーバー・コンポーネントを構成する番です。この例では、Apache Geronimo アプリケーション・サーバーにデプロイした Java サーブレットを使用します。

Apache Geronimo の紹介

Geronimo アプリケーション・サーバーは J2EE に完全に準拠したアプリケーション・プラットフォームで、エンタープライズ・クラスのアプリケーションおよびサービスを作成するために使用できます。モジュール式の Geronimo は極めて自在に構成でき、コンポーネントとサービスを効果的に分離する IoC 手法を使用したアーキテクチャーをベースとしています。さらに、JXM (Java Management Extensions) や同様の専有管理フレームワークの利点を備えた Geronimo は、監視、構成、管理がしやすいプラットフォームとなっています。

Apache Geronimo のダウンロードとインストール

「参考文献」セクションにリストしたサイトから Geronimo プラットフォームをダウンロードして、ディレクトリーにファイルを解凍してください。このディレクトリーは {GERONIMO_HOME} で参照することができます。次に、Geronimo システムの {GERONIMO_HOME}\bin\ ディレクトリーにある起動スクリプトを実行すると、図 1 のようなコンソール・ウィンドウが表示されます。

図 1. Geronimo の起動
Geronimo の起動
Geronimo の起動

起動コンソールには、Geronimo ランタイム環境を構成するためにロードおよび起動される多数のモジュール、コネクター、アプリケーションが表示されます。Geronimo ランタイムを停止する場合は、同じく Geronimo システムの {GERONIMO_HOME}\bin\ ディレクトリーにあるシャットダウン・スクリプトを使用してください。

非同期メッセージング

非同期メッセージング・システムが中心とする概念では、メッセージの受信側は特定のメッセージの送信元を認識あるいは意識しません。代わりに受信側は、受信側でタスクを実行するために必要なすべての情報をそれぞれの受信メッセージで受け取ることを前提とします。パブリッシュ/サブクスライブ関係とも呼ばれるメッセージの送信側と受信側のこのような分離は、非同期メッセージング・システムの最も有益な特徴の 1 つとなっています。

一般的に、非同期メッセージング・システムはメッセージ・バスまたはブローカーに依存して、メッセージ作成者がパブリッシュしたメッセージを受信するキューあるいはイベント・チャネルを公開します。この同じバスまたはブローカーが公開するサブスクリプション・インターフェースを使用して、対象となるメッセージの受信側またはイベントのコンシューマーは、特定タイプのメッセージまたはイベントに通知リスナーとして自らを登録します。

Ajax システム

この記事で説明する非同期メッセージ・ベースのフレームワークで使用するメッセージ・バスは、イベント・チャネルという手段によって Ajax から送られるメッセージをビジネス・サービスに送信します。イベント・チャネルは、ビジネス・サービスによって正常に処理されたイベントを対象リスナーに通知することもできます。

結合とは、ソフトウェア・コンポーネントやサービスが互いに依存し合っている程度を表す言葉です。サービスまたはコンポーネントのグループを定義する結合の程度によって、コンパイル時と実行時に必要なオブジェクトが決まります。疎結合されたコンポーネントは互いに独立して動作することが可能なため、それぞれ個別に開発してデプロイし、コンポーネント間の関係は実行時に指定することができます。これはよく、実行時バインディングまたは遅延バインディングと呼ばれます。

ビジネス・リクエストを非同期で処理するメッセージ・ベースのフレームワークあるいはバスを導入できるかどうかは、それぞれ個別の非同期メッセージが対象とするビジネス・ロジックを処理する疎結合ビジネス・サービスの有無によって決まります。

ビジネス・サービスをサービス・コンシューマーから分離するには、RPC (Remote Procedure Call) スタブおよびスケルトン、XSD (XML Schema Definition) スキーマ・ベース・シグニチャー、標準化インターフェースをはじめ、さまざまなメカニズムを使用できますが、この例では標準の粗粒度インターフェース、BusinessService を使用します。このインターフェースは、汎用メッセージ・データをパラメーターとして 1 つの実行メソッドを定義します。

強い型付きオブジェクトの代わりに汎用データを受け入れるメソッド・シグニチャーが目標とするのは、呼び出し側と対象オブジェクトの疎結合を確実にすることです。強い型付きオブジェクトをパラメーターとして使用してデータとコードを組み合わせた場合、特定の振る舞いを暗黙的に示すことになります。振る舞いがコンポーネントまたはサービスの境界を越えれば、容易に密結合という形が現れてきます。その一方、汎用メッセージ・データを渡せば暗黙的に示される振る舞いもないため、密結合という形にはなりません。

リスト 4 のコード・スニペットに、BusinessService インターフェースを示します。

リスト 4. 標準化したビジネス・サービス・インターフェース
public interface BusinessService
   extends Serializable
{
   public void setID(String id);

   public String getID();

   public Object execute(String methodName, Object[] params)
      throws ServiceException;
}

クライアントとサーバー間でのメッセージ・フロー

この例の UI は、Ajax に対応した 1 つの単純な JSP (JavaServer Pages) コンポーネントで構成されています。この JSP が定義するのは、前述した XMLHttpRequest オブジェクトを使ってサーバーにサービス・リクエストを渡す 1 つのフォームです (リスト 5 を参照)。

リスト 5. Ajax 対応の HTML フォーム
<form name="ServiceRequestForm" method="POST" onSubmit="return false">
  <table>
     <tr>
       <th>
         Raw Ajax XML
       </th>
       <th>
         User Names
       </th>
     </tr>
     
     <tr>
       <td>
         <textarea name="result" id="result" COLS="40" ROWS="8"></textarea>
       </td>
       <td>
         <textarea name="users" id="users" COLS="20" ROWS="8"></textarea>
       </td>
     </tr>
     
     <tr>
       <td colspan="2">
         <input name="submit" id="submit" type="submit" value="Get User Names"
                onclick="callService('services?ServiceName=UserAccountService&'
                                     + 'MethodName=getUserNames&ServiceParams=');">
         <input name="reset" id="reset" type="reset"
                onclick="resetFields();">
       </td>
     </tr>
  </table>
</form>

フォームで開始されたリクエストは callService JavaScript 関数で実行され、この関数が XMLHttpRequest オブジェクトを使って HTTP 通信を処理します。サーブレットで受信されたメッセージは非同期メッセージに変換され、Java コンポーネントのフレームワークによってルーティングされます。この非同期メッセージが、最終的にビジネス・サービス・リクエストおよび XML ベースのサービス・レスポンスとなります。

図 2 に、Ajax システムでの場合のメッセージとメソッド呼び出しのフローを示します。

図 2. 非同期システムのフロー
非同期システムのフロー
非同期システムのフロー

以下に、図 2 に示したプロセスを説明します。

  1. FrontController サーブレットが Web 層でメッセージを受信します。
  2. FrontController サーブレットがリクエスト・プロセッサーを使用して、それぞれの HTTP リクエストを正規非同期メッセージに変換します。
  3. 各メッセージが、非同期コールバック・リスナーとともにビジネス層に常駐するメッセージ・バスにパブリッシュされます。
  4. メッセージ・バスがイベント・オブジェクトを作成し、ビジネス・サービスのインスタンスと併せてイベント・チャネルにディスパッチします。
  5. イベント・チャネルは該当するビジネス・サービスを呼び出し、イベント・チャネルをサブスクライブしているすべてのリスナーにイベントが正常に完了したこと、あるいは失敗したことを通知します。

層とコンポーネントの間でのデータの受け渡しは、モデル・オブジェクトという形で行われます。モデル・オブジェクトは必要に応じて XML にシリアライズすることができます (FrontController サーブレットが XML ベースの Ajax クライアントにレスポンスを送信するときなど)。

このシステムで重要となる概念は、特定の操作の失敗または成功を、その処理を行うコンポーネントにコールバック・オブジェクトで中継するということです。最終的には、この失敗または成功の状態が Ajax クライアントに送信されてユーザーに表示されます。このようにコールバック・オブジェクトと非同期通知に依存するということは、通常のリクエストまたはレスポンス Web アプリケーションにはない問題を生じさせます。つまりユーザーの注意力が続く時間と HTTP タイムアウトという制限を念頭に置くと、クライアントには迅速にレスポンスを返さなければならいという難題です。この問題に対処するために通常採られている方法は、ビジネス層にタイムアウトを導入し、プロセスが妥当な時間枠を超えてブロックしないようにすることです。有効なタイムアウト制限を課すために使用できるメカニズムは、いくつか挙げるだけでも Java Timer オブジェクト、子スレッド、begin-wait-abort ループ、メッセージ・キュー・タイムアウトとさまざまですが、この例のシステムでは単純な begin-wait-abort ループを使用します。

非同期メッセージング・システムと Apache Geronimo の統合

Geronimo では非同期メッセージング・システムを簡単にデプロイすることができます。まずシステムを WAR ファイルとしてパッケージ化し、このパッケージを Geronimo プラットフォームで配布される Deployer ツールを使って Geronimo にデプロイするという方法です。Deployer ツールは、{GERONIMO_HOME}\bin\ に配置された deployer.jar にあります ({GERONIMO_HOME} は、お使いの Geronimo システムのディレクトリーです)。

WAR ファイルを作成する

リスト 6 のコマンドを実行してシステム・クラスをコンパイルしてください。これによって、WAR ファイルが作成されます。

リスト 6. WAR ファイルの作成
{YOUR_PROJECT_DIR}{MAVEN_HOME}\bin\mvn clean compile war:war

WAR ファイルをデプロイする

WAR ファイルを Geronimo アプリケーション・サーバーにデプロイするには、リスト 7 のコマンドを実行します。

リスト 7. .war ファイルのデプロイメント
{YOUR_PROJECT_DIR}{JAVA_HOME}\bin\java -jar {GERONIMO_HOME}\bin\deployer.jar deploy \
target/GeronimoAndAJAX-1.1.war

上記のコマンドを実行すると、リスト 8 のような結果が表示されます。

リスト 8. WAR ファイルのデプロイメント結果
Username: system
Password: *******
    Deployed default/GeronimoAndAJAX-1.1/1169329928406/war @
    http://localhost:8080/GeronimoAndAJAX-1.1

非同期メッセージング・システムの実行

非同期メッセージング・システムの Ajax に対応した開始ページからサーバーにメッセージを送信するには、Web ブラウザーで http://localhost:8080/GeronimoAndAJAX-1.1 を指定します。すると、図 3 のような開始ページが表示されます。

図 3. 非同期システムの開始ページ
非同期システムの開始ページ
非同期システムの開始ページ

開始ページが表示されたら、Submit Query をクリックして非同期サービス呼び出しを実行します。この操作によって、ブラウザー・ウィンドウに図 4 のようなページが表示されるはずです。

図 4. 非同期システムの結果ページ
非同期システムの結果ページ
非同期システムの結果ページ

上記のように、左の列にはサーバーから受信したとおりの XML が表示され、右の列には結果を表すフォーマット化されたリストが表示されます。

まとめ

Ajax プログラミングは Web アプリケーション開発者に従来の Web 開発方法よりも一層優れた機能と柔軟性を与えていますが、この威力を疎結合されたサービス指向ビジネス層と組み合わせることで、柔軟性と機能をさらに強化することができます。 Ajaxは非同期のリクエスト・レスポンス環境で動作するように設計されているので、 この非同期の性質を非同期ベースのメッセージング・システムと組み合わせれば、さらに優れたリアルタイムのデスクトップ・アプリケーション感覚をユーザーに提供することができるというわけです。

この記事では Apache Geronimo の 1 つの利用方法として、Ajax UI が持つ非同期の性質を、疎結合ビジネス・サービスを使用する非同期メッセージング・システムに組み合わせたシステムの構築方法を説明しました。Ajax ベースのクライアントとメッセージ・ベースのフレームワークまたはバスとの対話動作を追跡し、メッセージ・ベースのフレームワークまたはバスが Ajax クライアントで開始された非同期ビジネス・リクエストをビジネス・サービスに送り出すまでの過程を理解していただけたはずです。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Open source, Web development, WebSphere
ArticleID=243395
ArticleTitle=Ajax と Apache Geronimo による非同期メッセージ・フレームワークの作成
publish-date=06192007