目次


Ajaxを使用したLotus Notes文書の操作

Comments

タスク・リストは、誰もが使用したことのあるシステムです。一般的に、このようなシステムは小さなデータの集まりで構成され、素早く簡単に使用できる必要があります。タスク・リストは、Lotus DominoでのAsynchronous JavaScript and XML(Ajax)テクノロジーの使い方を示すのに最適なサンプルです。この記事では、Ajax設計パターンを使用して「タスク・リスト」と呼ばれるLotus Notesアプリケーションを構築する方法を説明します。このアプリケーションは、迅速なフィードバックとタスクの更新をユーザーに提供します。

この記事では、[タスク・リスト]アプリケーションの作成を通じて説明を進めますが、参考のために、完成したサンプル・アプリケーションもダウンロードできるようになっています。このアプリケーションでは、Webブラウザーから送信されたAjax要求(たとえば、Lotus Notes文書の作成と更新)を処理するLotus Dominoエージェントと、アプリケーションで使用されるXMLを生成するLotus Dominoビューを使用します。この記事は、Lotus Notes/Dominoアプリケーションの開発に習熟し、JavaScriptとXMLの知識を持っている方を対象に書かれています。

Ajaxの詳細については、この記事の「リソース」セクションに記載されている入門用の記事を参照してください。

[タスク・リスト]アプリケーションは、タスク項目のレコードを保持しています。各タスク項目には、SubjectとStatusという2つのフィールドがあります。Subjectフィールドには、各項目の内容を示す情報が格納され(図1参照)、Statusフィールドには、未処理のアクションを示す0、または完了済みのアクションを示す1が格納されます。

図1. Ajaxドリブンの[タスク・リスト]アプリケーション
図1. Ajaxドリブンの[タスク・リスト]アプリケーション
図1. Ajaxドリブンの[タスク・リスト]アプリケーション

Ajaxドリブン・アプリケーションの長所

Ajaxドリブン・アプリケーションはWebベース・アプリケーションのユーザビリティーを高め、Lotus Domino Serverは、付加されたセキュリティーとカテゴリー化されたビューにより、リッチ・クライアント・アプリケーションに適したリポジトリーを提供します。

Lotus Dominoが提供する設計要素により、Lotus DominoプラットフォームでのAjaxソリューションの開発が簡素化されます。Ajaxポストを処理するセッション対応(セキュリティーとパーソナライゼーションのため)のLotus Dominoエージェントは、容易に構築できます。また、HTML、XML、およびJavaScript Serialized Object Notation (JSON)を提供するようLotus Dominoビューを設定できます。Ajax実装を成功させるために必要なものは、すべて揃っています。

最新のWebブラウザーと成熟したDocument Object Model(DOM)により、ユーザー用のリッチ・クライアント・アプリケーションの作成がさらに簡単になりました。たとえば、入力補完フィールドをプロジェクトに含めると、入力時に候補がユーザーに表示され、名前の検索が容易になります。また、別のプロジェクトでは、小さなボックス(つまり<DIV>)を含むポータル・ページをロードしました。この方法では、各<DIV>はAjax呼び出しによってバックエンドで作成されます。そして、一部のボックスは30秒ごとに更新され、Enterprise Resource Planning(ERP)システムからの最新情報が管理者に提供されます。

3番目の例として、各ボックスの見出しに小さな[マイ・ページに追加]アイコンを持つポータル・プロジェクトが挙げられます。ユーザーがこのアイコンをクリックすると、どのボックスの購読を希望するかを示す情報を持った要求がバックグラウンドでサーバーに渡されます。サーバーは、「The box is now on your personal page」(ボックスが個人のページに追加されました)または「You have that box already!」(このボックスはすでに追加されています)のいずれかのメッセージで応答します。

これらのすべてのアプリケーションでは、APIを指定することから開始する必要がありました。APIの指定が不適切だと、どのようなプロジェクトでも失敗する恐れがあります。

API

[タスク・リスト]アプリケーションのコーディングを始める前に、クライアントとサーバー間で送信される情報の形式を決定する必要があります。システム・アーキテクトはどのような交換形式をも選択できますが、最近はXML、JSON、またはシンプル・テキストを選択することが一般的です。

XML、JSON、または単純な引数

