自定義標簽讓JSP頁面擺脫Scriptlet,實現「聲明式標記+Java邏輯分離」。本文系統講解標簽庫核心概念、標簽處理類開發、TLD描述文件編寫、web.xml配置、JSP頁面引用的完整鏈路,並深度解析TagSupport核心屬性與生命週期。
| 概念 | 說明 |
|---|---|
| 標簽 | XML元素,名稱/屬性區分大小寫,如<mytag:hello name="world"/> |
| 標簽庫 | 功能相關標簽的集合,如日期格式化庫、權限控制庫 |
| TLD (Tag Library Descriptor) | XML配置文件,定義標簽名→處理類映射、屬性規則、體內容類型 |
| 標簽處理類 | Java類,繼承TagSupport或實現SimpleTag,封裝標簽運行時邏輯 |
<%@ taglib prefix="my" uri="/WEB-INF/tlds/mytags.tld" %>
<my:hello name="world"/>
jsp, jspx, java, servlet, sun, sunw保留字)。WEB-INF/**/*.tld、jar包META-INF/*.tld),建立URI→TLD映射。<my:hello>。prefix="my"找到taglib指令的uri。uri在web.xml找到<taglib-uri>映射的<taglib-location>。/WEB-INF/tlds/mytags.tld)。<name>hello</name>對應的<tag-class>。new HelloTag())。setPageContext(pageContext)、setParent(parentTag)注入上下文。setName("world"))。doStartTag()返回EVAL_BODY_INCLUDE或SKIP_BODY。doEndTag()返回EVAL_PAGE。TagSupport,實現doStartTag()/doEndTag()。<tag><name><tag-class><attribute>等元素。web.xml:<taglib><taglib-uri>/myTags</taglib-uri><taglib-location>/WEB-INF/tlds/mytags.tld</taglib-location></taglib>(Servlet 2.4+可省略,容器自動掃描)。<%@ taglib prefix="my" uri="/myTags" %>。| 屬性/方法 | 說明 | 調用時機 |
|---|---|---|
pageContext | 頁面上下文,訪問request/session/application/out等 | setPageContext()最先調用 |
parent | 父標簽處理類實例(巢狀標簽) | setParent()緊隨其後 |
doStartTag() | 開始標簽邏輯,返回EVAL_BODY_INCLUDE/SKIP_BODY/EVAL_BODY_BUFFERED | 屬性設置後、體處理前 |
doEndTag() | 結束標簽邏輯,返回EVAL_PAGE/SKIP_PAGE | 體處理後 |
release() | 釋放資源,重置字段供下次復用 | 標簽實例池化回收時 |
pageContext:此時容器尚未調用setPageContext(),屬性為null。Object支持EL:private Object attr; + setAttr(Object v)內調用ExpressionEvaluatorManager.evaluate()。release()必須清理所有字段狀態。empty(無體)、JSP(有體且需評估)、tagdependent(體作為原文傳遞)。實現javax.servlet.jsp.tagext.SimpleTag接口,單一方法doTag(),無doStartTag/doEndTag分裂,體內容通過getJspBody().invoke(null)控制,API更簡潔、無池化線程安全憂慮。新項目優先選SimpleTag或標簽文件(.tag)。
掌握標簽庫開發全鏈路,是構建項目級DSL(領域特定語言)、統一UI組件庫、封裝跨頁面邏輯的關鍵能力。