Agusa Lab. > Webware Project > GrapeWeb
 

JSF(Java Server Faces)

JSFとは

JSFはJava Community ProcessのJSR-127で検討されてきたWebアプ リケーション向けユーザインタフェースフレームワークの仕様です. 

JSFはSwingのようなAWTコンポーネントをモデルとしたUIに重点が置 かれていましたが,Webアプリケーションに必要な機能をstrutsから 取り込み,両者が融合したような仕様となっています.

JSFはユーザインタフェースを構築するために必要な機能を提供しています.

  • 多くの多機能コンポーネントの実装
  • 入力値の妥当性検査を行うバリデーション機能
  • 値の型変換を行うデータコンバーション機能
  • イベント処理を行うイベントリスナー機能
  • 画面遷移を行うページナビゲータ機能
  • 値を保持するためのモデルデータ機能
  • クライアントにレスポンスを返すためのレンダラ機能

また,JSFはstrutsと比べて以下のメリットがあります.

  • Javaスタンダードとしての位置づけ(JSR-127)
  • 豊富なUIコンポーネント
  • レンダリング部分の分離によってクライアントに柔軟に対応
  • 少ないコーディングで開発可能
  • ツールによる自動生成を考慮

JSFの機能

下の図はJSFアプリケーションがクライアントからのリクエストを受 けて,JSFフレームワークの機能を利用して処理を実行する様子を示 したものです.処理の中で利用される機能について説明を行います.

  • FacesServlet
    JSFページのエントリー・ポイントとし て機能するサーブレットです。このサーブレットはJSFフレーム ワークのファサードのような役割を担います。クライアントか らのリクエストURLに基づいてJSFページに処理をフォワードし ます。このサーブレットはJSF1.0実装が提供します。
  • JSPページ
    JSFタグが含まれるJSPページはMVCモデルの ビューを担当します。ブラウザなどのクライアント画面を作成 するのがこのJSPページです。JSPページの中ではビューを表す コンポーネントが、タグを使用してプレゼンテーションと振る 舞いを定義されます。JSPページはアプリケーション開発者が実 装します。
  • タグ・ライブラリー
    JSPページが使用するタグはタグ・ ライブラリーとして提供されています。JSF1.0実装ではコア・ タグとHTMLコンポーネント・タグが提供されています。アプリ ケーション開発者が新規に開発することも可能です。このよう に新規で開発したタグをカスタム・タグと呼びます。
  • バリデーター
    入力項目のバリデーション・チェックを 行います。入力コンポーネントの設定を元に、必須項目には値 が入力されているか、入力値の設定された最大・最小の数に収 まっているかなどがチェックされます。バリデーション・チェッ クでエラーが発生したときには、エラー・メッセージを表示さ せることが可能です。JSF1.0実装ではデフォルト・バリデーター 実装を提供しています。アプリケーション開発者が新規に開発 することも可能です。このように新規で開発されたバリデーター をカスタム・バリデーターと呼びます。
  • コンバーター
    入力された値の型変換を行います。クラ イアントからのHTTPリクエストを受信すると、入力コンポーネ ントの入力値はバインドされたモデル・データに格納されます が、その際にはモデル・データの属性への型変換が行われます。 JSF1.0実装ではデフォルト・コンバーター実装を提供していま す。アプリケーション開発者が新規に開発することも可能です。 このように新規で開発されたコンバーターをカスタム・コンバー ターと呼びます。
  • モデル・データ
    ユーザー・アプリケーションの処理に 必要なデータを保持します。モデル・データの属性を入力コン ポーネントにバインドすることで、ビューとモデル間のデータ の同期化を図ることが出来ます。ブラウザからのリクエスト・ データは自動的にモデル・データの属性に設定されます。また モデル・データの属性値が自動的に処理結果画面に表示されま す。モデル・データはアプリケーション開発者が開発します。
  • イベント・リスナー
    画面のイベントをキャッチしてユー ザー・アプリケーションの処理を実行します。イベントの種類 としては入力値の変更時にイベントを発生させるバリュー・チェ ンジ・イベントやボタンのクリック時にイベントを発生させる アクション・イベントなどがあります。イベントへのリスナー 登録やイベント発生時の処理の実装はアプリケーション開発者 が開発します。
  • アクション・メソッド
    画面の遷移先を決定する処理です。 登録されているバッキング・ビーンのアクションメソッドを呼 び出し、その返り値で渡される文字列で遷移先の画面を決定し ます。アプリケーション開発者が開発します。
  • コンフィグレーションファイル
    JSFの構成ファイルです。 JSFフレームワークはこのファイルの設定を元に動作します。ア プリケーション開発者が開発します。