コミュニケーションを行う2つのコンピューターにとって、送信側と受信側がそれぞれの情報ごとに何をすればよいのかを認識するために、適切に定義されたルールを設定する必要があります。これらのルールは、複雑かつ詳細で柔軟性を高くすることも、単純かつ簡潔で採用しやすくすることもできます。 形式の選択が自由にできる場合は、小ささおよびオーバーヘッドよりも、可読性と保全性を優先することをお勧めします。選択できる形式は次のとおりです(表1にまとめられています)。

  • XML: XML形式は、構造化と適切な定義が行われているデータに最適です。サーバーとクライアントの双方がデータをどのように表示するのかを完全に認識している場合に使用します。しかし、XMLはやや冗長で、古いブラウザーのXML実装にはいくつかの難点があります。しかし、この難点は、この記事で取り上げる最新のAjaxドリブン・アプリケーションの例には影響しません。
  • HTML: HTMLは、サーバーからWebブラウザーにデータを送信して直接レンダリングする場合に最適です。特に、XMLと比較すると、レンダリングの前にクライアントでのHTML変換が必要な場合に適しています。ブラウザーが分析し、データに応答しなければならない場合、HTMLはお勧めできません。
  • JSON: JSONは可読性があり、サイズも小さくてあまりオーバーヘッドをともないません。JSONはJavaScript言語に対しネイティブですが、Javaサーバー・サイドで追加のコーディングが必要です。
  • CSV: コンマ区切り値(CSV)は、2つのシステム間でのデータ交換として、おそらく最も使用されている実証済みの方法です。可読性があるという意見もありますが、これには同意できません。保全性のチェックはありませんが、オーバーヘッドもありません。
  • テキスト: 情報交換に純粋なテキストを用いることは、URLなどの値の組み合わせに適しています。
表1. 情報交換における形式の違いのまとめ
XMLJSONHTMLCSVテキスト
オーバーヘッド高い中程度高い非常に低い中程度
保全性のチェック最良非常に低いなしなしなし
可読性良い中程度良い不可能良い

この記事のサンプルでは、バックエンド・システムへの要求にはテキスト形式を使用し、その応答にはXMLを使用します。XMLの定義には、もう少し時間と労力を費やす必要があります。これは、純粋なLotus Notes環境でフィールドを追加するほど簡単ではありません。

XML形式の定義

クライアントがサーバーに送信できるメソッドの定義については、後述します。ここでは、1つ以上のタスク項目を定義するために、どのXMLダイアレクトを使用するのかを決める必要があります。[タスク・リスト]アプリケーションの各タスク項目には、キー(key)、件名(subject)、およびステータス(status)の3つの値があります。キーは、タスク項目を含むLotus Notes文書のUniversal ID(UID)です。件名は、ユーザーが実行したいタスクまたはアクションです。ステータスは、未処理のタスクの場合は0、完了済みのタスクの場合は1になります。

このサンプルでは、サーバーは更新された項目リストを用いてすべての呼び出しに応答します。実際の状況では、応答はサーバーが実行したアクションにより密接に関連しています。このサンプルでの次の手順は、更新された項目リストを送り返すだけではなく、以下のコード・リストに示すように、サーバーの実行内容をクライアントに通知するステータス情報を提供します。

<response>
<response status></response status>
<document>
<key></key>
<subject></subject>
<status></status>
</document>
<document>
<key></key>
<subject></subject>
<status></status>
</document>
</response>

これで、API、交換形式、XML標準を設定できたので、サーバー・サイドの機能の開発を始められます。その後で、クライアント・サイドのコードに注目します。しかし、これらの作業の前に、サーバーが文書に対してどのようなアクションを実行するのかを決定する必要があります。

クライアントからサーバーへの呼び出しの作成

クライアントで生成される各呼び出しには、サーバーに実行内容を伝えるために、アクション引数を含める必要があります。また、たとえば、項目のステータスを変更する場合など、追加の引数を送信しなければならないケースもあります。このような場合、アクションはToggleStatusであり、Lotus Domino Serverが正しい文書に正しいアクションを実行するために、どの文書のステータスを変更するのかを示す情報を追加引数に含める必要があります。

クライアントからのすべての呼び出しは、HTTP GETメソッドといくつかのURL引数を使用して行われます。methodとkeyという引数を含む完全なURLの例を以下に示します。

