AJAXを活用したWebインタフェースの作成ツール ZK
上記の説明に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("Hello World!")"/> </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() )); } ...
最後に、右のスクリーンショットに示した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、ファイルシステム、検索ソリューションを中心にコンサルティングをしている。