連載 役に立つXMLツール集(9)
XULとJSFでリッチクライアント 〜JSF編〜 Page 1

XMLプログラミングでは、DOMやSAXといったAPIを使用すると単調なコードを繰り返し書くことになり生産性が上がらないものだ。本連載では開発者が“楽をする”ために役立つXML関連ツールを紹介していく。(編集局)

www.netpotlet.com
原田洋子
2004/6/24

JavaServer Facesを使いこなす

主な内容
--Page 1--
JavaServer Facesを使いこなす
JSFのリクエスト処理ライフサイクル
JSFのUIコンポーネントとレンダリング
--Page 2--
サンプルプログラムの作成
開発手順1 コンポーネント作成
開発手順2 XULとJavaBeansの作成
まとめ&サンプルダウンロード

 前回「XULとJSFでリッチクライアント 〜XUL編〜」ではXULの使い方を中心に解説しました。今回はサーバサイド側で使うJavaServer Faces(JSF)の話に移りましょう。JSFはJava Community ProcessでJSR-127の番号で検討されてきたWebアプリケーション向けユーザーインターフェイス(UI)フレームワークのための仕様です。バージョン1.0の正式版が2004年3月にリリースされ、その後、メンテナンスバージョンである1.1が2004年5月にリリースされました。JSF仕様の実装はサン・マイクロシステムズ社からの参照実装と、オープンソースの実装myFacesがリリースされています。

 JSFがターゲットにしているWebアプリケーション用のフレームワークは、現在、多種多様なものがリリースされているうえに、デファクトスタンダードとなるような製品もありません。それぞれ方式や得意とする部分が違い、開発手法までがフレームワークによって変わってくるので、これから始めようという開発者はとても迷うでしょう。

 JSFはこのような現状を改善する試みとして作られた仕様です。JSFは当初、SwingのようなAWTコンポーネントをモデルにしたUIに重点が置かれていました。ここに人気のあるフレームワーク製品StrutsからWebアプリケーションで必要になる機能などが取り込まれ、UIを含むWebアプリケーションフレームワークの仕様となりました。現在でも仕様書には“UIフレームワーク”と書かれていますが、JSPのJSFタグが強化され、UI部分がラッピングされてきているので、一般の開発者にとってはWebアプリケーション用フレームワークの仕様といえるでしょう。

 JSFで仕様化が試みられたのは、これまでWebアプリケーション開発者が決まって行う処理の部分です。つまり、

  • フォームの入力を取得する
  • 入力された値が適当かどうかを検証する
  • 入力値を使ってロジックを実行する
  • レスポンスを返す

といった処理の流れを仕様化し、フレークワーク製品を変えても、その上で動くWebアプリケーションを修正しなくて済むようにしようというものです。

JSFのリクエスト処理ライフサイクル

 Webアプリケーション開発者が決まって行う処理の部分には、リクエスト処理ライフサイクルという概念が持ち込まれました。各処理を分割し、時系列に従って並べたものです。仕様書によると、リクエスト処理ライフサイクルは図1のようになっています。

図1 JSFのリクエスト処理ライフサイクル

 このライフサイクルを回しているのが

  • UIコンポーネント
  • イベント

の2つです。UIをAWTに置き換えてみると、おなじみのイベント/イベントリスナで動くJavaのGUIプログラミングそのものです。JSFにはGUIコンポーネントの概念が持ち込まれ、UIコンポーネントが中心になって動く設計になっています。JSFを“UIコンポーネント指向のフレームワーク”ととらえると、より理解しやすくなるはずです。

 このライフサイクルをWebアプリケーションのお決まりの処理と照らし合わせてみましょう。各処理は次のようになっています。

1. Restore View
 リクエストに該当するHTMLやJSP、テンプレートなどを解析してUIコンポーネントのツリーを作る過程。従来のWebアプリケーションではプレゼンテーションツールが行うので開発者は何もしないことが多い。

2. Apply Request Values
 フォームに入力されたパラメータなどを取得する過程。取得した値はその値を維持するコンポーネントの状態として管理される。取得した値はコンポーネントの状態変化に適用されるので“apply”となっている。この過程ではUIコンポーネントのprocessDecode()メソッドが実行される。

3. Process Validations
 フォームなどにより取得した値が正当なものかどうかを検証する過程。UIコンポーネントのprocessValidations()メソッドが実行される。

4. Update Model Values
 JSFはロジック実行時に取得した値をそのまま使わず、モデル経由で参照するのが一般的。そのモデルの状態を更新するのがこの過程。UIコンポーネントのprocessUpdates()メソッドが実行される。

5. Invoke Application
 ロジックを実行する過程。UIコンポーネントのprocessApplication()メソッドが実行される。