JSFのライフサイクル

さらにJSFではリクエストからレスポンスまでのWebアプリケーショ ンに定番の処理をライフサイクルとして仕様化しています.以下に 示すライフサイクルの中でJSFが提供する機能が実行されます.

  • Apply Request Values
    Restore Viewで作成したビューの UIコンポーネントに対してリクエストのHTTPリクエスト、Cookie、 HTTPヘッダーをセットします。これはUIコンポーネントのdecode メソッドを使用して行われます。パラメーターのコンバージョン に失敗した場合にはエラーメッセージがFacesContextのキューに 追加され、JSF実装はリスナーに対してイベントを通知します。コ ンポーネントが属性immediate=trueを持つ場合、コンポーネント に関連付けられたバリデーション、コンバージョン、イベントは この局面で処理されます。
  • Process Validations
    コンポーネントに格納されたデー タのバリデーションを検証します。ここでバリデーション・エ ラーが発生したらFacesContextにエラー・メッセージを追加し て、Render Response局面へ移動してエラー・メッセージを表示 します。
  • Update Model Values
    バリデーションまで完了したデー タを使用してモデルのプロパティーを更新します。モデルのプロ パティーへの型変換に失敗した場合にはRender Response局面へ移 動してエラー・メッセージを表示します。
  • Invoke Application
    アプリケーション・イベントを処 理し、実行結果に応じて遷移先のページを決定します。 UICommandコンポーネントに対応するタグのaction属性の値を元に 関連付けられているアクション・リスナーを呼び出し、その返り 値とアプリケーション・コンフィグレーション・リソース・ファ イルの構成を参照して遷移先のページを決定します。
  • Render Response
    各コンポーネントのレンダラーを呼び 出し、レスポンスを作成します。各局面でエラーが発生した場合 にはエラー画面を作成します。その後でビューの状態をセッショ ンに保管します。ここで保管されたビューは次回のリクエストの Restore View局面で復元されます。

サンプルアプリケーションの開発

今からJSFを使って簡単なログインアプリケーションを作成してみま す.ログインアプリケーションの動作は以下になります.

  • login.jspでユーザ名「test」,パスワード「hogehoge」と入力 して「Login」ボタンを押すとwelcome.jspに遷移します.
  • ユーザ名かパスワードを間違えた場合はwelcome.jspに遷移しません
  • welcome.jspで「戻る」ボタンを押すとlogin.jspに戻ります

はじめにweb.xmlの設定をします.

