代碼
<%@ taglib uri="https://java.sun.com/jstl/core" prefix="c" %>
uri 本質
- 唯一標識符 (URI):標識一個標簽庫,**不是文件系統路徑**,不發起網絡請求。
- 容器 (Tomcat/Jetty) 根據 `uri` 在 `web.xml`、`TLD` 文件、JAR 包 `META-INF/taglib.tld` 中查找匹配的 ``。
- JSTL 1.2+ 標準 `uri`:
- `https://java.sun.com/jsp/jstl/core` (core)
- `https://java.sun.com/jsp/jstl/fmt` (fmt)
- `https://java.sun.com/jsp/jstl/sql` (sql)
- `https://java.sun.com/jsp/jstl/xml` (xml)
- `https://java.sun.com/jsp/jstl/functions` (fn)
- 舊版 (JSTL 1.0/1.1) 帶 `_rt` / `_elt` 後綴表示運行時表達式評估 / EL 表達式評估,**現代項目統一使用無後綴標準 URI**。
解析流程
- JSP 編譯為 Servlet 時,容器解析 `<%@ taglib %>`。
- 根據 `uri` 查找 TLD (Tag Library Descriptor) 文件定義的標簽類、屬性、體內容等元數據。
- 生成調用標簽處理類 (Tag Handler) 的 Java 代碼。
- 運行時實例化 Tag Handler,執行 `doStartTag`/`doEndTag` 等生命周期方法。
常見問題
- 找不到 TLD:缺少 `jstl.jar` / `standard.jar` (JSTL 1.2 只需 `jstl-1.2.jar`),或 JAR 未放在 `WEB-INF/lib`。
- URI 不匹配:使用舊版 URI (`.../jstl/core_rt`) 但項目依賴新版 JSTL JAR。統一升級至標準 URI。
- prefix 衝突:同頁面兩個 taglib 使用相同 `prefix`,編譯報錯。
類比理解
`uri` 如同 **Java 包名** (如 `java.util`),`prefix` 如同 **導入別名** (如 `import java.util.List as JList`)。使用冰箱不需懂製冷原理,會用標簽即可。
最佳實踐
- 統一使用 **標準 JSTL 1.2 URI** (無後綴)。
- Maven 依賴:`javax.servletjstl1.2`。
- IDE (IDEA/Eclipse) 會自動提示標簽屬性,善用代碼補全減少查閱文檔。