http://host/ibm/ajaxdemo.nsf/AjaxHandler?
open&method=deleteDocument&key=88877766fefe5678

サーバーはどのアクションを処理すべきか?

WebページはAPI用に、createDocument、updateDocument、deleteDocument、getDocument、toggleStatusなど、多数の異なるメソッドを使用します。各メソッドは1つ以上の引数を受け取ります。作成、更新、削除、およびステータスの切り替えの各アクションはデータベース内の情報を変更するため、これらの変更をWebページ上のタスク項目リストに反映する必要があります。この変更を反映する1つの方法として、データベース内でクライアントによる変更が行われるたびに、クライアントが追加要求を実行し、項目リストを取得します。さらに良い方法としては、エージェントが呼び出されるたびに、更新されたタスク・リストを返すエージェントをセットアップします(詳細については、後述します)。

サーバーは、表2に示す定義済みアクションに対して応答しなければなりません。

表2. 定義済みアクション
メソッド目的引数戻り値
CreateDocument新規の Lotus Notes 文書を作成し、指定されたデータを用いてフィールドを生成します。フィールドのリスト。各フィールド引数には、フィールド名、型、値が含まれます。すべての項目を含むXMLオブジェクト。
UpdateDocument文書識別子、フィールド名、および変更する値を指定して、更新を要求します。文書の固有IDとフィールド引数。フィールド引数には、フィールド名と新しいフィールド値が含まれます。すべての項目を含むXMLオブジェクト。
DeleteDocument文書を削除します。削除する文書の固有ID。すべての項目を含むXMLオブジェクト。
GetDocument文書のコンテンツを返します。取得する文書の固有ID。要求された項目を含むXMLオブジェクト。
ToggleStatus特定の[タスク]項目のステータスを切り替えます。ステータスを変更する文書の固有ID。すべての項目を含むXMLオブジェクト。

上記の5つのアクションを使用すると、Lotus Domino ServerとWebブラウザー間の完全なAPIを作成できます。それでは、サーバー・サイド・エージェントのコードに移りましょう。

サーバー・サイド

Lotus Domino Serverは、すべてのAjax要求が適切に処理されるように機能します。データを操作する呼び出しに対しては、サーバー・サイドでの知的な処理、つまりこの例ではエージェントによって応答する必要があります。単に情報を要求する呼び出しは、Lotus Notesビューを利用するとよいでしょう。Lotus Notesビューは、優れたXMLソースでもあります。

リスト用のビュー

この例では、XMLを表示するよう設定されたLotus Notesビューを使用します。Lotus Dominoが生成するHTMLコードが追加されるのを防ぐために、ビューがその内容をHTMLとして表すように設定します。

[タスク・リスト]アプリケーションでは、このビューに列が1つだけ必要です。この列では、システム内の各タスク項目に対する完全なXMLノードを生成します。件名のリストを表示する最初の列は、非表示にして、ソート用のルールを設定するためにのみ使用します(図2参照)。

図2. Lotus Domino Designerで表示したXMLビュー
図2. Lotus Domino Designerで表示したXMLビュー
図2. Lotus Domino Designerで表示したXMLビュー

このビューに加え、ビューに対応する$$viewtemplateフォームも必要です。このフォームには、図3に示すXMLラッピング・コードを含めます。

図3. $$viewtemplateフォームの一部
図3. $$viewtemplateフォームの一部

既存の情報を表示することは重要であり、図3に示したソリューションはニーズに完全に一致しています。それでは、要求に応答するLotus Notesエージェントを作成しましょう。

バックエンド・コマンド用のLotus Dominoエージェント

Ajaxパターンに適した方法でLotus Dominoバックエンド・システムからデータを取得する方法は知っているものとして、Lotus Dominoエージェントをどのように使用して、Ajax呼び出しを受信するのでしょうか。

最初に、HTTP GETメソッドまたはPOSTメソッドのどちらを用いてエージェントを呼び出すべきか決める必要があります。タスク項目に含まれる情報は非常に少ないので、GETメソッドを使用できます。これは、サーバーへのすべての引数が、URL文字列に含められて送信されることを意味します。例を示します。

/database.nsf/ajaxHandlerAgent?
openagent&method=UpdateDocument&key=FFF&status=0

