corner imagecorner image
IDEPlatformPluginsDocs & SupportCommunityPartners

JavaServer Faces 2.0 入門

JavaServer Faces (JSF) は、Java Web アプリケーション用のユーザーインタフェース (UI) フレームワークです。これは、Java アプリケーションサーバー上で実行され、UI をターゲットクライアントに描画するアプリケーションの作成と維持にかかる負荷を大幅に軽減するように設計されています。JSF は、次のような方法で使いやすさを実現します。

  • 再利用可能な UI コンポーネントのセットから UI を簡単に構築できる
  • UI との間でアプリケーションデータの移行を簡素化
  • サーバー要求間での UI の状態管理を支援
  • クライアントが生成したイベントをサーバー側アプリケーションコードに記述するための簡易モデルを提供
  • カスタム UI コンポーネントを簡単に構築して再利用できる

JSF フレームワークの詳細については、「Java EE 6 チュートリアル: 第 5 章 - JavaServer Faces テクノロジ」を参照してください。

このチュートリアルでは、NetBeans IDE を使用して JSF 2.0 サポートを Web アプリケーションに適用する方法を説明します。まず JSF 2.0 フレームワークサポートを基本的な Web アプリケーションに追加し、そのあと次の手順を実行します。

  • 要求データを処理する JSF 管理対象 Bean の作成
  • 管理対象 Bean をアプリケーションの Web ページに記述
  • Web ページを Facelets テンプレートファイルに変換

NetBeans IDE は、JavaServer Faces のサポートを長期にわたって提供してきました。JSF 2.0 および Java EE 6 のリリースに応じて、NetBeans IDE では JSF 2.0 の特別サポートを提供します。詳細については、「NetBeans IDE での JSF 2.0 のサポート」を参照してください。

目次

このページの内容は NetBeans IDE 6.8、6.9、7.0、および 7.1 が対象です

このチュートリアルを完了するには、次のソフトウェアとリソースが必要です。

ソフトウェアまたはリソース 必須バージョン
NetBeans IDE 6.8、6.9、7.0、7.1、Java EE バンドル版
Java Development Kit (JDK) 6
GlassFish サーバー Open Source Edition 3.x
jsfDemo Web アプリケーションプロジェクト n/a

注:

  • NetBeans IDE の Java バンドル版には、このチュートリアルに必要な、Java EE 6 準拠サーバーの GlassFish サーバー も含まれています。
  • プロジェクトを、正常に機能するソリューションと比較するには、完成したサンプルプロジェクトをダウンロードします。

Web アプリケーションへの JSF 2.0 サポートの追加

まず、IDE で jsfDemo Web アプリケーションプロジェクトを開きます。IDE でプロジェクトが開いたら、プロジェクトの「プロパティー」ウィンドウを使用して、フレームワークサポートを追加できます。

