| 術語 | 說明 |
|---|---|
| 標籤 | XML 風格元素,如 <mytag:hello/>,名稱/屬性區分大小寫 |
| 標籤庫 | 功能相關標籤的集合,打包為 JAR 部署 |
| TLD (Tag Library Descriptor) | XML 配置檔,定義標籤名、處理類、屬性、體內容類型等 |
| Tag Handler | 實作標籤邏輯的 Java 類,繼承 TagSupport 或實作 SimpleTag |
web.xml 宣告標籤庫(或依賴 JAR 自動掃描)package com.example.tag;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
public class HelloTag extends TagSupport {
private String name; // 屬性對應 setter
public void setName(String name) { this.name = name; }
@Override
public int doStartTag() throws JspException {
try {
pageContext.getOut().print("Hello, " + (name != null ? name : "World") + "!");
} catch (IOException e) {
throw new JspException(e);
}
return SKIP_BODY; // 無 body 內容
}
@Override
public int doEndTag() { return EVAL_PAGE; }
}
public class HelloSimpleTag extends SimpleTagSupport {
private String name;
public void setName(String name) { this.name = name; }
@Override
public void doTag() throws JspException, IOException {
getJspContext().getOut().print("Hello, " + (name != null ? name : "World") + "!");
}
}
位置:WEB-INF/tlds/mytags.tld 或 JAR 內 META-INF/tlds/
<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="https://java.sun.com/xml/ns/javaee"
version="2.1">
<tlib-version>1.0</tlib-version>
<short-name>mytag</short-name>
<uri>https://example.com/mytags</uri>
<tag>
<name>hello</name>
<tag-class>com.example.tag.HelloTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
<jsp-config>
<taglib>
<taglib-uri>https://example.com/mytags</taglib-uri>
<taglib-location>/WEB-INF/tlds/mytags.tld</taglib-location>
</taglib>
</jsp-config>
<%@ taglib prefix="my" uri="https://example.com/mytags" %>
<html><body>
<my:hello name="Developer"/>
</body></html>
// TagSupport
public int doStartTag() { return EVAL_BODY_INCLUDE; } // 執行 body 內容
public int doEndTag() { return EVAL_PAGE; }
// SimpleTag
public void doTag() throws JspException, IOException {
JspFragment body = getJspBody();
if (body != null) body.invoke(null); // 直接輸出 body
}
基本型別、String、Enum 自動轉換;複雜型別需在 setter 中處理或實作 TagAttributeConverter。
// 子標籤取得父標籤
ParentTag parent = (ParentTag) getParent();
parent.addChildData(this);
WEB-INF/lib,TLD 置於 JAR META-INF/tlds/,容器自動發現。https://com.example/tags)避免衝突。SimpleTag:不需管理生命週期、支援片段、程式碼更簡潔。BodyContent 緩衝,避免直接寫 Out 造成效能問題。