エージェントはURL文字列内の引数を解析し、method引数の値に基づいて応答します。次のコードのリストは、method引数に基づいて、ajaxHandlerAgentが必要なアクションを実行する方法を示します。

UrlArguments args = new UrlArguments(); (1)
args.fromSession(session);
				

String method = args.getString("method");

if("ToggleStatus".equals(method)) {
  try {
    Document doc = thisDB.getDocumentByUNID(args.getString("key")); (2)
    String newStatus="1";
    if(doc.hasItem("status")) {
      String currStatus = doc.getItemValueString("status");
      if("1".equals(currStatus)) {
        newStatus=="0";}
    }
    doc.replaceItemValue("status",newStatus);
    pw.println("[" + "/" + thisDB.getFilePath() + "/XmlView?open]");
    doc.save(true,false);
  } catch(Exception e) {
    pw.println(e);(3)
  }
}

メモ: 上記のエージェント・コードは、ToggleStatusアクションだけを示しています。このエージェントとクライアント用のすべてのコードは、「ダウンロード」セクションからダウンロードできます。
このコードでは、次の点に特に注意してください。 (1): UrlArgumentsクラスは、URL引数を解析し、hashtableオブジェクトに読み込む小さなユーティリティー・クラスです。 (2): この行では、各Lotus Notes文書のuniversalID引数が使用されます。(3): この行のエラー処理は実稼働環境では不十分で、必要に応じて改訂する必要があります。
ビュー内のデータをクライアントに戻すために、エージェントがリダイレクトを実行していることに気付いたでしょうか。

Lotus Dominoエージェントからのビューの提供

Ajaxを使用する大きな利点は、リアルタイムの情報を瞬時にサーバーから提供できることです。このため、[タスク・リスト]アプリケーションでは、すべてのサーバー要求に対する応答として、最新の項目リストをユーザーに送り返します。これを行うには、次に示すコードのように、XMLビューへのサーバー・サイドでのリダイレクトをエージェントに実行させます。これにより、Webブラウザーは、エージェントへのすべての呼び出しの応答として、XMLビューのコンテンツを取得します。

pw.println("[" + "/" + thisDB.getFilePath() + "/XmlView?open]");

クライアント・サイド

ブラウザーでは、Ajax要求を作成する関数、応答情報用のプレースホルダー、およびユーザーの対話を可能にする1つ以上のホット・スポットが必要です。イベントを発生するオブジェクトであれば、任意のオブジェクトを対話ポイントして使用できます。最もよく知られているタイプは、入力ボタンとアンカー・リンクです(図4参照)。ユーザーがカテゴリー化されたビューに慣れている場合は、何を対話ポイントにすればよいかを簡単に決められます。Ajaxによって、さらに効率の高い実装が可能になります。つまり、ユーザーがビューを開いたときに1つのカテゴリーだけをロードすると、オーバーヘッドを削減できるだけでなく、ユーザーにとっても利点があります。

図4. [タスク・リスト]アプリケーションでの対話ポイント
図4. [タスク・リスト]アプリケーションでの対話ポイント
図4. [タスク・リスト]アプリケーションでの対話ポイント

図4では、利用できるすべてのホット・スポットがピンク色で強調表示されています。ホット・スポットごとに、使用されているHTMLが異なります。[REFRESH!]リンクと[ Create new todo!]リンクは静的なコードであるのに対し、ステータス記号(赤色のXと緑色のチェックマーク)および項目の件名は動的にレンダリングする必要があります。このアプリケーションでは、ヘルパー関数をセットアップし、このルーチンはLotus Domino Server が提供するアイコンに基づいて動作します。ユーザーへの視覚的な応答を生成するために、どのようなHTMLコードおよびJavaScriptコードが必要な場合でも、サーバーへの要求は、XMLHttpRequestオブジェクトを使用して同じ方法でセットアップされます。

Ajax要求のセットアップと処理

実際のXMLHttpRequestオブジェクトを作成することは、非常に簡単です。より複雑なソリューションでは、一種のキュー・ハンドラーを用いることも可能です。しかし、ここでは、次のリストに示すコードを使用します。

