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

JSF 與 JSTL 標籤混合使用最佳實踐:共存、嵌套與數據共享

     編輯:J2EE

核心結論

JSF 標籤與 JSTL (及其他自定義標籤) 大程度可混合使用。JSF <f:view> 定義組件樹根節點,內部可嵌套 JSTL 標籤;反之 JSTL 結構中亦可嵌套 JSF 組件。工具廠商態度:IBM 勸勉混合,Sun Creator 偏純 JSF,Oracle JDeveloper 允許混合但勸純 JSF。

關鍵規則:組件 ID 強制要求

當 JSF 標籤嵌套在非 JSF 自定義標籤內時,必須為 JSF 標籤指定 id 屬性,以確保組件樹正確構建與狀態保存。

實戰示例一:基礎混合與 <f:verbatim> 包裝 XML/HTML 片段

<%@ taglib uri="https://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="https://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="https://java.sun.com/jstl/core" prefix="c" %>
<f:view>
  <h1><h:outputText value="Example of using JSF tags with other custom tags" /></h1>
  <p><b><c:out value="Here's the value of your web.xml (don't do this at home):" /></b></p>
  <blockquote>
    <f:verbatim>
      <c:import url="WEB-INF/web.xml" />
    </f:verbatim>
  </blockquote>
</f:view>

關鍵點解析

  • <c:import> 引入 XML 文件,輸出包含標記字符,必須包裹在 <f:verbatim> 中,否則 JSF 渲染器會嘗試解析導致異常或輸出錯亂。
  • <f:verbatim> 是 UIOutput 組件,負責轉義輸出模板文本,確保 XML/HTML 片段在頁面原樣呈現。
  • 任何擁有子組件的組件 (HtmlDataTable, HtmlPanelGrid 等) 內部的模板文本同樣需用 <f:verbatim> 包裹。

實戰示例二:JSF 輸入與 JSTL 邏輯共享 Backing Bean 數據

<f:view>
  <jsp:useBean class="org.jia.examples.TestForm" id="exampleBean" scope="session" />
  <h1><h:outputText value="Example of using JSF and JSTL expression languages" /></h1>
  <h:form>
    <h:outputLabel for="inputInt">
      <h:outputText value="How many times do you want to repeat the Oracle's prophecy?" />
    </h:outputLabel>
    <h:inputText id="inputInt" value="#{sessionScope.exampleBean.number}" />
    <h:commandButton value="Go!" />
  </h:form>
  <p>
    <c:if test="${sessionScope.exampleBean.number > 0}">
      <c:forEach begin="0" end="${sessionScope.exampleBean.number - 1}" var="count">
        Queen Tracey will achieve world domination.<br/>
      </c:forEach>
    </c:if>
  </p>
</f:view>

數據共享機制深度解析

層面JSF EL (#{...})JSTL EL (${...})
求值時機延遲求值 (Deferred) - 生命週期各階段按需求值即時求值 (Immediate) - 頁面編譯/渲染時求值
讀寫性可讀可寫 (ValueExpression 支援 setValue)僅讀 (ValueExpression 僅 getValue)
作用域引用#{sessionScope.bean.prop}${sessionScope.bean.prop}
共享前提Backing Bean 需註冊為 Managed Bean 或 <jsp:useBean> 放入作用域同樣從作用域 Map 獲取

示例中 <jsp:useBean> 將 TestForm 實例放入 Session (exampleBean),JSF <h:inputText> 雙向綁定 #{sessionScope.exampleBean.number},JSTL <c:if/forEach> 讀取同一屬性 ${sessionScope.exampleBean.number} 進行邏輯判斷與迭代,實現單一數據源、雙框架無縫協作。

進階建議與避坑指南

  1. 優先考慮 Facelets (JSF 2.0+): Facelets 原生支援 JSTL 標籤 (編譯期執行 c:*,運行期執行 ui:*/f:*/h:*),消除 JSP 混合模式的生命週期時序衝突,獲得更好模板復用與類型安全。
  2. 避免在 <c:forEach> 中動態生成 JSF 組件: JSTL 執行於視圖構建期,JSF 組件樹構建於渲染期,易導致組件 ID 衝突、狀態丟失、AJAX 失效。改用 <ui:repeat> / <h:dataTable> 等 JSF 原生迭代組件。
  3. 表達式語言統一: JSP 2.1+ 統一 EL (javax.el),JSF 2.0+ 強制使用統一 EL,消除 #{} 與 ${} 語義差異,但求值時機差異 (延遲/即時) 依然存在,需清晰理解。
  4. 工具支援: NetBeans 對 JSF+JSTL 混合編輯支援較好;Eclipse WTP 需配置項目 Facet 正確識別雙標籤庫。

總結

JSF + JSTL 混合是過渡期實用技術,核心在於 作用域共享 JavaBean + <f:verbatim> 包裝非組件文本 + 理解 EL 求值時機差異。新架構請拥抱 Facelets + 統一 EL + 純 JSF 組件樹,將邏輯下沉至 Backing Bean,視圖層純宣告式渲染。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved