TagSupport / BodyTagSupport / SimpleTagSupport。<%@ taglib ... %>) 並使用標籤。<hello:helloTag/> 輸出「Hello Tag!」tags.HelloTagpackage tags; // 必須放在包中,否則類加載器找不到
import java.io.IOException;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.TagSupport;
public class HelloTag extends TagSupport {
@Override
public int doStartTag() {
try {
JspWriter out = pageContext.getOut();
out.print("Hello Tag!");
} catch (IOException e) {
System.err.println("IOException in HelloTag: " + e);
}
return SKIP_BODY; // 無標籤體內容
}
}
/WEB-INF/tags/helloTag.tld<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"https://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>helloTag</short-name>
<uri>/WEB-INF/tags/helloTag</uri> <!-- 唯一標識,JSP 引用時使用 -->
<display-name>Hello Tag Library</display-name>
<description>Simple hello tag example</description>
<tag>
<name>helloTag</name>
<tag-class>tags.HelloTag</tag-class>
<body-content>empty</body-content> <!-- 無標籤體 -->
<description>Prints a greeting message</description>
</tag>
</taglib>
HelloTag.jsp<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib uri="/WEB-INF/tags/helloTag.tld" prefix="hello" %>
<html><body>
<h2>測試自定義標籤</h2>
<hello:helloTag />
</body></html>
tags.GreetTagpackage tags;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.BodyTagSupport;
import java.io.IOException;
public class GreetTag extends BodyTagSupport {
private String name; // 屬性
public void setName(String name) { this.name = name; }
public String getName() { return name; }
@Override
public int doStartTag() {
return EVAL_BODY_BUFFERED; // 需處理標籤體,使用 BodyContent
}
@Override
public int doAfterBody() {
try {
BodyContent body = getBodyContent();
String bodyStr = body.getString().trim();
JspWriter out = body.getEnclosingWriter();
out.print("Hello, " + name + "! Body content: [" + bodyStr + "]");
body.clearBody();
} catch (IOException e) {
e.printStackTrace();
}
return SKIP_BODY;
}
}
<tag>
<name>greetTag</name>
<tag-class>tags.GreetTag</tag-class>
<body-content>JSP</body-content> <!-- 有標籤體 -->
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue> <!-- 支持 EL 表達式 -->
</attribute>
</tag>
<hello:greetTag name="World">
這是標籤體內容
</hello:greetTag>
<!-- 輸出:Hello, World! Body content: [這是標籤體內容] -->
無需 Java 類與 TLD,直接編寫 /WEB-INF/tags/greet.tag:
<%@ tag body-content="scriptless" %>
<%@ attribute name="name" required="true" %>
Hello, ${name}! Body: <jsp:doBody/>
頁面引用:<%@ taglib prefix="my" tagdir="/WEB-INF/tags" %> → <my:greet name="World">內容</my:greet>
tags, com.mytags 等)。/WEB-INF/tld/ 或 /WEB-INF/tags/,web.xml 可不再聲明 <taglib> (Servlet 2.4+ 自動掃描)。rtexprvalue 以接受 EL/請求時表達式。empty (無)、scriptless (無 Scriptlet、有 EL/標準動作)、JSP (完全 JSP 語法)、tagdependent (原文傳遞給標籤處理)。pageContext.setAttribute() 或 ThreadLocal。IOException 拋出 JspException,讓容器統一處理錯誤頁。自定義標籤將展示邏輯封裝為可重用組件,是 JSP 組件化的核心。從經典 TagSupport 到 JSP 2.0 標籤文件、SimpleTag,開發門檻不斷降低。掌握標籤生命週期、屬性綁定、標籤體處理、線程安全,即可開發出健壯的企業級標籤庫。