AJAXを活用したWebインタフェースの作成ツール ZK

 Webブラウザー上で動作するユーザー・インタフェースが、デスクトップ・アプリケーションでイベント駆動インタフェースを作るときと同じように簡単に作れたら――この夢を実現するために作られたのがAJAXツールキット ZK だ。ZKが作るユーザー・インタフェースはXMLを使って定義し、Javaを使ってWebアプリケーションの機能を実装する。データバウンド・コントロールに対応しているため、Javaオブジェクトを変更したからといってユーザー・インタフェースのフォームを変更する必要はない。

 上記の説明にAJAXは出てくるのにJavaScriptが出てこないのはなぜだろうかと思った人のために、ZKのWebサイトにある次の言葉を引用しておこう。「AJAXの最良の使い方はその存在を見せないことだと我々は考える」。この言葉からプロジェクトの理念がわかると思う。より具体的には、すべてのクライアントサイド・コードをZKの枠組みの中に置き、開発したすべてのコードをサーバーサイドで実行するのだ。こうすれば、AJAXやXMLの解釈について心配する必要はまったくない。

 ZKには標準のサーバー・インストール用バイナリー・ダウンロード・ファイルとしてStandard Edition、Professional Edition、Enterprise Editionの3種が用意されている。上位と下位のEditionは上位が下位の全機能を包含する関係にある。たとえば、Professional EditionはStandard Editionが備えるすべての機能を持ち、さらにCAPTCHAやJFreeChartなどの機能も備えている。また、モバイル・クライアント用に、Mobile Interactive Languageを用いたものと、GoogleのAndroidとHandset Interactive Languageを対象とした特別版が用意されている。

 この記事を書くに当たって用いたマシンは32ビットFedora 9、ZKはEnterprise Editionバージョン3.0.6。大きさはtar.gzで21MBほどだ。ZKを使うには、ほかにWebサーバー上にApache Tomcatなどのサーブレット・コンテナーがインストールされている必要がある。サーバーにZKをインストールする方法には、Webアプリケーションの一部としてインストールする方法と、サーブレット環境にあるすべてのWebアプリケーションから利用可能な共有コンポーネントとしてインストールする方法がある。前者の場合、ZKはWebアプリケーションの中に埋め込まれるため、サイトの移動が容易という利点がある。また、同じサーバー上の複数のサイトでZKを使いたい場合は、後者の方法にすれば管理の手間を省くことができる。

 Tomcatについては、Fedora 9とopenSUSE 11用のtomcat6パッケージと、Debian系ディストリビューション用のtomcat5.5パッケージが用意されている。以下に、すべてのWebアプリケーションで使えるようにZKを共有コンポーネントとしてインストールする手順を示す。

