標籤庫三大核心組件
| 組件 | 角色 | 技術形式 |
| 標籤處理器 | 實現標籤邏輯 | Java 類,實現 Tag/BodyTag/SimpleTag 介面 |
| 標籤附加信息 (TEI) | 編譯期驗證屬性、聲明變數 | 繼承 TagExtraInfo,覆寫 getVariableInfo()、isValid() |
| 標籤庫描述符 (TLD) | 元數據:標籤名、屬性、體內容、處理器類映射 | XML 文件,置於 META-INF/taglib.tld 或 WEB-INF/*.tld |
標籤庫打包與部署 (JSP 1.1+ 規範)
- 編譯處理器、TEI 類 → JAR 包。
- TLD 放入 JAR
META-INF/taglib.tld。
- JAR 複製到 Web 應用
WEB-INF/lib/,容器自動掃描載入。
開發四步驟
- 設計標籤:名稱、屬性、變數、體內容類型 (empty/tagdependent/scriptless/JSP)。
- 編寫 TLD (XML)。
- 實現標籤處理器 (Java)。
- JSP 頁面引用:
<%@ taglib uri="..." prefix="mytag" %>。
JSP 頁面在容器中的轉換流程
- 指令元素 → 提供轉換期資訊 (不產出內容)。
- 靜態 HTML →
out.print() 序列。
- 宣告腳本
<%! ... %> → 類成員區域 (service 方法外)。
- 表達式腳本
<%= ... %> → out.print()。
- Scriptlet
<% ... %> → 直接複製進 _jspService() 方法體。
- 動作元素 (標準/自定義) → 生成運行時邏輯代碼。
- **自定義標籤** → 展開為調用對應處理器方法的 Java 語句序列:
TagHandler th = new TagHandler(); th.setPageContext(pageContext); th.setParent(parent); th.doStartTag(); ... th.doEndTag();
自定義標籤在容器中的解析流程
taglib 指令定位 TLD (uri 匹配)。
- 讀取 TLD 標籤列表與處理器類名。
- 遇到前綴標籤 → 查找對應 Taglib → 獲取處理器類。
- 依 TLD 結構信息生成調用處理器生命週期方法的代碼。
標籤處理器生命週期 (Classic Tag API)
1. setPageContext(pageContext)
2. setParent(parentTag)
3. setXxx(attributeValues) // 每個屬性一個 setter
4. doStartTag() → 返回 EVAL_BODY_INCLUDE / SKIP_BODY / EVAL_BODY_TAG
5. [若有 Body] doInitBody() → bodyContent → doAfterBody() 循環
6. doEndTag() → 返回 EVAL_PAGE / SKIP_PAGE
7. release() // 釋放資源,供下次複用 (池化)
SimpleTag API (JSP 2.0+ 推薦)
- 單一方法
doTag() 封裝全部邏輯,無 doStart/EndTag 複雜度。
- 體內容透過
getJspBody().invoke(null) 或 invoke(writer) 處理。
- 無釋放池化問題,每次請求新實例,簡化狀態管理。
現代化替代方案
| 需求 | 推薦技術 | 理由 |
| UI 組件庫 | React/Vue/Svelte 組件 + Web Components | 瀏覽器原生、框架無關、生態豐富 |
| 伺服器端模板片段 | Thymeleaf Fragment / FreeMarker Macro / JTE | 類型安全、IDE 支援、自然模板語法 |
| JSP 遺留系統擴展 | 繼續用 Taglib / Tag Files (.tag) | 零重構成本、漸進式遷移 |
結語
Taglib 是 JSP 時代**組件化、關注點分離**的核心機制。理解其容器轉換機制、生命週期、TLD 元數據結構,對維護舊系統、設計模板引擎擴展點仍有價值。新架構請擁抱前端組件化與現代模板引擎。
- 上一篇文章: JSP 防止表單重複提交:基於 Session Token 的服務端驗證方案
- 下一篇文章: JSP 生成靜態頁面:Tomcat 效能優化的終極之道 — 原理、策略與遷移指南
Copyright ©
程式碼之家 All Rights Reserved