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

JSP 自定義標籤庫 (Taglib) 完整開發指南:從無屬性到迭代、EL 函數、TLD 配置與實戰案例

     編輯:Java 綜合教學

一、標籤處理類基礎

所有標籤類需繼承 TagSupport (無 Body 互動) 或 BodyTagSupport (需讀取/修改 Body 內容)。核心方法:

  • doStartTag():遇到起始標籤,返回 EVAL_BODY_INCLUDE (處理 Body) 或 SKIP_BODY (跳過)。
  • doEndTag():遇到結束標籤,返回 EVAL_PAGE (繼續) 或 SKIP_PAGE (停止頁面)。
  • doAfterBody():Body 內容處理後調用,返回 EVAL_BODY_AGAIN (迭代) 或 SKIP_BODY。

二、無屬性標籤範例

public class HelloWorldTag extends TagSupport {
    @Override
    public int doEndTag() throws JspException {
        try { pageContext.getOut().write("Hello World!"); }
        catch (IOException e) { throw new JspException(e); }
        return EVAL_PAGE;
    }
}

三、TLD 檔案配置 (tag.tld)

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" xmlns="https://java.sun.com/xml/ns/j2ee">
    <tlib-version>1.0</tlib-version>
    <short-name>myTags</short-name>
    <uri>/myTags</uri>

    <tag>
        <name>helloWorld</name>
        <tag-class>org.lxh.taglib.HelloWorldTag</tag-class>
        <body-content>empty</body-content>
    </tag>

    <tag>
        <name>field</name>
        <tag-class>com.able.tag.FieldTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>field</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>count</name>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

    <tag>
        <name>forEach</name>
        <tag-class>exercise.taglib.ForEach</tag-class>
        <body-content>JSP</body-content>
        <attribute><name>id</name><required>true</required><rtexprvalue>true</rtexprvalue></attribute>
        <attribute><name>collection</name><required>true</required><rtexprvalue>true</rtexprvalue></attribute>
    </tag>

    <tag>
        <name>getProperty</name>
        <tag-class>exercise.taglib.GetProperty</tag-class>
        <body-content>empty</body-content>
        <attribute><name>name</name><required>true</required><rtexprvalue>true</rtexprvalue></attribute>
        <attribute><name>property</name><required>true</required><rtexprvalue>true</rtexprvalue></attribute>
    </tag>

    <function>
        <name>add</name>
        <function-class>exercise.taglib.ELFunction</function-class>
        <function-signature>int add(int, int)</function-signature>
    </function>
</taglib>

四、web.xml 註冊 (可選,Servlet 2.4+ 可自動掃描)

<jsp-config>
    <taglib>
        <taglib-uri>/myTags</taglib-uri>
        <taglib-location>/WEB-INF/tag.tld</taglib-location>
    </taglib>
</jsp-config>

五、JSP 頁面使用

<%@ taglib uri="/myTags" prefix="my" %>
<my:helloWorld />
<my:field field="姓名" count="10" />

<%-- 迭代標籤 --%>
<%@ page import="java.util.*" %>
<jsp:useBean id="voList" class="java.util.ArrayList" scope="request" />
<%
    voList.add(new UserVo("Alice", "123"));
    voList.add(new UserVo("Bob", "456"));
    pageContext.setAttribute("voList", voList);
%>
<table>
    <tr><th>姓名</th><th>密碼</th></tr>
    <my:forEach collection="voList" id="user">
        <tr>
            <td><my:getProperty name="user" property="name" /></td>
            <td><my:getProperty name="user" property="password" /></td>
        </tr>
    </my:forEach>
</table>

<!-- EL 函數 -->
2 + 5 = ${my:add(2,5)}

六、進階標籤實現片段

ForEach (迭代集合)

public class ForEach extends BodyTagSupport {
    private String id, collection;
    private Iterator iter;
    public int doStartTag() {
        Collection coll = (Collection) pageContext.findAttribute(collection);
        if (coll == null || coll.isEmpty()) return SKIP_BODY;
        iter = coll.iterator();
        pageContext.setAttribute(id, iter.next());
        return EVAL_BODY_INCLUDE;
    }
    public int doAfterBody() {
        if (iter.hasNext()) {
            pageContext.setAttribute(id, iter.next());
            return EVAL_BODY_AGAIN;
        }
        return SKIP_BODY;
    }
}

GetProperty (反射取屬性)

public class GetProperty extends BodyTagSupport {
    private String name, property;
    public int doStartTag() {
        Object obj = pageContext.findAttribute(name);
        if (obj == null) return SKIP_BODY;
        try {
            Method m = obj.getClass().getMethod("get" + capitalize(property));
            pageContext.getOut().print(m.invoke(obj));
        } catch (Exception e) { throw new JspException(e); }
        return SKIP_BODY;
    }
}

ELFunction (靜態方法)

public class ELFunction {
    public static int add(int i, int j) { return i + j; }
}

七、TagSupport vs BodyTagSupport 選擇

  • 不需讀取/修改 Body 內容 → TagSupport。
  • 需操作 Body (迭代、條件輸出、內容轉換) → BodyTagSupport。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved