本教學將概述如何建立 Jakarta-Taglibs 函式庫中一些基本標籤。標籤庫可讓您建立自訂動作並封裝功能。自訂標籤可清楚地將簡報層與商業邏輯分開。它們易於維護,可重複使用的元件,可存取 JSP 頁面中所有可用的物件。請參閱 JavaServer Pages 規格,版本 1.2 以取得更多詳細資料。
實作 JSP,v1.1+ 的伺服器支援標籤庫。您可以在 JavaServer Pages 產業動態 頁面中找到各種伺服器及其目前支援的說明。Sun 網站上也有非常好的 Java Web 服務教學,其中包含 自訂標籤 和 JSP 標準標籤庫 (JSTL) 的章節。
標籤處理器負責 JSP 頁面與其他伺服器端物件之間的互動。當遇到自訂標籤時,會在執行 JSP 頁面期間呼叫處理器。當分別遇到自訂標籤的開始和結束標籤時,會呼叫 doStartTag() 和 doEndTag() 方法。 release() 方法會釋放標籤處理器配置的資源。
有兩個介面描述標籤處理器
標籤 | 用於對不感興趣於操作其主體內容的簡單標籤處理器 |
BodyTag | Tag 的延伸,並讓處理器存取其主體 |
標籤處理器有兩個主要動作方法
doStartTag() |
處理此動作的起始標籤。 |
doEndTag() | 處理此動作的結束標籤。在從 doStartTag 回傳後呼叫。 |
release() | 釋放資源 |
doStartTag() 回傳下列內容
- EVAL_BODY_INCLUDE
- 處理動作的主體,但不要建立新的 BodyContent。傳遞主體而不加以操作。只有在您沒有實作 BodyTag 介面時才有效。
- EVAL_BODY_TAG
- 處理動作的主體,並建立新的 BodyContent。只有在您有實作 BodyTag 介面時才有效。
- SKIP_BODY
- 不要評估標籤的主體
doEndTag() 回傳下列內容
- EVAL_PAGE
- 將評估 JSP 頁面的其餘部分
- SKIP_PAGE
- 將不會評估 JSP 頁面的其餘部分
回傳值指示 JSP 容器如何評估 JSP 頁面的其餘部分。release() 方法釋放標籤處理器配置的資源。
TagSupport 和 BodyTagSupport 是 Tag 的子類別,可用於在建立新的標籤處理器時作為基礎類別。
TagSupport 類別是一個實作 Tag 介面並新增其他便利方法的公用程式類別,包括
如果標籤處理器操作動作的主體,則必須實作 BodyTag 介面。doStartTag() 必須回傳 EVAL_BODY_TAG,才能評估標籤的主體。如果回傳 SKIP_BODY,則會忽略主體。與主體內容互動的方法包括
doInitBody() | 在評估標籤的主體之前,但在設定主體內容之後呼叫 |
doAfterBody() | 在評估主體內容之後呼叫 |
BodyTagSupport 類別實作 BodyTag 介面並新增其他便利方法。這些方法包括
在 Web 應用程式中,處理器必須存在於下列標準 Java 類別位置之一
標籤處理器可以存取 JSP 容器使用設定器方法設定的一些屬性。這包括 pageContext 和 parent 物件。標籤處理器也可以存取伺服器端物件和封裝動作。如果標籤是巢狀的,可以使用下列任一方式存取封裝標籤的父處理器
取得父物件後,就可以取得父處理器的靜態和動態建立的物件。
JSP 容器使用標籤庫描述檔 (TLD) 來詮釋包含標籤庫指令頁面,這些指令會參照該標籤庫。它是一個 XML 文件,會將動作標籤對應到標籤處理器類別。您可以使用兩種方式來尋找 TLD
您可以在 Servlet 2.2 和 JSP 1.1 規格中找到有關 web.xml taglib 元素的更多資訊。
由於最近變更為呼叫驗證剖析器,因此您需要明確參照外部 DOCTYPE
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
TLD taglib 元素是文件根目錄。它具有下列子元素
tlibversion | 標籤庫實作的版本 |
jspversion | 標籤庫需要的 JSP 規格版本 |
shortname | 可從 JSP 頁面參照標籤庫的名稱 |
uri | 唯一識別標籤庫的 URI - 描述標籤庫「用途」的資訊字串 |
info | 描述標籤庫「用途」的字串 |
tag 元素定義標籤庫中的動作。它可能有幾個定義動作的子元素
name | 唯一的動作名稱 |
tagclass | 實作 javax.servlet.jsp.tagext.Tag 的標籤處理器類別 |
teiclass | javax.servlet.jsp.tagext.TagExtraInfo 的可選子類別 |
bodycontent |
三種類型的主體內容之一 |
info |
可選的標籤特定資訊 |
attribute |
動作的所有屬性 |
如果標籤有主體,則包含 bodycontent。它由頁面組成工具使用,因此不會影響主體的組成。它可以是下列三種類型之一
- JSP(預設)
- JSP 容器應評估標籤的任何主體,但它也可以是空的
- tagdependent
- 標籤的任何主體都將由標籤本身處理,但它也可以是空的
- empty
- 主體必須是空的
teiclass 定義腳本變數,並包含下列資訊
- name
- 類型
- 變數是否需要建立
- 範圍
attributes 可以有下列欄位
- name(必要)
- 屬性名稱
- 必要
- 屬性是否必要或選用
- rtexprvalue
- 如果屬性值可能在執行階段由小程式動態計算。注意:預設值為「false」,表示屬性具有靜態值。如果屬性值在要求時間決定,請務必將其設定為「true」。
對於每個屬性,您都必須在標籤處理常式中具備 JavaBeans 樣式的取得和設定方法。如果您的屬性名稱為 id,TagSupport 類別會為您定義 setId() 和 getId() 方法。
JavaServer Pages 可以處理封裝在標籤庫動作中的 XML 內容。
<%@ taglib uri="identifier" prefix="prefix" %>
若要使用標籤庫,您需要使用 taglib 指令告訴 JSP 容器其位置。該指令必須在任何動作之前。
若要安裝標籤庫,您需要執行下列步驟
<taglib> <taglib-uri>http://jakarta.apache.org/taglibs/{library}</taglib-uri> <taglib-location>/WEB-INF/{library}.tld</taglib-location> </taglib>
<%@ taglib uri="http://jakarta.apache.org/taglibs/{library}" prefix="x" %>
若要將標籤庫子專案新增至 Jakarta-Taglibs,您需要執行下列動作
使用 jakarta-taglibs 專案中的建置指令碼建立 war 檔案。建置 war 檔案後,您可以將該檔案放置在 $TOMCAT_HOME/webapps 目錄中。Tomcat 會載入您的類別並建立新的內容。
war 檔案應具有下列結構
META-INF/ META-INF/MANIFEST.MF WEB-INF/ WEB-INF/classes/ WEB-INF/lib/ WEB-INF/lib/{tagLibrary}.jar WEB-INF/web.xml WEB-INF/{tagLibrary}.tld
如果您不想使用 jar 檔案,您可以將所有類別檔案放置在 /WEB-INF/classes 目錄中。
請參閱 Java Servlet 規範,v2.2 以取得有關 war 檔案的更多資訊。
這個基本標籤是「Hello World」範例。每當遇到標籤時,就會列印「Hello World」文字。
您可以在 /WEB-INF/classes/basic 目錄中找到 Hello World 標籤的標籤處理常式,因為它是 basic 套件的一部分
package basic;
匯入 jsp 和標籤類別
import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*;
Hello World 標籤處理常式實作 doStartTag() 方法,在遇到開始標籤時會呼叫該方法。
public int doStartTag() throws JspException { try { pageContext.getOut().print("Hello World"); } catch (Exception ex) { throw new JspException("IO problems"); } return SKIP_BODY; }
JSP 容器設定 pageContext,且標籤處理常式可以使用。 SKIP_BODY 值可確保不會評估標籤主體。
<?xml version="1.0" encoding="ISO-8859-1" ?>
描述部署描述符 DOCTYPE 的 XML 標頭。部署描述符包含 Web 應用程式的元素和組態資訊。
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglib_1_1.dtd">
初始標籤庫描述
<taglib> <!-- The version number of this tag library --> <tlibversion>1.0</tlibversion> <!-- The JSP specification version required to function --> <jspversion>1.1</jspversion> <!-- The short name of this tag library --> <shortname>utility</shortname> <!-- Public URI that uniquely identifies this version of the tag library --> <uri>http://jakarta.apache.org/taglibs/utilitytags</uri> <!-- General information about this tag library --> <info> A simple tag library for the examples </info>
Hello World 標籤描述。
<!-- Hello tag --> <tag> <name>Hello</name> <tagclass>basic.Hello</tagclass> <bodycontent>empty</bodycontent> <info> Print Hello World </info> </tag>
web.xml 檔案描述標籤庫描述符的標籤 uri 和位置之間的對應。
這裡的唯一 taglib-uri "http://jakarta.apache.org/taglibs/utilitytags" 與 /WEB-INF/tld/utilitytags.tld 中的標籤庫描述符關聯。
<web-app> <taglib> <taglib-uri> http://jakarta.apache.org/taglibs/utilitytags </taglib-uri> <taglib-location> /WEB-INF/tld/utilitytags.tld </taglib-location> </taglib> </web-app>
以下指令告訴 JSP 容器使用在 web.xml 中定義的 "http://jakarta.apache.org/taglibs/utilitytags" uri。"jLib" 被定義為標籤的前置詞值。
<%@ taglib uri="http://jakarta.apache.org/taglibs/utilitytags" prefix="jLib" %>
Hello World 標籤被呼叫。標籤名稱 "Hello" 在標籤庫描述符中定義。
<jLib:Hello/>
這個巢狀標籤是 "If" 條件標籤的範例。包含的指令碼會根據屬性的值進行評估或略過。
BodyTagSupport 類別實作 BodyTag 介面,並有 bodyContent 屬性的 getter 方法。
public class IfTag extends BodyTagSupport {
doStartTag() 方法會在遇到開始標籤時呼叫,並呼叫本地的 getPredicate() 方法。如果傳回值為 true,則會評估標籤主體的其餘部分,否則會略過。
public int doStartTag() { if (getPredicate()) return EVAL_BODY_TAG; else return SKIP_BODY; }
doAfterBody() 會在評估某些主體之後呼叫。它不會在空標籤或在 doStartTag() 中傳回 SKIP_BODY 的標籤中呼叫。
public int doAfterBody() throws JspException { try { bodyContent.writeOut(bodyContent.getEnclosingWriter()); return SKIP_BODY; } catch (IOException ex) { throw new JspTagException(ex.toString()); } }
<!-- IF tag --> <tag> <name>If</name> <tagclass>lang.IfTag</tagclass>
If 標籤有一個必要的屬性。由於 rtexprvalue 設為 true,因此屬性可以有指令碼表達式作為值。該值可以在請求時動態計算。
<attribute> <name>predicate</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <info> Conditional Tag. </info> </tag>
web.xml 檔案描述標籤庫描述符的標籤 uri 和位置之間的對應。
這裡的唯一 taglib-uri "http://jakarta.apache.org/taglibs/utilitytags" 與 /WEB-INF/tld/utilitytags.tld 中的標籤庫描述符關聯。
If 標籤需要一個屬性。predicate 屬性包含一個指令碼,它會在執行階段評估。根據 predicate 屬性的值,jLib:Hello 標籤會被評估或略過。
<jlib:if predicate="<%= x==5 %>"> <jLib:Hello/> </jlib:if>
這個自訂標籤庫不需要任何軟體,只要支援 JavaServer Pages 規格版本 1.1 的 servlet 容器即可。
請遵循下列步驟,使用這個標籤庫組態您的網路應用程式
<taglib> <taglib-uri>http://jakarta.apache.org/taglibs/utilitytags</taglib-uri> <taglib-location>/WEB-INF/utilitytags.tld</taglib-location> </taglib>
若要在 JSP 頁面中使用這個庫中的標籤,請在每個頁面的頂端新增以下指令
<%@ taglib uri="http://jakarta.apache.org/taglibs/utilitytags" prefix="x" %>
For 標籤是基本迴圈標籤。
屬性
|
說明
|
必要
|
---|---|---|
反覆運算
|
要完成的迴圈反覆運算次數。任何字串整數值。
|
是
|
變數名稱
|
與 For 迴圈相關聯的變數名稱。任何字串值。
|
否
|
開始
|
迴圈開始值。任何字串整數值。
|
否
|