<web-app>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup> 1 </load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/jsf/*</url-pattern>
    </servlet-mapping>
</web-app>
	

ここではjsfで始まるパスをJSFのサーブレットに処理させるように設定します

次にindex.jspを作成します.

<html>
<body>
    <jsp:forward page="jsf/login.jsp"/>
</body>
</html>
	  

login.jsp以降はJSFのサーブレットに処理させたいので jsf/login.jspとしてフォワードさせています.

ログイン画面となるlogin.jspを作成します.

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ page contentType="text/html; charset=Shift_JIS" %>

<html>
<body>
<f:view>
    <h2>ログイン画面</h2>
    <h:form>     
        name:<h:inputText id="name" value="#{login.name}"/><br/>
        password:<h:inputSecret id="password" value="#{login.password}"/><br/>
        <h:commandButton action="#{login.login}" value="Login"/>
    </h:form>
</f:view>
</body>
</html>
	  

JSFでは標準でコア・タグとHTMLタグを提供しており,その2種類 のタグライブラリーを利用します.

bodyタグの直後にf:viewタグが出現します.JSFではタグライブラ リーをf:viewの中に記述しなくてはなりません.

h:inputTextはテキストフィールド,h:inputSecretはパスワード フィールド,h:commandButtonはボタンのコンポーネントです. value属性に「#」から始まる文字列が記述されていますが,これ をEL(Expression Language)と言います.

login.jspではユーザ名とパスワードを保持するためのBeanが必要になります. JSFではアプリケーションで利用するBeanをfaces-config.xmlに記述します.

<?xml version='1.0' encoding='UTF-8'?>

<!DOCTYPE faces-config PUBLIC
  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
  "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">

<faces-config>
    <managed-bean>
        <managed-bean-name>login</managed-bean-name>
        <managed-bean-class>org.sapid.grape.sample.jsf.login.Login</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
</faces-config>
	  

managed-beanセクションでアプリケーションで利用するBeanを指定します.

  • managed-bean-name : Beanの論理名
  • managed-bean-class : Beanのクラス名
  • managed-bean-scope : Beanのスコープ(request/session/application)
        name:<h:inputText id="name" value="#{login.name}"/><br/>
        password:<h:inputSecret id="password" value="#{login.password}"/><br/>
	  

managed-beanセクションで指定したBeanはELを用いる事でjsp内の コンポーネントとバインドする事が出来ます.今回はテキスト フィールドの値とLoginクラスのname属性を,パスワードフィー ルドの値とLoginクラスのpassword属性をバインドしています.

        <h:commandButton action="#{login.login}" value="Login"/>
	  

login.jspでは「Login」ボタンを押したらログイン処理をして画面 遷移をします.JSFではボタンのaction属性にELでBeanのメソッドを 記述する事でボタンアクションと処理をバインドします.今回は 「Login」ボタンを押した時にLoginクラスのloginメソッドが実行さ れるようにバインドしています.

画面遷移はfaces-config.xmlに以下のように記述します.

    <navigation-rule>
        <from-view-id>/login.jsp</from-view-id>
        <navigation-case>
            <from-outcome>success</from-outcome>
            <to-view-id>/welcome.jsp</to-view-id>
        </navigation-case>
    </navigation-rule>
    <navigation-rule>
        <from-view-id>/login.jsp</from-view-id>
        <navigation-case>
            <from-outcome>failed</from-outcome>
            <to-view-id>/login.jsp</to-view-id>
        </navigation-case>
    </navigation-rule>
	  

navigation-rulesエントリに遷移元のjspファイル名,action属性の値, 遷移先jspファイル名を記述します.

「Login」ボタンが押されたときの処理をLoginクラスに実装します

	private String name = new String();
	private String password = new String();

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
	public String login(){
		if(name.equals("test") && password.equals("hogehoge")){
			return "success";
		}else{
			return "failed";
		}
	}
	  

loginメソッドでログイン処理を行っています.ユーザ名(name)とパス ワードは(password)はバインドによってテキストフィールドとパスワー ドフィールドと同期がとれているので,strutsのActionFormのような 処理は必要ありません.さらに画面遷移の情報として"success"と "failed"という文字列を返すようにしています.

最後にwelcome.jspを作成します.

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ page contentType="text/html; charset=Shift_JIS" %>

<html>
<body>

<f:view>
    <h2>ようこそ</h2>
    <h:form>
        こんにちわ!<h:outputText value="#{login.name}"/>さん!<br/>
        <h:commandButton action="back" value="戻る"/>
    </h:form>
</f:view>
</body>
</html>
	  

ここではlogin.jspで入力された名前を出力するためにh:outputTextタ グを利用しています.また,「戻る」ボタンでlogin.jspに遷移するた めにaction属性に「back」を指定し,画面遷移の設定を faces-config.xmlに追加します.

       <navigation-rule>
           <from-view-id>/welcome.jsp</from-view-id>
           <navigation-case>
               <from-outcome>back</from-outcome>
               <to-view-id>/login.jsp</to-view-id>
           </navigation-case>
       </navigation-rule>
	  

おわりに

簡単なアプリケーションでJSFの紹介を行いました.strutsに比べる とサーバーサイドの処理がシンプルになったと思います.JSFにはコ ンバージョンやレンダリング等,今回紹介しきれなかった機能がま だまだありますので,興味を持った方は勉強してみてください.

by Yuuki MIZUNO