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

自定義 Taglib 與 JSTL 協作實戰:EL 表達式互通的最佳實踐

     編輯:Java 相關知識

核心需求:自定義標籤處理邏輯,JSTL 負責輸出

在 JSP 開發中,常見模式是:自定義標籤處理複雜業務邏輯(如權限計算、資料轉換),將結果放入請求屬性,再由 JSTL 標籤(<c:out>、<c:forEach> 等)配合 EL 表達式完成顯示。關鍵在於:如何讓自定義標籤產出的資料被 EL 正確識別?

最小可行範例:從 Request 取物件、取屬性、存回 Request

1. JSP 頁面佈局

<%@ taglib uri="/WEB-INF/tlds/diego.tld" prefix="diego" %>
<%@ taglib uri="/WEB-INF/tlds/c.tld" prefix="c" %>

<% 
    Man man = new Man(); man.setName("diego");
    request.setAttribute("man", man);
%>

<!-- 自定義標籤:取得 man 物件的 name 屬性,存入 myname -->
<diego:set value="${man}" property="name" var="myname" />

<!-- JSTL 輸出結果 -->
value is : <c:out value="${myname}" />

輸出結果:value is : diego

2. 標籤處理類:SetVarTag

package diegoyun;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;

public class SetVarTag extends TagSupport {
    private Object value;
    private String property;
    private String var;

    // setter 方法對應 TLD 屬性定義
    public void setValue(Object value) throws JspException {
        // 關鍵:支援 EL 表達式動態求值
        this.value = ExpressionEvaluatorManager.evaluate(
            "value", value.toString(), Object.class, this, pageContext);
    }
    public void setProperty(String property) { this.property = property; }
    public void setVar(String var) { this.var = var; }

    public int doEndTag() throws JspException {
        try {
            // 1. 利用 BeanUtils 取得巢狀屬性值
            Object propertyValue = PropertyUtils.getProperty(value, property);
            // 2. 存入 pageContext(請求範圍),供後續 EL 存取
            pageContext.setAttribute(var, propertyValue);
        } catch (Exception e) {
            throw new JspException(e);
        }
        return EVAL_PAGE;
    }
}

3. TLD 定義:/WEB-INF/tlds/diego.tld

<tag>
    <name>set</name>
    <tag-class>diegoyun.SetVarTag</tag-class>
    <body-content>empty</body-content>
    
    <attribute>
        <name>value</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>  <!-- 支援 EL 運算式 -->
    </attribute>
    <attribute>
        <name>property</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
        <name>var</name>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
</tag>

關鍵技術點解析

EL 表達式求值機制

ExpressionEvaluatorManager.evaluate() 是 JSTL 內部工具類,負責將字串形式的 EL 表達式(如 "${man}")在當前 pageContext 中解析為實際物件。這是自定義標籤支援 EL 的核心橋樑。

屬性存取與作用域

pageContext.setAttribute(var, value) 預設存入 PageScope,但 EL 表達式 ${myname} 會依序搜尋 Page → Request → Session → Application 範圍,因此能被 <c:out> 正確找到。

PropertyUtils 靈活取值

支援巢狀屬性路徑(如 "address.city.name")、Map 鍵值、List 索引等,極大擴展了標籤適用場景。

進階應用模式

  • 集合轉換標籤:將 List<User> 轉為 List<String>(只取名字),供 <c:forEach> 直接迭代。
  • 條件邏輯封裝:複雜權限判斷在標籤內完成,輸出 boolean 供 <c:if> 使用。
  • 分頁工具標籤:輸入總筆數、頁大小,輸出分頁導航 HTML 片段或資料結構。

最佳實踐總結

  1. 職責單一:自定義標籤只做「資料準備/邏輯運算」,JSTL 只做「流程控制/輸出格式化」。
  2. EL 友善:所有對外輸出屬性必須支援 rtexprvalue="true" 並正確求值。
  3. 作用域最小化:優先用 pageContext.setAttribute(PageScope),避免汙染 Request/Session。
  4. 異常轉換:捕獲底層異常包裝為 JspException,確保 JSP 編譯期/執行期錯誤可被容器統一處理。

遵循此模式,團隊可將「業務邏輯」與「視圖渲染」徹底解耦,Java 開發者專注標籤開發,頁面設計師專注 JSTL+EL 模板編寫,極大提升協作效率與代碼復用率。

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