var xmlHttp;
function createXMLHttpRequest() { 
  if (window.ActiveXObject) { 
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); 
  }
  else if (window.XMLHttpRequest) { 
    xmlHttp = new XMLHttpRequest(); 
  }
}

作成、送信、取得

読みやすさを考慮すると、APIの各メソッドをクライアント・サイドの1つのメソッドとサーバー・サイドの同名のメソッドにマッピングする方法がより簡単です。次のコード・リストに示すJavaScript関数は、ユーザーがステータス・アイコン(緑色のチェックマークまたは赤色のX)をクリックするたびに呼び出されます。これは、関数の宣言から開始します(02)。この関数は、xmlHttpオブジェクトがステータスの変更を受信するたびに実行されます(12)。

行(10)ではグローバル変数Httpが生成され、行(11)ではURLに追加する引数が構築されます。行(13)では、行(16)で送信されるAjaxオブジェクトが開始されます。

01  function toggleStatus(key) {
02    this.handleStateChange = function() {
03      if(xmlHttp.readyState == 4) {
04        if(xmlHttp.status == 200) {
05          refreshTodoList(xmlHttp.responseXML);
06        }
07      }
08    }
09
10  createXMLHttpRequest(); // build update string
11    var args='&method=ToggleStatus&key=' + key;
12    xmlHttp.onreadystatechange = this.handleStateChange;
13    xmlHttp.open("GET"
14      ,"./HandleAjaxRequests?open" + args
15      ,true);
16    SMLHTTP.send(null);
17  }

行(05)でXMLパーサーへ応答を渡す前に、2つのチェックが行われます。

サーバー間実装のソリューション

現在のすべてのXMLHttpRequest (XHRとも呼ばれます)インプリメンテーションには、異なるドメインによる要求の処理を禁止するセキュリティー制限があります。この制限により、複数のサーバーが関与する場合は、Ajaxソリューションを使用することが困難になります。この記事では、この制限を変更する方法やその意義については触れません。代わりに、コードの量が少し増えますが、少なくともXMLHttpRequestインプリメンテーションによって得られるものと同じエクスペリエンスをユーザーに与えることができる代替手法を紹介します。

  • XMLHttpRequestオブジェクトがあらゆる場所にインプリメントされる以前は、Ajax機能を得るために、iframeによる手法が一般的でした。非表示のiframeオブジェクトにコンテンツをロードし、バックグラウンドで処理することにより、XHRソリューションと同じような実現性を得られます。
  • XHRがオリジナル以外のサーバーを呼び出すときは、プロキシーによる手法が最良で、おそらく最も一般的でしょう。この手法では、Ajaxページを提供するサーバーにプロキシーを設置する必要があります。プロキシーはすべてのAjax呼び出しを受信し、正しい宛先に転送します。
  • プロキシー設計パターンにも、キャッシュの追加とコンテンツの検証の実現性があります。このため、すべてのコンテンツが同じサーバーからロードされる場合でも、この手法が良いソリューションになることがあります。

まとめ

Ajax設計パターンは、実行する各アクションへの直接の応答を得られるため、ユーザーに適した方法です。また、通信エラーなどが発生した場合に、サーバー・サイドでデータが完結することも優れています。しかし、Lotus Domino開発者またはアーキテクトは、Ajaxソリューションをデプロイする前に、いくつかの点を考慮する必要があります。

まず、W3Cで標準化の動きがありますが、XMLHttpRequestオブジェクトは標準ではありません。次に、サーバーのパフォーマンスについても考慮しなければなりません。Ajaxソリューションは帯域幅の要求を増加させない可能性もありますが、トランザクション数の観点では、Lotus Domino Serverにストレスを与えます。さらに、Webブラウザーの[戻る]ボタンの機能をサポートしないソリューションは避けたい場合もあります。

これらのネガティブな点と、優れた設計のAjaxドリブン・ソリューションがもたらすユーザー・エクスペリエンスとを考え合わせると、ユーザビリティーを改善できる場所であれば、Ajaxを使用できるものと考えられます。この記事では、要素を少し追加するだけで、一般的なページ指向のWebサイトよりも便利なWebエクスペリエンスをユーザーに簡単に提供できることを説明しました。


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


関連トピック


コメント

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Lotus
ArticleID=341098
ArticleTitle=Ajaxを使用したLotus Notes文書の操作
publish-date=06062006