簡介 Tag


簡介 Simple Tag〉中曾經使用 Simple Tag 開發了一個 <f:if> 自訂標籤,在這邊則改用 Tag 介面下的相關類別來實作 <f:if> 標籤。要定義標籤處理器,可以透過繼承 javax.servlet.jsp.tagext.TagSupport 來實作。例如:

package cc.openhome;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;

public class IfTag extends TagSupport {
    private boolean test;

    @Override
    public int doStartTag() throws JspException {
        if(test) {
            return EVAL_BODY_INCLUDE;
        }
        return SKIP_BODY;
    }

    public void setTest(boolean test) {
        this.test = test;
    }
}

當 JSP 中開始處理標籤時,會呼叫 doStartTag() 方法,後續是否執行本體則是根據 doStartTag() 的傳回值決定。如果 doStartTag() 方法傳回 EVAL_BODY_INCLUDE 常數(定義在 Tag 介面中),則會執行本體內容,傳回 SKIP_BODY 常數(定義在 Tag 介面中),則不執行本體內容。

接著定義 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>JSP</body-content>
        <attribute>
            <name>test</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
            <type>boolean</type>
        </attribute>
    </tag>
</taglib> 

基本上,在定義 TLD 檔案時與使用 Simple Tag 時是相同的,除了在 <body-content> 的設定值上,在這邊可以設定的有 emptyJSPtagdependent(在 Simple Tag 中可以設定的是 emptyscriptlesstagdependent)。其中 JSP 的設定值表示本體中若包括動態內容,如 Scriptlet 等元素、EL 或自訂標籤都會被執行。

再來可以如〈簡介 Simple Tag〉範例來使用這個標籤,基於簡介時範例的完整性,再將測試用的 JSP 放過來:

<%@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> 

同樣地,如果請求中包括請求參數 password 且值為 123456,則會顯示本體內容,否則只會看到一片空白。