相較於 Tag File 的使用,實作 Simple Tag 時有更多的東西必須了解。首先來使用 Simple Tag 模彷 JSTL 的 <c:if>
標籤功能,了解一個簡單的 Simple Tag 要如何開發,由於這是個「偽」JSTL 標籤,姑且叫它作 <f:if>
標籤好了。
首先要撰寫標籤處理器,這是一個 Java 類別,可以繼承 javax.servlet.jsp.tagext.SimpleTagSupport
來實作標籤處理器(Tag Handler),並重新定義 doTag()
方法來進行標籤處理。
package cc.openhome;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
public class IfTag extends SimpleTagSupport {
private boolean test;
@Override
public void doTag() throws JspException {
if (test) {
try {
getJspBody().invoke(null);
} catch (java.io.IOException ex) {
throw new JspException("IfTag 執行錯誤", ex);
}
}
}
public void setTest(boolean test) {
this.test = test;
}
}
在這邊的 <f:if>
標籤有個 test
屬性,所以標籤處理器必須有個接受 test
屬性的設值方法(Setter)。如果 test
屬性為 true
,則呼叫 SimpleTagSupport
的 getJspBody()
方法,這會傳回一個 JspFragment
物件,代表 <f:if>
與 </f:if>
間的本體內容,如果呼叫 JspFragment
的 invoke()
並傳入一個 null
,表示執行 <f:if>
與 </f:if>
間的本體內容,如果沒有呼叫 invoke()
,則 <f:if>
與 </f:if>
間的本體內容不會執行,也就不會有結果輸出至使用者的瀏覽器。
為了讓 Web 容器了解 <f:if>
標籤與 IfTag
標籤處理器之間的關係,要定義一個標籤程式庫描述檔(Tag Library Descriptor),也就是一個副檔名為 *.tld 的檔案。
f.tld
<?xml version="1.0" encoding="UTF-8"?>
<taglib xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.1">
<tlib-version>1.0</tlib-version>
<short-name>f</short-name>
<uri>https://openhome.cc/jstl/fake</uri>
<tag>
<name>if</name>
<tag-class>cc.openhome.IfTag</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>test</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
</attribute>
</tag>
</taglib>
其中 <uri>
設定是在 JSP 中與 taglib
指示元素的 url
屬性對應用的。每個 <tag>
標籤中使用 <name>
定義了自訂標籤的名稱,使用 <tag-class>
定義標籤處理器類別,而 <body-content>
設定為 scriptless
,表示標籤本體中不允許使用 Scriptlet 等元素。
如果標籤上有屬性,則是使用 <attribute>
來設定,<name>
設定屬性名稱,<required>
表示是否一定要設定這個屬性,<rtexprvalue>
(也就是 runtime expression value)表示屬性是否接受執行時期運算的結果(例如 EL 運算式的結果),如果設定為 false
或不設定 <rtexprvalue>
,表示在 JSP 上設定屬性時僅接受字串形式,<type>
則設定屬性型態。
可以將 TLD 檔案放在 WEB-INF 資料夾下,如此容器就會自動載入它。如果要使用這個標籤,同樣必須在JSP頁面上使用 taglib
指示元素。例如:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="https://openhome.cc/jstl/fake" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>自訂 if 標籤</title>
</head>
<body>
<f:if test="${param.password == '123456'}">
你的秘密資料在此!
</f:if>
</body>
</html>
在這個示範的 JSP 頁面中,使用自訂的 <f:if>
標籤,檢查 password
請求參數是否為所設定的數值,如果正確才會顯示 <f:if>
本體的內容。
JSTL 本身並非用 Simple Tag 來實作的,而是使用之後要介紹的 Tag 自訂標籤來實作。在這邊只是用 Simple Tag 來模彷 JSTL 的功能。