IDE で、JSF 2.0 をサポートする新しいプロジェクトを作成することもできます。詳細については、「JSF 2.0 サポートを含む新しいプロジェクトの作成」を参照してください。

  1. IDE のメインツールバーで「プロジェクトを開く」(「プロジェクトを開く」ボタン) ボタンをクリックするか、Ctrl-Shift-O (Mac の場合は &#8984-Shift-O) キーを押します。
  2. 「プロジェクトを開く」ダイアログで、展開したチュートリアルプロジェクトを格納した場所に移動します。選択して「プロジェクトを開く」をクリックし、IDE で開きます。
  3. プロジェクトを実行して、ブラウザでどのように表示されるかを確認します。「プロジェクト」ウィンドウで「jsfDemo」プロジェクトノードを右クリックして「実行」を選択するか、メインツールバーの「プロジェクトを実行」(「プロジェクトを実行」ボタン) ボタンをクリックします。プロジェクトがパッケージ化されて GlassFish サーバーに配備され、ブラウザが開いて開始ページ (index.xhtml) が表示されます。
    ブラウザの開始ページのスクリーンショット
  4. 「送信」ボタンをクリックします。応答ページ (response.xhtml) が次のように表示されます。
    ブラウザの応答ページのスクリーンショット
    現在、開始ページと応答ページは静的なページで、stylesheet.css ファイルと duke.png イメージがあり、ブラウザからアクセスできる唯一のアプリケーションです。
  5. 「プロジェクト」ウィンドウ (Ctrl-1、Mac の場合は &#8984-1) で、プロジェクトノードを右クリックし、「プロパティー」を選択します。「プロジェクトプロパティー」ウィンドウが表示されます。
  6. 「フレームワーク」カテゴリを選択し、「追加」ボタンをクリックします。表示されるダイアログで「JavaServer Faces」を選択し、「了解」をクリックします。
    「プロジェクトプロパティー」ウィンドウの「フレームワークの追加」ダイアログ
    JavaServer Faces を選択すると、さまざまな構成オプションが使用可能になります。「ライブラリ」タブで、プロジェクトが JSF 2.0 ライブラリにアクセスする方法を指定できます。デフォルトオプションでは、サーバー (GlassFish サーバー) に含まれているライブラリを使用します。ただし、IDE では JSF 2.0 ライブラリもバンドルされます。プロジェクトで登録されているライブラリを使用する場合は、「登録されているライブラリ」オプションを選択できます。
    JSF 構成設定の「ライブラリ」タブ
  7. 「構成」タブをクリックします。Faces サーブレットをプロジェクトの配備記述子にどのように登録するかを指定できます。また、プロジェクトで Facelets または JSP ページを使用するかどうかを示すこともできます。
    JSF 構成設定の「構成」タブ

    NetBeans IDE 7.1 では、プロジェクトで使用するさまざまな JSF コンポーネントスイートを「コンポーネント」タブで簡単に構成することができます。コンポーネントスイートを使用するには、必要なライブラリをダウンロードし、ライブラリマネージャーを使用して、コンポーネントスイートのライブラリを含む新しいライブラリを作成する必要があります。

    JSF 構成設定の「構成」タブ
  8. 「了解」をクリックして変更を確定し、「プロジェクトプロパティー」ウィンドウを終了します。

プロジェクトに JSF サポートを追加すると、プロジェクトの web.xml 配備記述子が変更されて次のようになります。変更場所はボールドで示されています。

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <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>/faces/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

重要: <welcome-file> エントリに「faces/」が含まれていない場合は、手動で追加する必要があります。これにより、開始ページ (index.xhtml) が、Faces サーブレットを介してブラウザに表示されるようになります。Facelets タグライブラリコンポーネントが正しく描画されるようにするには、この処理が必要です。詳細は、「課題 #182277」を参照してください。

Faces サーブレットがプロジェクトに登録され、index.xhtml 開始ページを要求すると、ページは Faces サーブレットを介して渡されるようになります。また、PROJECT_STAGE コンテキストパラメータのエンティティーも追加されています。このパラメータを「Development」に設定すると、アプリケーションをデバッグするときに有用な情報が提供されます。詳細は、 http://blogs.sun.com/rlubke/entry/jsf_2_0_new_feature2 を参照してください。

JSF ライブラリを見つけるには、「プロジェクト」ウィンドウでプロジェクトの「ライブラリ」ノードを展開します。GlassFish サーバーのデフォルトライブラリを使用している場合、これらは GlassFish サーバーノードの下に表示される jsf-api.jarjsf-impl.jar ファイルです。

IDE の JSF 2.0 サポートには、主に JSF 固有の多数のウィザード、および Facelets エディタで提供される特別な機能が含まれています。これらの機能については、以降の手順で説明します。詳細については、「NetBeans IDE での JSF 2.0 のサポート」を参照してください。


管理対象 Bean の作成

JSF の管理対象 Bean を使用して、ユーザーデータを処理し、要求間でそれを保持することができます。管理対象 Bean は、データの格納に使用できる POJO (プレーンオールド Java オブジェクト) です。これは、JSF フレームワークを使用して GlassFish サーバーなどのコンテナで管理されます。

POJO は基本的に、公開で引数のないコンストラクタを格納し、プロパティーが JavaBeans 命名規則に準拠する Java クラスです。

プロジェクトを実行して生成された静的ページを見ると、ユーザーが入力した数値が現在選択されている数値と一致するかどうか、また、この結果に適した表示が返されるかどうかを判断する機構が必要です。IDE の「管理対象 Bean」ウィザードを使用して、この目的に応じた管理対象 Bean を作成します。次の節で作成する Facelets ページは、ユーザーが入力する数値と生成された応答にアクセスする必要があります。これを可能にするには、userNumber および response プロパティーを管理対象 Bean に追加します。

管理対象 Bean ウィザードの使用

  1. 「プロジェクト」ウィンドウで「jsfDemo」プロジェクトノードを右クリックし、「新規」>「JSF 管理対象 Bean」を選択します。「管理対象 Bean」が表示されない場合は、「その他」を選択します。次に、「JavaServer Faces」カテゴリから「JSF 管理対象 Bean」オプションを選択します。「次へ」をクリックします。
  2. ウィザードで、次の情報を入力します。
    • クラス名: UserNumberBean
    • パッケージ: guessNumber
    • 名前: UserNumberBean
    • スコープ: session
    「JSF 管理対象 Bean」ウィザード
  3. 「完了」をクリックします。UserNumberBean クラスが生成され、エディタで開かれます。次の注釈 (ボールドで表示) を確認します。
    package guessNumber;
    
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.SessionScoped;
    
    /**
     *
     * @author nbuser
     */
    @ManagedBean(name="UserNumberBean")
    @SessionScoped
    public class UserNumberBean {
    
        /** Creates a new instance of UserNumberBean */
        public UserNumberBean() {
        }
    
    }

    ここでは JSF 2.0 を使用しているため、注釈を使用して、JSF 固有のコンポーネントをすべて宣言できます。以前のバージョンでは、Faces 構成ファイル (faces-config.xml) で宣言する必要がありました。

    すべての JSF 2.0 注釈を確認するには、「Faces 管理対象 Bean の注釈の仕様」を参照してください。

コンストラクタの作成

UserNumberBean コンストラクタは、0 から 10 の間のランダムな数値を生成し、インスタンス変数に格納します。これが、アプリケーションのビジネスロジックの一部を形成します。

  1. UserNumberBean クラスのコンストラクタを定義します。次のコードを入力します (変更箇所はボールドで表示)。
    public class UserNumberBean {
    
        Integer randomInt;
    
        /** Creates a new instance of UserNumberBean */
        public UserNumberBean() {
            Random randomGR = new Random();
            randomInt = new Integer(randomGR.nextInt(10));
            System.out.println("Duke's number: " + randomInt);
        }
    
    }
    このコードは 1 から 10 の間のランダムな数値を生成し、その数値をサーバーログに出力します。
  2. インポートを修正します。これを行うには、エディタの左側の余白に表示されるヒントバッジ (ヒントバッジ) をクリックし、java.util.Random をクラスにインポートするオプションを選択します。
  3. プロジェクトを再度実行します。「プロジェクトを実行」(「プロジェクトを実行」ボタン) ボタンをクリックするか、F6 キー (Mac の場合は fn-F6) を押します。プロジェクトを実行すると、サーバーのログファイルが「出力」ウィンドウに自動的に開かれます。
    「出力」ウィンドウ内のサーバーログ
  4. コンストラクタで示されるように、出力には Duke's number: が表示されません。UserNumberBean オブジェクトは作成されませんでした。これは、JSF がデフォルトで遅延インスタンス化を使用するためです。つまり、特定のスコープ内の Beans は、アプリケーションで必要とされたときにだけ、作成され、インスタンス化されます。

    @ManagedBean 注釈用の Javadoc には、次のように記載されています。

    eager() 属性の値が true で、managed-bean-scope の値が application の場合は、アプリケーションの開始時にランタイムがこのクラスをインスタンス化する必要があります。このインスタンス化とインスタンスの格納は、ほかの要求を処理する前に実行される必要があります。eager の値が指定されていないか false の場合、または managed-bean-scope が application 以外の場合は、デフォルトの「遅延」インスタンス化と管理対象 Bean のスコープ指定ストレージが発生します。
  5. UserNumberBean はセッションスコープ指定されているため、Serializable インタフェースを実装させます。
    @ManagedBean(name = "UserNumberBean")
    @SessionScoped
    public class UserNumberBean implements Serializable {
    ヒントバッジ (ヒントバッジ) を使用して、java.io.Serializable をクラスにインポートします。

プロパティーの追加

次の節で作成する Facelets ページは、ユーザーが入力する数値と生成された応答にアクセスする必要があります。これを容易にするため、userNumber および response プロパティーをクラスに追加します。

  1. まず、userNumber という名前の Integer を宣言します。
    @ManagedBean(name="UserNumberBean")
    @SessionScoped
    public class UserNumberBean implements Serializable {
    
        Integer randomInt;
        Integer userNumber;
  2. エディタ内で右クリックし、「コードを挿入」を選択します (Alt-Insert、Mac の場合は Ctrl-I)。取得メソッドおよび設定メソッドを選択します。
    コードのポップアップウィンドウを生成
  3. userNumber : Integer」オプションを選択します。
    「取得メソッドおよび設定メソッドの生成」ダイアログ
    「生成」をクリックします。getUserNumber() および setUserNumber(Integer userNumber) メソッドがクラスに追加されます。
  4. response プロパティーを作成します。response という名前の String を宣言します。
    @ManagedBean(name="UserNumberBean")
    @SessionScoped
    public class UserNumberBean implements Serializable {
    
        Integer randomInt;
        Integer userNumber;
        String response;
  5. response の取得メソッドを作成します。(このアプリケーションでは設定メソッドは必要ありません。)前出の手順 2 で示した IDE の「コードを生成」ポップアップを使用して、テンプレートコードを生成することもできます。ただし、このチュートリアルでは、単純に次のメソッドをクラスにペーストします。
    public String getResponse() {
        if ((userNumber != null) && (userNumber.compareTo(randomInt) == 0)) {
    
            //invalidate user session
            FacesContext context = FacesContext.getCurrentInstance();
            HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
            session.invalidate();
    
            return "Yay! You got it!";
        } else {
    
            return "<p>Sorry, " + userNumber + " isn't it.</p>"
                    + "<p>Guess again...</p>";
        }
    }
    このメソッドでは 2 つの関数が実行されます。
    1. ユーザーが入力した数値 (userNumber) がセッション用に生成されたランダムな数値 (randomInt) と等しいかどうか、および String 応答が返されるかどうかがテストされます。
    2. ユーザーが正しい数値を推測した場合 (たとえば userNumberrandomInt が正しい場合)、ユーザーセッションは無効化されます。ユーザーが再度操作する場合に新しい数値が生成されるようにするには、この処理が必要です。
  6. エディタを右クリックし、「インポートを修正」を選択します (Alt-Shift-I、Mac の場合は &#8984-Shift-I)。次の項目用に、インポート文が自動的に作成されます。
    • javax.servlet.http.HttpSession
    • javax.faces.context.FacesContext

    エディタ内の項目上で Ctrl- スペースキーを押すと、コード補完による候補とドキュメントサポートを呼び出しできます。FacesContext で Ctrl- スペースキーを押して、Javadoc のクラス説明を表示します。


    ドキュメントポップアップウィンドウ
    ドキュメントウィンドウの Web ブラウザ (Web ブラウザのアイコン) アイコンをクリックし、外部 Web ブラウザで Javadoc を開きます。

ページへの管理対象 Bean の接続

JSF の主な目的の 1 つは、POJO および POJO とアプリケーションのビューとの相互作用を管理するために、ボイラープレートコードを記述する必要をなくすことです。前の節で、アプリケーションを実行したときに JSF が UserNumberBean オブジェクトをインスタンス化したのがこの例です。この概念は制御の反転 (IoC) と呼ばれ、コンテナがアプリケーションの一部を管理できるようにするものです。これがない場合、開発者は反復的なコードを記述する必要があります。

前の節では、0 から 10 の間のランダムな数値を生成する管理対象 Bean を作成しました。また、ユーザーが入力する数値を表す userNumber プロパティーと、ユーザーの推測に対する応答を表す response プロパティーも作成しました。

この節では、UserNumberBean とそのプロパティーを Web ページで使用する方法について説明します。JSF では、式言語 (EL) を使用して実行できます。式言語を使用して、プロパティー値を、アプリケーションの Web ページに含まれている JSF の UI コンポーネントにバインドします。この節では、JSF 2.0 の暗黙的なナビゲーション機能を活用して index ページと応答ページとの間を移動する方法も説明します。

IDE には、エディタ内の項目上で Ctrl- スペースキーを押すことによって呼び出しできる、コード補完とドキュメント機能によるサポートも用意されています。

まず index.xhtml を変更してから、response.xhtml を変更します。両方のページで、HTML フォーム要素を、JSF HTML タグライブラリで定義されている JSF の対応する要素で置き換えます。次に、JSF 式言語を使用して、プロパティー値と選択した UI コンポーネントをバインドします。

index.xhtml

  1. エディタで index.xhtml ページを開きます。「プロジェクト」ウィンドウで「index.xhtml」ノードをダブルクリックするか、Alt-Shift-O キーを押して「ファイルに移動」ダイアログを使用します。

    inedx ページと応答ページの両方に、ここで必要な JSF UI コンポーネントがすでに含まれています。それらをコメント解除し、現在使用している HTML 要素をコメントアウトします。
  2. HTML フォーム要素をコメントアウトします。これを行うには、次の図の HTML フォーム要素を強調表示し、Ctrl-/ キー (Mac の場合は &#8984-/) を押します。

    注: 強調表示するには、マウスを使用してエディタ内でクリックしてドラッグするか、キーボードを使用して、Shift キーを押しながら矢印キーを押します。
    エディタ内で強調表示されたコード

    Ctrl-/ キー (Mac の場合は &#8984-/) を使用して、エディタ内のコメントを切り替えます。Java や CSS など、ほかのファイルの種類にこのキーボードショートカットを適用することもできます。

  3. JSF HTML フォームコンポーネントをコメント解除します。次の図に示すように、コンポーネントを強調表示して Ctrl-/ キー (Mac の場合は &#8984-/) を押します。
    エディタ内で強調表示されたコード
    JSF HTML フォームコンポーネントをコメント解除すると、<h:form><h:inputText>、および <h:commandButton> タグが宣言されていないことがエディタに表示されます。
    エディタのエラーメッセージ
  4. これらのコンポーネントを宣言するには、IDE のコード補完を使用して、タグライブラリ名前空間をページの <html> タグに追加します。宣言されていない任意のタグの上にカーソルを置き、Ctrl- スペースキーを押します。コード補完による候補とドキュメントサポートが表示されます。
    コード補完による候補とドキュメントのポップアップウィンドウ
    Enter キーを押します。(複数のオプションがある場合は、エディタに表示されているタグを選択してから Enter キーを押してください。)JSF HTML タグライブラリ名前空間が <html> タグ (次にボールドで表示) に追加され、エラー表示が消えます。
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:h="http://java.sun.com/jsf/html">
  5. JSF 式言語を使用して、UserNumberBeanuserNumber プロパティーを inputText コンポーネントにバインドします。value 属性は、描画されたコンポーネントの現在の値を指定するために使用できます。次のボールドで表示されているコードを入力します。
    <h:form>
        <h:inputText size="2" maxlength="2" value="#{UserNumberBean.userNumber}" />
    JSF 式言語では #{} 構文を使用します。これらの区切り文字内で、管理対象 Bean の名前と、適用する Bean プロパティーを、ドット (.) で区切って指定します。これで、フォームデータがサーバーに送られると、プロパティーの設定メソッド (setUserNumber() を使用して、値が自動的に userNumber プロパティーに保存されます。また、ページが要求されて userNumber の値がすでに設定されている場合、描画される inputText コンポーネントに値が自動的に表示されます。詳細については、「Java EE 6 チュートリアル: 統一された式言語を使用した、バッキング Beans の参照」を参照してください。
  6. フォームボタンをクリックして呼び出された要求の宛先を指定します。フォームの HTML バージョンでは、<form> タグの action 属性を使用してこれを実行できました。JSF の場合は、commandButtonaction 属性を使用できます。また、JSF 2.0 の暗黙的なナビゲーション機能により、宛先のファイルの名前を指定するだけで済みます。ファイル拡張子は不要です。

    次のボールドで表示されているコードを入力します。

    <h:form>
        <h:inputText size="2" maxlength="2" value="#{UserNumberBean.userNumber}" />
        <h:commandButton id="submit" value="submit" action="response" />
    </h:form>

    JSF ランタイムは、response という名前のファイルを検索します。JSF では、要求元のファイル (index.xhtml) で使用されているのと同じファイル拡張子であると想定し、元のファイルと同じディレクトリ内 (webroot など) で response.xhtml ファイルを探します。

    注: JSF 2.0 は、開発者のタスクを容易にすることを目的としています。このプロジェクトで JSF 1.2 を使用している場合は、Faces 構成ファイルでナビゲーション規則を次のように宣言する必要があります。

    <navigation-rule>
        <from-view-id>/index.xhtml</from-view-id>
    
        <navigation-case>
            <from-outcome>response</from-outcome>
            <to-view-id>/response.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>

    以降の手順 7 から 12 は、省略可能です。プロジェクトをすばやく構築する場合は、response.xhtml に進みます。

  7. 前出の EL 式で要求を処理するときに setUserNumber() メソッドが実際に呼び出されるかどうかをテストします。これを行うには、IDE の Java デバッガを使用します。

    UserNumberBean クラスに切り替えます (Ctrl-Tab キーを押し、一覧からファイルを選択)。setUserNumber() メソッドの署名にブレークポイントを設定します。これを行うには、左側の余白をクリックします。赤のバッジが表示され、メソッドのブレークポイントが設定されたことを示します。

    エディタの左側の余白にあるブレークポイント
  8. IDE のメインツールバーにある「プロジェクトをデバッグ」(「プロジェクトをデバッグ」ボタン) ボタンをクリックします。デバッグセッションが開始され、プロジェクトの開始ページがブラウザに表示されます。

    注: 「プロジェクトをデバッグ」ダイアログが表示されたら、デフォルトの「サーバー側 Java」オプションを選択して、「デバッグ」をクリックします。

  9. ブラウザで、フォームに数値を入力し、「送信」ボタンをクリックします。
  10. IDE に切り替え、UserNumberBean クラスを確認します。デバッガが setUserNumber() メソッド内で中断されています。
    中断されているデバッガを表示するエディタ
  11. デバッガの「変数」ウィンドウを開きます (「ウィンドウ」>「デバッグ」>「変数」を選択、または Ctrl-Shift-1 キーを押す)。デバッガが中断されている場所の変数値が表示されます。
    「変数」ウィンドウ

    前出の図では、setUserNumber() 署名の userNumber 変数に、値 4 が指定されています。(数値 4 がフォームに入力されたため。)「this」は、ユーザーセッション用に作成された UserNumberBean オブジェクトを参照します。その下にある userNumber プロパティーの値は、現在 null と表示されています。

  12. デバッガのツールバーで、「ステップイン」(「ステップイン」ボタン) ボタンをクリックします。デバッガは、現在中断されている行を実行します。「変数」ウィンドウが再表示され、実行による変更が表示されます。
    「変数」ウィンドウ

    userNumber プロパティーは、フォームに入力された値に設定されます。

response.xhtml

  1. エディタで response.xhtml ページを開きます。「プロジェクト」ウィンドウで「response.xhtml」ノードをダブルクリックするか、Alt-Shift-O キーを押して「ファイルに移動」ダイアログを使用します。
  2. HTML フォーム要素をコメントアウトします。HTML <form> の開始タグと終了タグ、およびそれらのタグ間にあるコードを強調表示し、Ctrl-/ キー (Mac の場合は &#8984-/) を押します。

    注: 強調表示するには、マウスを使用してエディタ内でクリックしてドラッグするか、キーボードを使用して、Shift キーを押しながら矢印キーを押します。

  3. JSF HTML フォームコンポーネントをコメント解除します。<h:form> の開始タグと終了タグ、およびそれらのタグ間にあるコードを強調表示し、Ctrl-/ キー (Mac の場合は &#8984-/) を押します。

    この時点では、<body> タグ間のコードは次のようになります。

    <body>
        <div id="mainContainer">
    
            <div id="left" class="subContainer greyBox">
    
                <h4>[ response here ]</h4>
    
                <!--<form action="index.xhtml">
    
                    <input type="submit" id="backButton" value="Back"/>
    
                </form>-->
    
                <h:form>
    
                    <h:commandButton id="backButton" value="Back" />
    
                </h:form>
    
            </div>
    
            <div id="right" class="subContainer">
    
                <img src="duke.png" alt="Duke waving" />
                 <!--<h:graphicImage url="/duke.png" alt="Duke waving" />-->
    
            </div>
        </div>
    </body>

    JSF HTML フォームコンポーネントをコメント解除すると、エディタに <h:form><h:commandButton> タグが宣言されていないことが表示されます。

  4. これらのコンポーネントを宣言するには、IDE のコード補完を使用して、タグライブラリ名前空間をページの <html> タグに追加します。

    エディタのコード補完サポートを使用して、必要な JSF 名前空間をファイルに追加します。コード補完を使用して JSF または Facelets タグを選択すると、必要な名前空間が自動的にドキュメントのルート要素に追加されます。詳細については、「NetBeans IDE での JSF 2.0 のサポート」を参照してください。

    宣言されていない任意のタグの上にカーソルを置き、Ctrl- スペースキーを押します。コード補完による候補とドキュメントサポートが表示されます。

    コード補完による候補とドキュメントのポップアップウィンドウ

    Enter キーを押します。(複数のオプションがある場合は、エディタに表示されているタグを選択してから Enter キーを押してください。)JSF HTML タグライブラリ名前空間が <html> タグ (次にボールドで表示) に追加され、エラー表示が消えます。

    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:h="http://java.sun.com/jsf/html">
  5. フォームボタンをクリックして呼び出された要求の宛先を指定します。ユーザーがボタンをクリックすると index ページに戻るように、ボタンを設定します。これを行うには、commandButtonaction 属性を使用します。ボールドで表示されているコードを入力します。
    <h:form>
    
        <h:commandButton id="backButton" value="Back" action="index" />
    
    </h:form>

    注:action="index"」と入力すると、JSF の暗黙的なナビゲーション機能に依存することになります。ユーザーがフォームボタンをクリックすると、JSF ランタイムは index という名前のファイルを検索します。JSF では、要求元のファイル (response.xhtml) で使用されているのと同じファイル拡張子であると想定し、元のファイルと同じディレクトリ内 (webroot など) で index.xhtml ファイルを探します。

  6. 静的テキスト「[ response here ]」を、UserNumberBeanresponse プロパティーの値で置き換えます。これを行うには、JSF 式言語を使用します。次のボールドで示すコードを入力します。
    <div id="left" class="subContainer greyBox">
    
        <h4><h:outputText value="#{UserNumberBean.response}"/></h4>
  7. プロジェクトを実行します。これを行うには、「プロジェクトを実行」(「プロジェクトを実行」ボタン) ボタンをクリックするか、F6 キー (Mac の場合は fn-F6) を押します。ブラウザに開始ページが表示されたら、数値を入力して「送信」をクリックします。次のような応答ページが表示されます (正しい数値を推測しなかった場合)。
    ブラウザに表示される応答ページ

    応答ページの現在の状態に、2 つの間違いがあります。

    1. Html <p> タグが、応答メッセージ内に表示されています。
    2. 「戻る」ボタンが正しい位置に表示されていません。(元のバージョンと比較。)

    次の 2 つの手順で、これらの間違いを修正します。

  8. <h:outputText> タグの escape 属性を false に設定します。カーソルを outputTextvalue の間に置き、スペースを挿入してから Ctrl- スペースキーを押して、コード補完を呼び出します。下にスクロールして escape 属性を選択し、ドキュメントを確認します。
    エディタに表示された、コード補完による候補およびドキュメント

    ドキュメントで示されるように、escape の値はデフォルトで true に設定されます。つまり、前出に示すように、通常は html として解析される文字がすべて文字列に含まれます。値を false に設定すると、html として解析できるすべての文字を、そのように描画できます。

    Enter キーを押し、値として「false」と入力します。

    <h4><h:outputText escape="false" value="#{UserNumberBean.response}"/></h4>
  9. <h:form> タグの prependId 属性を false に設定します。カーソルを <h:form> の「m」のすぐあとに置き、スペースを入力してから Ctrl- スペースキーを押して、コード補完を呼び出します。下にスクロールして prependId 属性を選択し、ドキュメントを確認します。次に Enter キーを押し、値として「false」と入力します。
    <h:form prependId="false">

    JSF は内部 ID を適用して、UI コンポーネントを追跡します。現在の例で、描画されたページのソースコードを調べると、次のように表示されます。

    <form id="j_idt5" name="j_idt5" method="post" action="/jsfDemo/faces/response.xhtml" enctype="application/x-www-form-urlencoded">
    <input type="hidden" name="j_idt5" value="j_idt5" />
        <input id="j_idt5:backButton" type="submit" name="j_idt5:backButton" value="Back" />
        <input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="7464469350430442643:-8628336969383888926" autocomplete="off" />
    </form>

    フォーム要素の ID は j_idt5 です。この ID は、フォームに含まれている「戻る」ボタンの ID に付加されます (ボールドで表示)。「戻る」ボタンは #backButton スタイル規則 (stylesheet.css で定義) に依存するため、JSF の ID が付加されると、この規則が妨げられます。これを回避するには、prependIdfalse に設定します。

  10. プロジェクトを再度実行します。「プロジェクトを実行」(「プロジェクトを実行」ボタン) ボタンをクリックするか、F6 キー (Mac の場合は fn-F6) を押します。開始ページに数値を入力し、「送信」をクリックします。応答ページに <p> タグのない応答メッセージが表示され、「戻る」ボタンが正しい位置に配置されます。
    ブラウザに表示される応答ページ
  11. 「戻る」ボタンをクリックします。UserNumberBeanuserNumer プロパティーの現在の値は JSF inputText コンポーネントにバインドされているため、前に入力した数値がテキストフィールドに表示されます。
  12. IDE の「出力」ウィンドウでサーバーログを確認し (Ctrl-4、Mac の場合は &#8984-4)、正しい推測値を判断します。

    何らかの理由でサーバーログが表示されない場合は、「サービス」ウィンドウに切り替え (Ctrl-5、Mac の場合は &#8984-5)、「サーバー」ノードを展開します。次に、プロジェクトが配備されている GlassFish サーバーを右クリックし、「サーバーログを表示」を選択します。サーバーログに数値が見つけることができない場合は、プロジェクトノードを右クリックし、「生成物を削除して構築」を選択して、アプリケーションを再構築してみてください。

  13. 正しい数値を入力し、「送信」をクリックします。アプリケーションは、入力された数値を現在保存されている数値と比較し、適切なメッセージを表示します。
    ブラウザに表示された応答ページ
  14. 「戻る」ボタンをもう一度クリックします。前に入力した数値はテキストフィールドに表示されていません。UserNumberBeangetResponse() メソッドは、正しい数値が推測されると現在のユーザーセッションを無効にします

Facelets テンプレートの適用

Facelets は、JSF 2.0 の標準の表示テクノロジになりました。Facelets は、すべての JSF UI コンポーネントをサポートする軽量テンプレート作成フレームワークで、アプリケーションビュー用の JSF コンポーネントツリーを構築および描画するのに使用されます。また、ユーザーがスタックトレース、コンポーネントツリー、およびスコープ指定された変数を確認できるようにすることで、EL エラー発生時の開発サポートを提供します。

チュートリアルでこれまでに操作してきた index.xhtml および response.xhtml ファイルは、Facelets ページです。Facelets ページでは .xhtml 拡張子が使用されます。また、JSF 2.0 プロジェクトで作業しているため (JSF 2.0 ライブラリには Facelets JAR ファイルが含まれる)、JSF コンポーネントツリーを適切に描画することができました。

この節は、Facelets のテンプレート作成に慣れることを目的としています。多くのビューを含むプロジェクトの場合、複数のビューの構造および外観を定義するテンプレートファイルを適用すると便利なことがよくあります。アプリケーションでは、要求を処理するときに、動的に用意されたコンテンツをテンプレートファイルに挿入し、それをクライアントに送り返します。このプロジェクトには 2 つのビュー (開始ページと応答ページ) しか含まれていませんが、これらのビューには重複するコンテンツが多数含まれています。重複するコンテンツを Facelets テンプレートにまとめて、テンプレートクライアントファイルを作成し、開始ページと応答ページに固有のコンテンツを処理することができます。

IDE には、Facelets テンプレートを作成するための 「Facelets テンプレート」ウィザードと、テンプレートに依存するファイルを作成するための「Facelets テンプレートクライアント」ウィザードが用意されています。この節では、これらのウィザードを使用します。

注: IDE には、プロジェクト用に個々の Facelets ページを作成するための、「JSF ページ」ウィザードも用意されています。詳細については、「NetBeans IDE での JSF 2.0 のサポート」を参照してください。

Facelets テンプレートファイルの作成

  1. Facelets テンプレートファイルを作成します。Ctrl-N キー (Mac の場合は &#8984-N) を押して、「ファイル」ウィザードを開きます。「JavaServer Faces」カテゴリを選択し、「Facelets テンプレート」を選択します。「次へ」をクリックします。
  2. ファイル名として「template」と入力します。
  3. 8 つのレイアウトスタイルから任意のスタイルを選択し、「完了」をクリックします。(既存のスタイルシートを使用するので、どのレイアウトスタイルを選択してもかまいません。)
    「Facelets テンプレート」ウィザードに示されるレイアウトスタイル
    ウィザードで、選択に基づいて template.xhtml ファイルおよび付属するスタイルシートが生成され、プロジェクトの webroot 内の「resources」>「css」フォルダに置かれます。

    ウィザードが完了すると、テンプレートファイルがエディタに開かれます。ブラウザでこのテンプレートを表示するには、エディタ内を右クリックし、「表示」を選択します。

  4. テンプレートファイルのマークアップを確認します。次の点を確認します。
    • facelets タグライブラリがページの <html> タグ内で宣言されています。タグライブラリに接頭辞 ui があります。
      <html xmlns="http://www.w3.org/1999/xhtml"
            xmlns:ui="http://java.sun.com/jsf/facelets"
            xmlns:h="http://java.sun.com/jsf/html">
    • Facelets ページで、html の <head> および <body> タグではなく、<h:head> および <h:body> タグが使用されています。Facelets は、これらのタグを使用することによって、ページ全体にわたるコンポーネントツリーを構築できます。
    • ページは、ウィザードの完了時に作成されたスタイルシートを参照します。
      <h:head>
          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
          <link href="./resources/css/default.css" rel="stylesheet" type="text/css" />
          <link href="./resources/css/cssLayout.css" rel="stylesheet" type="text/css" />
          <title>Facelets Template</title>
      </h:head>
    • <ui:insert> タグは、選択したレイアウトスタイルに関連付けられているすべての区画のページ本体で使用されます。それぞれの <ui:insert> タグには、区画を識別する name 属性があります。例:
      <div id="top">
          <ui:insert name="top">Top</ui:insert>
      </div>
  5. 開始ページと応答ページを再度確認します。2 つのページ間で異なるコンテンツは、グレーの四角形の中にあるタイトルとテキストだけです。そのため、テンプレートで残りのすべてのコンテンツを提供できます。
  6. テンプレートファイルのすべてのコンテンツを、次のコンテンツに置き換えます。
    <?xml version='1.0' encoding='UTF-8' ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:h="http://java.sun.com/jsf/html">
    
        <h:head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <link href="css/stylesheet.css" rel="stylesheet" type="text/css" />
    
            <title><ui:insert name="title">Facelets Template</ui:insert></title>
        </h:head>
    
        <h:body>
    
            <div id="left">
                <ui:insert name="box">Box Content Here</ui:insert>
            </div>
    
        </h:body>
    
    </html>
    このコードによって、次の変更が実装されます。
    • プロジェクトの stylesheet.css ファイルによって、ウィザードで作成されたテンプレートスタイルシート参照が置き換えられます。
    • <ui:insert> タグ (およびそれらに含まれる <div> タグ) が、box という名前のものを除き、すべて削除されます。
    • ページタイトルを囲んで <ui:insert> タグペアが配置され、title という名前が付けられています。
  7. 該当するコードを、index.xhtml または response.xhtml ファイルからテンプレートにコピーします。次にボールドで示されているコンテンツを、テンプレートファイルの <h:body> タグに追加します。
    <h:body>
        <div id="mainContainer">
            <div id="left" class="subContainer greyBox">
                <ui:insert name="box">Box Content Here</ui:insert>
            </div>
            <div id="right" class="subContainer">
                <img src="duke.png" alt="Duke waving" />
            </div>
        </div>
    </h:body>
  8. プロジェクトを実行します。ブラウザで開始ページが開いたら、URL を次のように変更します。
    http://localhost:8080/jsfDemo/faces/template.xhtml
    テンプレートファイルが次のように表示されます。
    ブラウザに表示された Facelets テンプレート

これで、プロジェクトには、すべてのビューの外観と構造を定義するテンプレートファイルが作成されました。ここで、テンプレートを呼び出すクライアントファイルを作成できます。

テンプレートクライアントファイルの作成

開始ページおよび応答ページ用のテンプレートクライアントファイルを作成します。開始ページのテンプレートクライアントファイルには、greeting.xhtml という名前を付けます。応答ページのファイルには、response.xhtml という名前を付けます。

greeting.xhtml

  1. Ctrl-N キー (Mac の場合は ⌘-N) を押して、「新規ファイル」ウィザードを開きます。「JavaServer Faces」カテゴリを選択し、「Facelets テンプレートクライアント」を選択します。「次へ」をクリックします。
  2. ファイル名として「greeting」と入力します。
  3. 「テンプレート」フィールドの横にある「参照」ボタンをクリックし、表示されたダイアログを使用して、前の節で作成した template.xhtml ファイルに移動します。
    「Facelets テンプレートクライアント」ウィザード
  4. 「完了」をクリックします。新しいテンプレートクライアントファイル greeting.xhtml が生成され、エディタに表示されます。
  5. マークアップを確認します。ボールドで強調表示されているコンテンツを確認してください。
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:ui="http://java.sun.com/jsf/facelets">
    
        <body>
    
            <ui:composition template="./template.xhtml">
    
                <ui:define name="title">
                    title
                </ui:define>
    
                <ui:define name="box">
                    box
                </ui:define>
    
            </ui:composition>
    
        </body>
    </html>
    テンプレートクライアントファイルは、<ui:composition> タグの template 属性を使用して、テンプレートを参照します。テンプレートには title および box<ui:insert> タグが含まれているため、このテンプレートクライアントには、これらの 2 つの名前の <ui:define> タグが含まれます。<ui:define> タグの間で指定するコンテンツは、テンプレートの対応する名前の <ui:insert> タグの間に挿入されるコンテンツです。
  6. ファイルのタイトルとして「greeting」を指定します。次にボールドで示す変更を加えます。
    <ui:define name="title">
        Greeting
    </ui:define>
  7. index.xhtml ファイルに切り替え (Ctrl-Tab キー)、表示されるページで、通常はグレーの四角形内に表示されるコンテンツをコピーします。greeting.xhtml に切り替え、テンプレートクライアントファイルにペーストします。変更場所はボールドで示されています。
    <ui:define name="box">
        <h4>Hi, my name is Duke!</h4>
    
        <h5>I'm thinking of a number
    
            <br/>
            between
            <span class="highlight">0</span> and
            <span class="highlight">10</span>.</h5>
    
        <h5>Can you guess it?</h5>
    
        <h:form>
            <h:inputText size="2" maxlength="2" value="#{UserNumberBean.userNumber}" />
            <h:commandButton id="submit" value="submit" action="response" />
        </h:form>
    </ui:define>
  8. ファイルの JSF HTML タグライブラリを宣言します。エラーのフラグが付いているタグ (接頭辞が「h」のタグ) にカーソルを置き、Ctrl- スペースキーを押します。コード補完による候補の一覧から、タグを選択します。タグライブラリ名前空間がファイルの <html> タグ (ボールドで表示) に追加され、エラー表示が消えます。
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:h="http://java.sun.com/jsf/html">

    <h:form> の「m」のあとにカーソルを置き、Ctrl- スペースキーを押すと、名前空間が自動的にファイルに追加されます。Ctrl- スペースキーを押したときに使用可能な論理オプションが 1 つだけの場合は、それがすぐにファイルに適用されます。タグ上でコード補完を呼び出すときに、JSF タグライブラリが自動的に宣言されます。

response.xhtml

プロジェクトには response.xhtml という名前のファイルがすでに含まれており、テンプレートクライアントファイルの内容もわかっているので、既存の response.xhtml を修正して、テンプレートクライアントファイルにします。(このチュートリアルでは、提供されているコードをコピーしてペーストします。)

  1. エディタで response.xhtml を開きます。(すでに開かれている場合は、Ctrl-Tab キーを押して選択します。)ファイル全体のコンテンツを、次のコードで置き換えます。
    <?xml version='1.0' encoding='UTF-8' ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:h="http://java.sun.com/jsf/html">
    
        <body>
    
            <ui:composition template="./template.xhtml">
    
                <ui:define name="title">
                    Response
                </ui:define>
    
                <ui:define name="box">
                    <h4><h:outputText escape="false" value="#{UserNumberBean.response}"/></h4>
    
                    <h:form prependId="false">
    
                        <h:commandButton id="backButton" value="Back" action="greeting" />
    
                    </h:form>
                </ui:define>
    
            </ui:composition>
    
        </body>
    </html>
    title および box<ui:define> タグ間で指定されているコンテンツを除き、ファイルは greeting.xhtml と同じになります。
  2. プロジェクトの web.xml 配備記述子で、アプリケーションを実行したときに greeting.xhtml ページが開かれるように、開始ファイルのエントリを変更します。

    「プロジェクト」ウィンドウで「構成ファイル」>「web.xml」をダブルクリックして、エディタで開きます。「ページ」タブで「開始ファイル」フィールドを「faces/greeting.xhtml」に変更します。
    配備記述子インタフェース
  3. プロジェクトを実行して、ブラウザでどのように表示されるかを確認します。F6 キー (Mac の場合は fn-F6) を押すか、メインツールバーの「プロジェクトを実行」(「プロジェクトを実行」ボタン) ボタンをクリックします。プロジェクトが GlassFish サーバーに配備され、ブラウザで開かれます。

Facelets テンプレートおよびテンプレートクライアントファイルを使用して、アプリケーションは以前とまったく同じように動作します。アプリケーションの開始ページと応答ページで重複しているコードを取り除くことによって、アプリケーションのサイズを小さくするとともに、あとでページが追加されたときに重複したコードを記述することがなくなりました。これにより、大規模なプロジェクトで作業するときに、開発作業が効率化され、管理が容易になります。


関連項目

JSF 2.0 の詳細については、次のリソースを参照してください。