JSFに触ってみる
JSFって?
JSF(JavaServer Faces)は、Sun Microsystemsが策定したWebアプリケーションフレームワーク
(ユーザインタフェース開発)用の仕様(JSR-127)です。
つまり、実際にWebアプリケーションを開発する場合は、実装が必要になります。
今のところ、SunのRIやMyFacesといった実装が存在します。
特徴
- Ease-of-Development
EoD(Ease of Development)は、「開発をより簡単にしよう」というJavaの一つの流れです。
EoDでは、開発生産性を上げるとともに、要求される技術者のスキルを低くし、他言語の技術者が
Javaへ入り込みやすい環境を提供します。
特にJSFでは、「ツール(IDE)を利用することにより開発を簡単にする」という考え方が前提としてあり、
VB(Visual Basic)のようなGUIライクな開発スタイルを想定しています。
Standardization(標準化)の一番のメリットはフレームワーク導入コストの削減が可能である
ということです。
そもそもフレームワークは開発生産性を向上してくれるものですが、フレームワークの使い方を覚える
為にはそれなりの時間が必要となります。
ところが、プロジェクトにより利用されるフレームワークは様々です。
プロジェクトが変わる度に別のフレームワークの使い方を学習しなければなりません。
そこで、標準化フレームワークであるJSFを利用することで、フレームワークを乗り換えるコストを
削減しようということが狙いです。
JSFは、JCP(Java Community Process)というJavaの標準化プロセスを経て作られています。
JCPで作られる仕様はJSR(Java Specification Requests)と呼ばれ、仕様毎に番号で管理されます。
JSFは、JSR127で議論が交わされ、仕様が策定されました。
- Device Independence
Device Independence(デバイスの独立)は、クライアント端末の切り替えを容易にします。
つまり、どういうことかというと例えばクライアントをブラウザ(HTML)から携帯端末(WML)へ
容易に移行できるということです。
JSFでは、ビューとロジックが明確に分離して設計されている為、同じビジネスロジックを異なるビュー
でも流用することが可能です。
ライフサイクル
JSFアプリケーションにおいて、「リクエストを処理する一連の流れ」です。
フェーズとは、ライフサイクル中の処理単位のことです。
①Resotre Viewフェーズ:
リクエスト送信元の画面構造(JSFタグの階層)をJavaのオブジェクト(UIコンポーネント)で構築する。
(コンポーネントツリーの構築)
②Apply Request Valuesフェーズ:
①で構築したオブジェクト(UIコンポーネント)に、画面の値を設定する。
③Process Validationsフェーズ:
②で設定した値に対し、バリデーション(値の検証)を行なう。(入力チェック)
バリデーションに失敗した場合は、⑥Render Responseに進みます。(④、⑤はスキップ)
バリデーションに成功した場合は、値のコンバージョンを行ないます。(String→Integer等)
④Update Model Valuesフェーズ:
UIコンポーネントの値を、モデルへ反映します。
モデルとは、一般的にビジネスドメインのオブジェクトを指しますが、
JSFでは、managed bean、またはbacking beanと呼びます。
⑤Invoke Applicationフェーズ:
このフェーズでは、アクションの実行が行なわれます。
アクションの結果により、遷移先が決まります。
⑥Render Responseフェーズ:
このフェーズでは、UIコンポーネントから画面が作成されます(レンダリング)。
Managed Bean
managed bean(backing bean)は、JSFで利用するJavaクラスのことです。
このJavaクラスは、faces-config.xmlのmanaged-bean要素に登録して利用します。
JSPからJavaクラスへアクセスするには以下のようにJSPへ記述します。
・プロパティの利用
<h:outputText value="#{mybean.name}
・メソッドの利用
<h:commandButton action="#{mybean.doAction}" value="OK"/>
JSFのEL(Expression Language)表記
アクセス | 例 |
---|---|
プロパティ | myBean.number |
配列 | myArray[2] |
マップ | myMap{"key"] |
※.JSTLのEL表記は「${・・・}」ですが、JSFでは「#{・・・}」です。
JSFタグ内では、JSFのELしか記述できない。
ナビゲーション
ナビゲーションとは、画面遷移のことで、ナビゲーションの定義をナビゲーションルールと言います。
また、各画面はそれぞれID(viewID)を持ちます。
ナビゲーションルールは以下の要素で構成されています。
- 遷移元の画面ID
- それに対応した遷移先の画面ID
- その遷移が行なわれる条件
要素 | 説明 | 例 |
---|---|---|
navigation-rule | ナビゲーションルール。faces-config上に複数記述することができる。 | |
from-view-id | 遷移元のviewID | /hello.jsp |
navigation-case | 遷移先パターンを一つ表します。 | |
from-outcome | アクションの結果。アクションとは、JSPのaction属性で指定した文字列。またはアクションメソッドの戻り値です。 | success |
to-view-id | 画面遷移先のviewID | /world.jsp |
from-action | アクションのメソッド。メソッドバインディングを用いて指定します。 | #{useBean.add} |
redirect | リダイレクトを行なうかどうか。この要素を指定すると、フォワードではなくリダイレクトされます。 |
バリデーション
標準バリデータ
JSFで用意されているバリデータは以下の3つです。
- DoubleRangeValidator
- 小数(double型)の精度で範囲チェック
- LongRangeValidator
- 整数(long型)の精度で範囲チェック
- LengthValidator
- 文字数チェック
使用例
<h:inputText id="first" size="8" required="true" value="#{userBean.firstNumber}"> <f:validateLongRange minimum="0" maximum="100" /> </h:inputText>
メソッドバリデータの作成
標準バリデータだけで行なえる検証は、上記の3種類に限られます。
標準バリデータで行なえない検証が必要になった場合、独自にバリデータを作成することになります。
その一つがメソッドバリデータです。
メソッドバリデータは、次のようにして作成します。
- managed beanにバリデートメソッドを作成します。
- 入力タグのvalidator属性へそのメソッドを指定
バリデートメソッドの例
public void check(FacesContext context, UIComponent, Object value) { ValueHolder from = (ValueHolder)component.findComponent("first"); Integer fromValue = (Integer)from.getValue(); if(fromValue.intValue() >= ((Integer)value).intValue()) { FacesMessage errerMsg = new FacesMessage("項目1は項目2より小さい値でなければなりません。"); throw new ValidatorException(errerMsg); } }
JSPの例
<h:inputText id="first" size="8" required="true" value="#{userBean.firstNumber}"> <f:validateLongRange minimum="0" maximum="100" /> </h:inputText> <h:inputText id="first" size="8" required="true" value="#{userBean.secondNumber}" validator="#{userValidator.check}" />
メッセージと国際化
メッセージリソースの指定
アプリケーションで利用するメッセージはソース中に文字を埋め込まずに、
外部のリソースファイルに定義します。
メッセージリソースファイルは、faces-config.xmlのapplication要素で指定します。
<application> <message-bundle>myapp.Messages</message-bundle> <locale-config> <default-locale>en</default-locale> <supported-locale>en</supported-locale> <supported-locale>ja</supported-locale> </locale-config> </application>
この例では、リソースファイル(message-bundle)にmyapp.Messageを指定しています。
このリソースファイルは、クラスパス上でmyapp/Messages.propertiesという名前で配置します。
(日本語リソースの場合はmyapp/Messages_ja.properties)
このように複数のロケールを予め定義しておくことで、クライアントのブラウザのロケール設定により
表示されるメッセージを切り替えることができる。