JSF(2) ナビゲーション(ページ遷移)

次に、JSF 1.1でページ間遷移を行う手順です。以下のサンプルは2つのJSPページからなり、 最初のページで自分の名前を入力すると、次のページに移り、自分への挨拶が表示されます。
●hellomsg1.jsp

<%@ page contentType="text/html;charset=Windows-31J" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<html>
<body>
<f:view>
<h:form>
お名前:
  <h:inputText value="#{UserName.name}">
    <f:validateLength minimum="4"/>
  </h:inputText>
<h:commandButton value="OK" action="success"/>
</h:form>
</f:view>
</body>
</html>


●hellomsg2.jsp

<%@ page contentType="text/html;charset=Windows-31J" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<html>
<body>
<f:view>
<h:form>
<h:outputText value="#{UserName.greeting}"/>
<br/>
<h:commandButton value="前のページに戻る" action="success"/>
</h:form>
</f:view>
</body>
</html>

名前を保存するBeanはUserNameBeanと名づけ、nameプロパティの他に、 挨拶のメッセージを返すgreetingというRead Onlyプロパティを持ちます。
●UserNameBean.java

package jsfcl01.beans;

import java.io.Serializable;
import java.util.Calendar;

public class UserNameBean implements Serializable {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGreeting() {
        Calendar cal = Calendar.getInstance();
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        if (hour >= 6 && hour <= 9) {
            return "おはようございます、" + name + "さん。";
        } else if (hour >= 10 && hour <= 17) {
            return "こんにちは、" + name + "さん。";
        } else if (hour >= 18 && hour <= 23) {
            return "こんばんは、" + name + "さん。";
        } else {
            return "眠くないですか、" + name + "さん。";
        }
    }

    public String check(){
        return (name.equals("admin") ? "admin" : "normal");
    }
}

faces-config.xmlです。 from-view-idが遷移元のページ、 to-view-idが遷移先のページのURLで、コンテキスト・ルートからの相対パスで指定しますが、 パスはスラッシュ(/)から始まります。 from-outcomeはその遷移を起こすアクションの名前です。この例では、 JSPのh:commandButtonタグのaction=で"success"としているので、これがfrom-outcomeになります。

<faces-config>

  <navigation-rule>
    <from-view-id>/hellomsg/hellomsg1.jsp</from-view-id>
    <navigation-case>
      <from-outcome>success</from-outcome>
      <to-view-id>/hellomsg/hellomsg2.jsp</to-view-id>
    </navigation-case>
  </navigation-rule>
  <navigation-rule>
    <from-view-id>/hellomsg/hellomsg2.jsp</from-view-id>
    <navigation-case>
      <from-outcome>success</from-outcome>
      <to-view-id>/hellomsg/hellomsg1.jsp</to-view-id>
    </navigation-case>
  </navigation-rule>

  <managed-bean>
    <managed-bean-name>UserName</managed-bean-name>
    <managed-bean-class>jsfcl01.beans.UserNameBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
  </managed-bean>
</faces-config>

なお、from-view-idにワイルドカード(*など)を使うこともできます。 from-view-idを*に指定すると、Strutsでいうglobal-forwards のような設定にすることができます。


条件分岐するページ遷移

常に同じページに遷移するのではなく、 Javaコードの実行結果によって、遷移するページを変えることもできます。 以下のサンプルは、名前として"admin"を入力すると管理者用のページに、 その他を入力すると通常のページに遷移します。 Backing Beanは前の例のUserNameBeanと同じです。 というか、前の例では最後のメソッドcheck()の出番はなかったのですが、今度はこれを使います。
●hellomsg3.jsp

<%@ page contentType="text/html;charset=Windows-31J" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<html>
<body>
<f:view>
<h:form>
お名前:
  <h:inputText id="aaa" value="#{UserName.name}">
    <f:validateLength minimum="4"/>
  </h:inputText>
<h:commandButton value="OK" action="#{UserName.check}"/>
<br/>
<h:message for="aaa"/>
</h:form>
</f:view>
</body>
</html>

h:commandButtonのaction属性が式になっています。 これすなわち、UserNameBeanのcheck()の実行結果がアクションの名称になるという意味で、 これはfaces-config.xmlのfrom-actionにも全く同じように書きます。
●hellomsg4_normal.jsp

<%@ page contentType="text/html;charset=Windows-31J" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<html>
<body>
<f:view>
<h:form>
<h:outputText value="#{UserName.greeting}"/>
<br/>
通常ユーザ用のページです。
<br/>
<h:commandButton value="前のページに戻る" action="success"/>
</h:form>
</f:view>
</body>
</html>


●hellomsg4_admin.jsp

<%@ page contentType="text/html;charset=Windows-31J" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<html>
<body>
<f:view>
<h:form>
<h:outputText value="#{UserName.greeting}"/>
<br/>
管理者ユーザ用のページです。
<br/>
<h:commandButton value="前のページに戻る" action="success"/>
</h:form>
</f:view>
</body>
</html>

そしてfaces-config.xmlです。 DTDがこの順番になっている?のか、ちょっと順番がわかりづらいですが、 from-actionで指定した式の実行結果が、from-outcomeの値に等しい場合、 to-view-idに書いたURLへの遷移が発生します。

<faces-config>
  <navigation-rule>
    <from-view-id>/hellomsg/hellomsg3.jsp</from-view-id>
    <navigation-case>
      <from-outcome>normal</from-outcome>
      <from-action>#{UserName.check}</from-action>
      <to-view-id>/hellomsg/hellomsg4_normal.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
      <from-outcome>admin</from-outcome>
      <from-action>#{UserName.check}</from-action>
      <to-view-id>/hellomsg/hellomsg4_admin.jsp</to-view-id>
    </navigation-case>
  </navigation-rule>
  <navigation-rule>
    <from-view-id>/hellomsg/hellomsg4_normal.jsp</from-view-id>
    <navigation-case>
      <from-outcome>success</from-outcome>
      <to-view-id>/hellomsg/hellomsg3.jsp</to-view-id>
    </navigation-case>
  </navigation-rule>
  <navigation-rule>
    <from-view-id>/hellomsg/hellomsg4_admin.jsp</from-view-id>
    <navigation-case>
      <from-outcome>success</from-outcome>
      <to-view-id>/hellomsg/hellomsg3.jsp</to-view-id>
    </navigation-case>
  </navigation-rule>


バリデーションについて少しだけ…

バリデーションの記述方法は、Strutsがvalidation.xmlに独立して書くのに対し、 JSFでは評価を行うJSPのタグの中に直接書きます。 組み込みで数個のバリデータが提供されていますが、 それらは入力された数値の値の範囲をチェックするものと、 入力された文字列の長さをチェックするもの、という簡単なラインアップです。 上の例では、 f:validateLength というバリデータを使っており、この設定では、名前として4文字以上入力しないとエラーになり、 (エラー処理方法は1文字も書いていないのでデフォルトの動作ですが)同じページが再描画されます。 そのとき、 「h:message for="フォーム要素のID"」というタグを書いておくと、 その位置に、対応するフォーム要素の入力に対してエラーがあった場合には、 エラーメッセージが表示されます。このエラーメッセージも組み込みのものです。
このページの先頭のサンプルでは、バリデータを書いているのに、 エラー時に何も表示されないのは、単にh:messageタグを書いていないためです。

Server Side Java Index Top

(first uploaded 2004/11/06 last updated 2006/03/15, URANO398)

テレワークならECナビ Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!
無料ホームページ 無料のクレジットカード 海外格安航空券 海外旅行保険が無料! 海外ホテル