# yum install tomcat6 tomcat6-webapp
# service tomcat6 stop
# cd /tmp
# tar xzf /.../zk-bin-3.0.6.tar.gz
# cd zk-bin-3.0.6/
#  vi /etc/tomcat6/catalina.properties
...
shared.loader=/usr/share/java/tomcat6/shared/lib/*.jar
...
# mkdir -p  /usr/share/java/tomcat6/shared/lib
# cd ./dist/lib
# find . -name "*.jar" -exec \
    install -m 644 {} /usr/share/java/tomcat6/shared/lib/ \;
# service tomcat6 start

 TomcatとZKが正常に機能することを確認するため、zipファイルzk-demoをダウンロードする。そして、以下に示すように、そこに含まれている最小版のWebアプリケーション・アーカイブ(WAR)ファイルをTomcatのwebappsディレクトリーに置く。この最小版warファイルにはZKが含まれていないため、ZKがTomcatサーバー上に正しく共有インストールされていないとデモは動かない。次のコマンドを実行し、http://localhost:8080/zkdemo-min/userguide/というURLを開いてみよう。ZKのデモがサーバーからロードされ表示されれば、インストールは完了だ。

# cd /tmp
# unzip /.../zk-demo-3.0.6.zip
# cd ./zk-demo-3.0.6/
# install -m 644 zkdemo-min.war /var/lib/tomcat6/webapps
# service tomcat6 restart

ZKの使用法

 ZKの使用法は、ZK Tutorialに概略が、Developer's Guideに詳細が説明されている。WebインタフェースはMozilla XMLユーザー・インタフェース・ファイル形式(XUL)に類似した言語、ZK User Interface Markup Language(ZUML、またはZUL)で記述する。Tomcatを使ったアプリケーションの開発に不慣れな場合は、まず、テスト用のWEB-INF/web.xmlファイルをZULファイルのディレクトリーの下に置いてみよう。また、Resortサンプルのweb.xmlファイルをコピーして実行するとZULファイルをロードすることができる。

 ZULファイルには、簡単な処理を含めることができる。JavaコードとZULインタフェースの記述は分離した方がよいのはもちろんだが、コードの埋め込みは実験の際には便利だ。適正なXMLとするには埋め込みコードを引用符で囲む必要がある。したがって、Javaコード中の二重引用符は"と記述する。Enterprise Editionでは、JavaScript、Ruby、Groovyで記述することもできる。zscript要素を使うと、ZULファイル中にさらに大きなコード・ブロックを含めることができる。zscript要素の中では二重引用符をエスケープする必要がないので便利だ。以下に、簡単なZULファイルによるWebインタフェースを示す。ボタンがクリックされると、埋め込んだJavaが動作しメッセージ・ボックスが開く。

<window title="Hello" border="normal">
    <button label="Say Hello" onClick="Messagebox.show(&quot;Hello World!&quot;)"/>
</window>

 ZULファイルにコードを埋め込む場合、次の2つの機能を利用するとコードを簡潔に表現することができる。その一つはEL式だ。小さなスニペットを埋め込むことで、Javaオブジェクトのプロパティーにアクセスしたり簡単な比較を行ったりすることができる。もう一つはforEach文で、リストボックスなどの反復的なZUL要素にデータを埋め込む際に使う。また、ユーザー・インタフェースが生成したイベントに応答したいときは、ZULファイルの中でオブジェクトのサブクラスを定義し、明示的にそのサブクラスを使用すればよい。これを利用すると、ZULインタフェース定義ファイルを変えなくても、Javaコードを変更しイベントに対する応答を変えることができる。その際、forward属性を使えば、押下イベントを親オブジェクトに回し、ボタンの押下にサブクラスで反応しないようにすることができる。

 ZKはいわゆる「ライブ・データ」モデルをサポートしており、org.zkoss.zul.ListModelインタフェースを実装すると、そのインタフェースを介して示されたデータはWebページ上のほかのコントロールからも見えるようになる。次に示す例では、Bookmarkクラスをタプルとして使い、URL、ページ・タイトル、最後に訪問された時刻を格納している。ここではaccessorメソッドは省いた。

...
public class Bookmark
{
 private String m_title;
 private String m_earl;
 private Date m_lastVisit;

 public Bookmark() {}
 public Bookmark( String title, String earl, Date lvisit )
 {
 	m_title = title;
	m_earl = earl;
	m_lastVisit = lvisit;
 }
...

 Bookmarkオブジェクトをグリッドに表示するには、表示方法を規定するRendererサブクラスを用意する必要がある。所要のデータを個別のセルに入れる例を以下に示す。

...
public class BookmarkRenderer implements RowRenderer {
 public void render(Row row, java.lang.Object nastyDataRef)
 {
   Bookmark bm = (Bookmark)nastyDataRef;
   new Label( bm.getTitle() ).setParent(row);
   new Label( bm.getURL() ).setParent(row);
   new Label( bm.getLastVisitTime().toString() ).setParent(row);
 }
};

 ListModelListクラスのorg.zkoss.zul.ListModelを可変実装することもできる。下に例示したControllerオブジェクトはbookmarkのサンプルを数件作成している。データはJDBCなどのソースから簡単に取り込むことができる。

...
public class BookmarkController extends Window {
        ListModelList m_bookmarks = new org.zkoss.zul.ListModelList( new ArrayList() );
        Bookmark m_selected = new Bookmark();
        public BookmarkController() {
                m_bookmarks.add( new Bookmark( "Slashdot: News for nerds, stuff that matters",
                                                "http://linux.com", new Date() ));
                m_bookmarks.add( new Bookmark( "Linux.com :: Feature"
                                                "http://slashdot.org", new Date() ));
                m_bookmarks.add( new Bookmark( "The libferris VFS!",
                                                "http://www.libferris.com", new Date() ));
        }
...

zk1_thumb.png
ZK

 最後に、右のスクリーンショットに示したWebインタフェースを作るZULファイルを例示する。window要素のuse属性はこのウィジェットで使用するカスタムJavaクラスを指定する。また、グリッドのモデルにはwindowクラスのBookmarkメンバーを指定している。具体的には、BookmarkControllerクラスのm_bookmarksだ。グリッドでのカスタムJavaオブジェクトの表示方法を規定するため、Rendererを指定する必要がある。

<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<window id="win" use="com.linux.zk.example.bookmark.ui.BookmarkController" 
      title="Bookmarks" width="800px" border="normal">
 <hbox>
<grid model="@{win.Bookmarks}" rowRenderer="com.linux.zk.example.bookmark.ui.BookmarkRenderer" >
  <columns>
   <column label="Title" width="70px"/>
   <column label="URL" width="250px"/>
   <column label="Last Visited" width="100px" />
  </columns>
 </grid>
   <timer id="timer" delay="3000" repeats="false"
          onTimer="win.dataArrived()"/>
 </hbox>
</window>

まとめ

 ZKはSourceForge.net Community Choice Awardsで最終選考に残っているが、現在主流になっている配布方式には対応していない。インストールが特別難しいというわけではないが、Linuxディストリビューションのパッケージ・マネージャーで自動的にアップデートできる方が好ましいことは言うまでもない。

 WebブラウザーとWebサーバー間の通信には非同期コールが使われているが、サーバーとの通信が必要なカスタムDataモデルを表示しているデータ・グリッドをソートするなどの場合に、ネットワークで時間を要していると感じられることがある。サーバー・クライアント間のネットワーク遅延の大きさによっては問題になるかもしれない。

 Webインタフェースを作りたい場合、Javaを使っているならZKを利用してみよう。ブラウザーによって扱いが異なるためJavaScriptコードが期待通りに動くかどうかを心配したり、Webブラウザー用のウィジェットを詳細に指定して作成したりしなくても済む。ZK以前はページをロードするかそれともカスタムJavaScriptコードからAJAXを呼び出して応答するかを常に考えていなければならなかったが、ZKはイベントベースのプログラミング・モデルを採用しており、この点も新鮮に感じられるだろう。

Ben Martin 10年以上にわたってファイルシステムを研究。博士課程を修了し、現在、libferris、ファイルシステム、検索ソリューションを中心にコンサルティングをしている。

Linux.com 原文