首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JSF 導航規則完整指南:從基礎配置到進階模式匹配

     編輯:Java 相關知識

配置入口:多文件模組化管理

JSF 導航規則定義於 faces-config.xml,支援模組化拆分。在 web.xml 中聲明多配置文件:

<context-param>
    <param-name>javax.faces.CONFIG_FILES</param-name>
    <param-value>/WEB-INF/faces-config.xml,/WEB-INF/faces-beans.xml</param-value>
</context-param>

載入順序決定規則優先級:後載入文件的同名規則覆蓋先載入者。

導航規則核心結構

<navigation-rule>
    <from-view-id>/pages/inputname.jsp</from-view-id>
    <navigation-case>
        <from-outcome>sayHello</from-outcome>
        <to-view-id>/pages/greeting.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-outcome>sayGoodbye</from-outcome>
        <to-view-id>/pages/goodbye.jsp</to-view-id>
    </navigation-case>
</navigation-rule>

三要素:來源視圖、結果碼、目標視圖。

進階規則變體

1. 默認結果碼(通配符結果)

<navigation-case>
    <from-outcome>sayHello</from-outcome>
    <to-view-id>/pages/greeting.jsp</to-view-id>
</navigation-case>
<navigation-case>
    <!-- 缺少 from-outcome,匹配所有非 sayHello 的結果 -->
    <to-view-id>/pages/goodbye.jsp</to-view-id>
</navigation-case>

2. 視圖模式匹配(路徑前綴通配)

<navigation-rule>
    <from-view-id>/pages/*</from-view-id>
    <navigation-case>
        <from-outcome>menu</from-outcome>
        <to-view-id>/menu/main_main.jsp</to-view-id>
    </navigation-case>
</navigation-rule>

限制:* 必須位於字串末尾,/pages/*.jsp 為非法模式。

3. 全域結果碼(跨視圖跳轉)

<!-- 寫法一:顯式 * -->
<navigation-rule>
    <from-view-id>*</from-view-id>
    <navigation-case>
        <from-outcome>globalHelp</from-outcome>
        <to-view-id>/help/index.html</to-view-id>
    </navigation-case>
</navigation-rule>

<!-- 寫法二:省略 from-view-id -->
<navigation-rule>
    <navigation-case>
        <from-outcome>globalHelp</from-outcome>
        <to-view-id>/help/index.html</to-view-id>
    </navigation-case>
</navigation-rule>

陷阱:<from-view-id></from-view-id>(空元素)不生效,等同於無規則。

規則衝突解決機制

  1. 具體優先於通用:/pages/login.jsp 精確匹配優先於 /pages/* 模式匹配。
  2. 後載入覆蓋先載入:多文件衝突時,web.xml 列表中靠後文件勝出。
  3. 同文件最後定義勝出:同一 from-view-id + from-outcome 重複,最後一條生效。

規則拆分與重組

單一 navigation-rule 可拆分為多個片段分散在文件各處甚至跨文件,運行時自動合併。建議:

  • 按功能模組拆分文件(如 faces-nav-admin.xml、faces-nav-user.xml)
  • 同一視圖的規則集中在單一 navigation-rule 內,利於維護

Action 綁定與 from-action 精準控制

兩種 Action 寫法

<!-- 靜態結果碼 -->
<h:commandButton action="sayHello" value="Submit" />

<!-- 動態結果碼:調用 Bean 方法返回字串 -->
<h:commandButton action="#{GetNameBean.helloAction}" value="Submit" />

from-action 區分同結果碼不同來源

<navigation-rule>
    <from-view-id>/pages/inputname.jsp</from-view-id>
    <navigation-case>
        <from-outcome>sayHello</from-outcome>
        <to-view-id>/pages/anotherhello.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-outcome>sayHello</from-outcome>
        <from-action>#{GetNameBean.helloAction}</from-action>
        <to-view-id>/pages/hello.jsp</to-view-id>
    </navigation-case>
</navigation-rule>

若 sayHello 由 GetNameBean.helloAction 產生,命中第二條;否則命中第一條。實現「同結果碼、不同業務來源、不同跳轉目標」的精準路由。

思考題解析

<h:commandButton action="#{GetNameBean.helloAction}" />

<navigation-rule>
    <from-view-id>/pages/inputname.jsp</from-view-id>
    <navigation-case>
        <from-outcome>sayHello</from-outcome>
        <to-view-id>/a.jsp</to-view-id>
    </navigation-case>
</navigation-rule>
<navigation-rule>
    <from-view-id>/pages/*</from-view-id>
    <navigation-case>
        <from-outcome>#{GetNameBean.helloAction}</from-outcome>
        <to-view-id>/b.jsp</to-view-id>
    </navigation-case>
</navigation-rule>

答案:跳轉至 /b.jsp。原因:第二條規則的 from-outcome 為 EL 表達式 #{GetNameBean.helloAction},若 Bean 方法返回 "sayHello",則 from-outcome 匹配 "sayHello";同時 from-view-id 模式 /pages/* 匹配 /pages/inputname.jsp。雖然第一條規則精確匹配視圖,但第二條規則同時匹配 from-outcome(動態值)與 from-view-id(模式),且載入順序靠後(或同文件後定義),依「具體優先、後載入勝出」原則生效。

最佳實踐清單

  • 統一使用 from-action 綁定 Bean 方法,避免魔術字串散落頁面
  • 全域導航(如登出、錯誤頁)用省略 from-view-id 寫法
  • 模式匹配僅用於目錄級通用導航(如選單、幫助)
  • 配置文件按模組拆分,web.xml 載入順序:通用規則在前,業務覆蓋規則在後
  • 開發階段開啟 javax.faces.FACELETS_REFRESH_PERIOD 熱加載驗證規則即時生效
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved