JSP 自定義標籤通過封裝可復用邏輯減少頁面 Java 代碼,提升可維護性。本文系統講解基於 SimpleTag 接口的標籤開發全流程,涵蓋無主體標籤、帶主體標籤、TLD 配置細節及 JspFragment 處理。
| 方法 | 調用時機 | 作用 |
|---|---|---|
| setJspContext(JspContext) | 最先調用 | 接收 PageContext,用於後續輸出操作 |
| setParent(JspTag) | 有父標籤時 | 建立標籤嵌套關係 |
| setJspBody(JspFragment) | 有標籤主體時 | 接收標籤體片段對象 |
| doTag() | 最後調用 | 執行標籤核心邏輯 |
調用順序固定:setJspContext → setParent → setJspBody → doTag
void invoke(Writer out) // 執行片段並輸出到指定 Writer,null 表示輸出到 JspContext.getOut()
package userDefinedJspTag;
import java.io.IOException;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
public class TagDemo1 extends SimpleTagSupport {
private PageContext pc;
@Override
public void setJspContext(JspContext pc) {
this.pc = (PageContext) pc;
}
@Override
public void doTag() throws JspException, IOException {
pc.getOut().print("hello");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" xmlns="https://java.sun.com/xml/ns/j2ee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/j2ee https://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd">
<tlib-version>1.0</tlib-version>
<short-name>myfn</short-name>
<uri>https://www.thecatcher/mytag</uri>
<tag>
<name>printHi</name>
<tag-class>userDefinedJspTag.TagDemo1</tag-class>
<body-content>empty</body-content> <!-- 關鍵:無主體 -->
</tag>
</taglib>
<%@ taglib uri="https://www.thecatcher/mytag" prefix="mytag"%> <mytag:printHi/>
public void doTag() throws JspException, IOException {
JspFragment jf = this.getJspBody();
jf.invoke(null); // null 表示輸出到當前 JspContext 的 out
}
<tag>
<name>out</name>
<tag-class>userDefinedJspTag.TagDemo2</tag-class>
<body-content>scriptless</body-content> <!-- 關鍵:允許 EL 表達式,禁止 Java 代碼 -->
</tag>
| 值 | 含義 | 典型場景 |
|---|---|---|
| empty | 無主體 | <mytag:printHi/> |
| JSP | 支持 EL、Java 代碼、腳本 | 複雜邏輯標籤(不推薦) |
| scriptless | 支持 EL、JSP 標籤,禁止 Java 代碼 | 最常用,符合減少 Java 代碼原則 |
| tagdependent | 不解析任何表達式,原樣輸出 | 模板引擎、代碼生成器 |
<mytag:out>你好啊.</mytag:out>
scriptless,配合 EL 表達式實現邏輯WEB-INF/tld/ 目錄,web.xml 中可不顯式聲明(Servlet 2.4+ 自動掃描)com.project.tags)便於管理