6. Render Response
 UIコンポーネントのツリーをHTMLなどのクライアントがレンダリングできる形式にしてレスポンスを返す。UIコンポーネントのencodeBegin()/encodeChildren()/encodeEnd()メソッドか、レンダリングを制御するViewHandlerのrenderView()メソッドが実行される。

 図1の“Process Event”と記されている処理はJSFコンテナ側がイベントを発火させる地点です。また、“Response Complete”と記されているのはJSFのレンダリング機能に代わって、独自のレンダリングエンジンを使う場合に利用されるルートです。JSFのシステムであるFacesContextに定義されているresponseComplete()がそのためのメソッドです。

 ここまでの説明に、UIコンポーネント以外にハンドラやコンテキストが登場しましたが、JSFのライフサイクル各ステージでは図2のハンドラやマネージャが働くことになっています。これらのうち、ViewHandlerやNavigationHandlerなどいくつかはJSFの実装がディフォルトの振舞いを提供することになっていますので、一般の開発者が実装しなくても使えるようになっています。

図2 JSFのハンドラ/マネージャ

なぜライフサイクルなのか

 さて、図1は“サイクル”という名前に反してサイクルになっていません。仕様書もやはり明示的にスタート時点に戻ってはいません。それではなぜサイクルなのでしょうか。

 実はこのサイクルと並行して状態維持という操作が定義されています。維持される状態にはフォームの入力値などを扱うモデルオブジェクトやUIコンポーネントツリーです。つまり、JSFはスタート時点で維持されているUIコンポーネントツリーがあればそれをコンポーネントの値ともども復元する、なければ新規にツリーを作ることを定義しています。スタート時点が“Restore View”で始まるのはこのためです。

 復元されるはずのコンポーネントツリーというのはクライアントに返したレスポンスと同等のもので、このツリーを取っておく作業は“Render Response”の過程で行われます。仕様でこのように定義されているので、JSFを実装しているフレームワーク製品ならどれでも同じ方法で、“さっきの入力ページ”に戻ったときに、“さっき入力した値”を復元できます。なお、状態の維持はStateManagerに任されている仕事です。

JSFのUIコンポーネントとレンダリング

マークアップ言語に依存しないUIコンポーネント

 JSFではUIコンポーネントが中心的な役割を果たしていると説明しました。今度はその要となるUIコンポーネントがどうなっているかを見てみましょう。

 JSFはHTMLなどのマークアップ言語に依存しないUIコンポーネントツリーを作れるのが売りの1つです。図3に示すように、JSF内部ではHTMLなどのマークアップ言語のファイルが“restore”されてUIコンポーネントツリーにマップされ、“render”によりツリーからマークアップ言語などのクライアントに合わせた形式にマップされてレスポンスが返ります。実際には、UIコンポーネントツリーの作り方や“render”部分でやや工夫が必要ですが、設計上はHTMLを読み込んでXULやSVGでの出力もできるような仕様になっています。

図3 UIコンポーネントツリーとのマッピング

レンダリングの詳細

 マークアップ言語に依存しないUIコンポーネントツリーからどのようにしてレンダリングされるかを詳しく見てみましょう。JSFのレンダリング方法には

  • direct implementation
    UIコンポーネントのencodeXXX()メソッドを実行する
     
  • delegated implementation
    ViewHandlerのrenderView()メソッドを実行する
    具体的なレンダリング方法はRenderKitが知っている

の2種類があります。1つ目の方法は簡単に実装できますが、これではマークアップ言語と1対1の依存関係ができてしまいます。依存関係をなくすには2つ目の方法で実装することになります。図4を見てください。ViewHandlerはRenderKitを参照していますが、そのRenderKitはUIコンポーネント1つ1つの具体的なレンダリング方法を知っているRendererを持っています。薄いオレンジ色で囲んだRenderKitとRendererの部分は変更可能なので、HTML用RenderKit、XUL用、SVG用……と作り、必要に応じて取り換えてHTMLからXULを出力するのは不可能ではありません。コンポーネントとRendererとの対応にはfamily nameと通常、component typeも使います。このような識別名で対応を取りながらレンダリングしていくのがJSFのモデルです。

 HTML用のRenderKitはあらかじめ用意しておくことが仕様で決められているので、デフォルトで使えるようになっています。

図4 JSFのレンダリングモデル

 以上、ごく簡単にJSFの概要を説明しましたが、JSFにはほかにも国際化機能やXMLモデルからオブジェクトモデルへなどのモデルマッピングを行う場合のデータ型の変換を行うコンバータなどいくつも機能があります。次回のアクション編ではナビゲーションやリスナなどの説明が中心になりますが、ほかの機能についても触れる予定です。

 それでは次ページより、XULとJSFを使ったサンプルプログラムの作成に入りましょう。(次ページに続く)

  1/2

 Index
連載 役に立つXMLツール集(9)
XULとJSFでリッチクライアント 〜JSF編〜
Page 1
・JavaServer Facesを使いこなす

・JSFのリクエスト処理ライフサイクル
・JSFのUIコンポーネントとレンダリング
  Page 2
・サンプルプログラムの作成
・開発手順1 コンポーネント作成
・開発手順2 XULとJavaBeansの作成
・まとめ&サンプルダウンロード


「連載 役に立つXMLツール集」


XML & SOA フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

HTML5+UX 記事ランキング

本日月間