一篇介紹JSP標籤庫很詳細的文章,可以做為參考手冊

來源:互聯網
上載者:User
js|參考|參考手冊

標準的JSP 標記可以調用JavaBeans組件或者執行客戶的請求,這大大降低了JSP開發的複雜度和維護量。JSP技術也允許你自訂taglib,其實換句話說,taglib可以看成是對JSP標記的一種擴充,正如xml是對html的一種擴充一樣。taglib通常定義在tag標籤庫中,這種標籤庫存放著你自己定義的tag標籤。簡而言之,如果使用taglib,那麼你可以設計自己的JSP標記!

一般來說,自訂tag標籤主要用於操作隱藏對象、處理html提交表單、訪問資料庫或其它企業級的服務,諸如郵件和目錄操作等等。自訂tag標籤的使用者一般都是那些對java程式設計語言非常精通,而且對資料訪問和企業級服務訪問都非常熟悉的程式員,對於HTML設計者來說,使得他可以不去關注那些較複雜的商業邏輯,而將精力放在網頁設計上。同時,它也將庫開發人員和庫使用者進行合理分工,自訂tag標籤將那些重複工作進行封裝,從而大大提高了生產力,而且可以使得tag庫可用於不同的項目中,完美地體現了軟體複用的思想。

在這篇文章中,我們主要討論:

· 什麼是自訂tag標籤?

· 怎麼使用tag標籤?

o 聲明要使用的tag庫

o 找到與之對應的tag處理類

o tag標籤的類型

· 自訂tag標籤

o tag處理類

o tag庫描述

o tag標籤樣本

o 帶屬性的tag

o 帶body的tag

o 定義了指令碼變數的tag

o 具有協作關係的tag

· 自訂tag標籤

o 一個迭代tag的例子

o 一個模板tag庫

o tag處理類到底是怎樣被調用的?


什麼是自訂的tag?

一個自訂的tag標籤是使用者定義的一種JSP標記。當一個含有自訂的tag標籤的JSP頁面被jsp引擎編譯成servlet時,tag標籤被轉化成了對一個稱為tag處理類的對象進行的操作。於是當JSP頁面被jsp引擎轉化為servlet後,實際上tag標籤被轉化成為了對tag處理類的操作。

自訂tag標籤有很多特色,諸如:

· 可以在JSP頁面中自訂tag標籤的屬性

· 訪問JSP頁面中的所有對象

· 可以動態地修改頁面輸出

· 彼此這間可以相互連信。你可以先建立一個JavaBeans組件,然後在一個tag中調用此JavaBeans組件,同時可以在另一個tag中調用它。

· tag允許相互嵌套,可以在一個JSP頁面中完成一些複雜的互動。


使用tag標籤


本節主要描述怎樣在JSP頁面中使用tag標籤,以及tag標籤的不同類型。

要使用tag標籤,JSP程式員必須做2件事:

· 聲明此tag標籤的tag庫

· 實現此tag標籤

聲明tag標籤所在的tag庫

如果要使用tag標籤,則應用JSP的taglib指示符來指定其tag庫(注意:taglib要在在使用此tag標籤之前聲明)

<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %>

uri屬性定義了唯一的標籤庫描述(以下簡稱TLD),它可以是直接是tld檔案名稱或一個獨一無二的名字。prefix是用來區別其它TLD中和本TLD中有重名的tag的一種手段。

TLD必須以.tld作為副檔名,並且存放在當前應用的WEB-INF目錄或其子目錄下。你可以通過它的檔案名稱直接引用它,也可以通過別的方式間接地引用它。

以下taglib指示符直接引用一個TLD:

<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %>

以下的taglib指示符通過一個邏輯名稱間接地引用一個TLD:

<%@ taglib uri=”/tutorial-template” prefix=”tt” %>

如果是間接引用TLD的話,那你必須還要在web.xml中定義此邏輯名稱與tld檔案之間的映射,具體做法是在web.xml中加入一個名為taglib的元素:

<taglib>

<taglib-uri>/tutorial-template</taglib-uri>

<taglib-location>

/WEB-INF/tutorial-template.tld

</taglib-location>

</taglib>


實現此tag標籤


為了實現tag標籤,你有2種方法來存放tag處理類。一、讓tag處理類以.class的方式存放於當前應用的WEB-INF/class子目錄下,二、如果tag處理類是以JAR包的形式存在的話,那可以放在當前應用的WEB-INF/lib目錄下,如果tag處理類要在多個應用中共用,那麼它就應放在jsp伺服器上的common/lib目錄下,對於tomcat來說,就是tomcat/common/lib目錄下。


tag標籤類型


自訂的tag標籤遵循XML文法。它有一個開始標記和一個結束標記,有的還有body(即文本節點):

<tt:tag>

body

</tt:tag>


一個不帶body的tag標籤如下:

<tt:tag />


簡單的tag標籤

一個沒有body和屬性的tag標籤如下:

<tt:simple />


帶屬性的tag標籤


自訂標籤可以有自己的屬性。屬性一般在開始標記中定義,文法為 attr=”value”。屬性的作用相當於自訂標籤的一個參數,它影響著tag處理類的行為。你可以在TLD中詳細定義它。

你可以用一個String常量給一個屬性賦值,也可以通過運算式給它賦值,如<%= ...%>。以struts為例,它的logic:present標籤就是用的String常量來給屬性賦值:

<loglic:present parameter = “Clear”>

而另一個標籤logic:iterate是用運算式來給屬性賦值:

<logci:iterate collection=”<%= bookDB.getBooks() %>”

id=”book” type=”database.BookDetails”>


帶body的tag標籤

一個自訂標籤可以包含其它自訂標籤、指令碼變數、HTML標記或其它內容。

在下述例子中,此JSP頁面使用了struts的logic:present標籤,如果些標籤定義了parameter=”Clear”的屬性,則將清除購物車的內容,然後列印出一條資訊:

<logic:present parameter=”Clear”>

<% cart.clear(); %>

<font color=”#ff0000” size=”+2”><strong>

你選擇了清除購物車!

</strong></font>

</logic:present>


到底是用屬性還是用body來傳遞資訊?

如上所述,我們既可以通過屬性,也可以通過body來傳遞資訊。但一般來說,比較簡單的類型,如字串或簡單運算式最好採用屬性來傳遞資訊。


定義指令碼變數的tag標籤

所謂指令碼變數,是指JSP中可以調用的變數或對象。它可由tag標籤產生。以下樣本闡述了一個tag標籤定義了一個名為tx的由JNDI所定義的交易處理對象。指令碼變數可以是ejb對象、事務、資料庫連接等等:

<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” />

<% tx.begin(); %>

...


具有協作關係的tag標籤

自訂tag標籤之間可以通過共用對象來實現協作。在下述例子中,標籤tag1建立了一個名為obj1的對象,在標籤tag2仍可以重複使用obj。

<tt:tag1 attr1=”obj1” value1=”value” />

<tt:tag2 attr1=”obj1” />

在以下這個例子當中,如果外層的tag標籤建立了一個對象,那麼其內層的所有tag標籤都可以使用這個對象。由於這樣產生的對象沒有一個指定的名字,那麼就可以將少重名的衝突。這個例子闡述了一系列協作的嵌套對象。

<tt:outerTag>

<tt:innerTag />

</tt:outerTag>

Tag處理類


Tag處理類必須實現Tag介面或BodyTag介面,不過現在一般都流行從TagSupport或BodyTagSupport類中繼承,這些類或介面都可以在javax.servlet.jsp.tagext包中找到。

當JSP引擎看到自己的JSP頁面中包含有tag標籤時,它會調用doStartTag方法來處理tag標籤的開頭,調用doEndTag方法來處理tag標籤的結束。

下表說明不同類型的tag所需要不同的處理過程:

Tag處理類的方法

Tag標籤類型
所調用的方法

基本標籤
doStartTag, doEndTag, release

帶屬性的標籤
doStartTag, doEndTag, set/getAttribute1...N, release

帶內容的標籤
doStartTag, doEndTag, release

帶內容的標籤,且內容重複迴圈
doStartTag, doAfterBody, doEndTag, release

帶內容的標籤,且內容與JSP互動
doStartTag, doEndTag, release, doInitBody, doAfterBody, release

一個tag處理類可以通過javax.servlet.jsp.PageContext來與JSP互動,通過javax.servlet.jsp.PageContext類,tag處理類可以訪問JSP中的request、session和application對像。

如果tag標籤是互相嵌套的,那內層的tag處理類可以通過它的parent屬性來訪問上層的tag處理類。

一般情況都將所有的tag處理類打成了JAR的包,以便於發布。


Tag庫描述(簡稱TLD)


Tag庫是用xml語言描述的,TLD包括了tag庫中所有tag標籤的描述,它一般用來被jsp伺服器用來校正tag的文法正確性,或者被jsp開發人員用來開發新的標籤。

TLD的副檔名必須為.tld,而且必須放在當前WEB應用的WEB-INF目錄或其子目錄中。

一個TLD的內容的開頭必須遵守標準的XML開頭,用於描述DTD和xml的版本,例如:

<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
TLD必須以<taglib>來作為它的根項目,<taglib>的子項目如下表:


<taglib>的子項目

Element
Description

tlib-version
Tag庫的版本

jsp-version
Tag庫所需要的jsp的版本

short-name
助記符,tag的一個別名(可選)

uri
用於確定一個唯一的tag庫

display-name
被視覺化檢視(諸如Jbuilder)用來顯示的名稱(可選)

small-icon
被視覺化檢視(諸如Jbuilder)用來顯示的小表徵圖(可選)

large-icon
被視覺化檢視(諸如Jbuilder)用來顯示的大表徵圖(可選)

description
對tag庫的描述(可選)

listener
參見下面listener元素

tag
參見下面tag 元素

Listener元素

一個tag庫可能定義一些類做為它的事件偵聽類,這些類在TLD中被稱為listener 元素,jsp伺服器將會執行個體化這些偵聽類,並且註冊它們。Listener元素中有一個叫listener-class的子項目,這個元素的值必須是該偵聽類的完整類名。

Tag元素

每個tag元素在tag庫中都要指出它的名字、類名、指令碼變數、tag的屬性。其中指令碼變數的值可以直接在TLD中定義或通過tag附加資訊的類來取得。每個屬性描述了這個屬性是否可以省略,它的值是否可以通過<%= …%>這樣的JSP文法來獲得,以及屬性的類型。

每一個tag在TLD中對應一個tag元素,下表是tag元素的子項目:

Tag元素的子項目

元素名稱
描述

name
獨一無二的元素名

tag-class
Tag標籤對應的tag處理類

tei-class
javax.servlet.jsp.tagext.TagExtraInfo的子類,用於表達指令碼變數(可選)

body-content
Tag標籤body的類型

display-name
被視覺化檢視(諸如Jbuilder)用來顯示的名稱(可選)

small-icon
被視覺化檢視(諸如Jbuilder)用來顯示的小表徵圖(可選)

large-icon
被視覺化檢視(諸如Jbuilder)用來顯示的大表徵圖(可選)

description
此tag標籤的描述

variable
提供指令碼變數的資訊(同tei-class)(可選)

attribute
Tag標籤的屬性名稱

以下章節介紹對於不同類型的tag,如何具體地實現它們。


簡單的tag


tag處理類

簡單的tag處理類必須實現Tag介面的doStartTag和doEndTag方法。當jsp引擎碰到tag標籤的開頭時,doStartTag被調用,因為簡單的tag沒有body,所以此方法將返回 SKIP_BODY。當jsp引擎碰到tag標籤的結尾時,doEndTag被調用,如果餘下的頁面還要被計算,那它將返回EVAL_PAGE,否則將會返回SKIP_PAGE。

以下是例子:對於標籤 <tt:simple /> ,它的tag處理類實現如下:


public SimpleTag extends TagSupport

{

public int doStartTag() throws JspException

{

try{

pageContext.getOut().print(“Hello.”);

}catch(Exception e){

throw new JspTagException(“SimpleTag: “ + e.getMessage());

}

return SKIP_BODY;

}

public int doEndTag()

{

return EVAL_PAGE;

}

}


注意:如果tag標籤沒有內容的話,那必須定義body-content元素為空白,例如

<body-content>empty</body-content>


帶屬性的tag標籤


tag處理類

對於tag標籤的每個屬性,你必須依照JavaBeans規範來定義其屬性,以及get和set方法。以struts的logic:present 標籤為例,

<logic:present parameter=”Clear”>

與此相應,此tag處理類應有如下方法和定義:


protected String parameter = null;

public String getParameter()

{

return this.parameter;

}

public void setParameter(String parameter)

{

this.parameter = parameter;

}


注意:如果你的屬性名稱為id,而且你的tag處理類是從TagSupport類繼承的,那你就不需要定義它的屬性和set和get方法,因為他們早已在TagSupport被定義過了。

Attribute元素

對於tag標籤的每個屬性,你必須定義它是否必須的,它的值是否可以用諸如<%= …%>的運算式來獲得,以及它的類型(可選),如果不指定它的類型,那就預設為是java.lang.String類型。如果rtexprvalue元素被定義為true或yes,那麼在type元素中就定義了attribute的傳回型別。

<attribute>

<name>attr1</name>

<required>true|false|yes|no</required>

<rtexprvalue>true|false|yes|no</rtexprvalue>

<type>attribute的傳回型別(只用當rtexprvalue為真是才有效)</type>

</attribute>

如果tag的某個屬性不是必須的,那tag處理類會自動提供一個預設值。

例如,在logic:present這個tag標籤中定義了一個屬性叫parameter,但它不是必須的,而且它可以被諸如<%= …%>的運算式來賦值。

<tag>

<name>present</name>

<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class>

<body-content>JSP</body-content>

<attribute>

<name>parameter</name>

<required>false</required>

<rtexprvalue>true</rtexprvalue>

</attribute>

</tag>


屬性元素的校正


有關於tag標籤的有效值可以從tag庫的說明文檔中獲得,當JSP頁面被編譯時間,jsp引擎會強制性地參照TLD中定義的規則進行檢查。

還有一個方法也可以進行屬性元素的校正,就是先繼承類TagExtraInfo,然後調用它的isValid方法。這個類同時也起到提供tag中定義的指令碼變數資訊的作用。

IsValid方法通過TagData對象來傳遞屬性資訊,它包括著tag的所有的屬性名稱-值的資訊。由於校正發生在運行時刻,因此這個屬性的值將被賦值為TagData.REQUEST_TIME_VALUE。

例如tag標籤<tt:twa attr1=”value1” />在TLD中定義如下:

<attribute>

<name>attr1</name>

<required>true</required>

<rtexprvalue>true</rtexprvalue>

</attribute>


這個定義說明了attr1能在運行期間被賦值。

以下的isValid方法檢查attr1屬性的值是否屬於Boolean類型。注意由於attr1能在運行刻被賦值,那麼isValid方法必須檢查tag使用者是否對此tag進行了運行時刻賦值。


Public class TwaTEI extends TagExtraInfo

{

public boolean isValid(Tagdata data)

{

Object o = data.getAttribute(“attr1”);

If(o != null && o != TagData.REQUEST_TIME_VALUE)

{

if( ( (String)o).toLowerCase().equals(“true”) || 

((String)o).toLowerCase().equals(“false”) )

return true;

else

return false;

}

else

return true;

}

}

帶body的tag

tag處理類


如果tag標籤含有內容,那處理方式會略微有些不同,而且還要視tag處理類是否要與body互動的情況而定。如果要與body互動,那我們認為tag處理類要可能要對body進行操作。

Tag處理類不與body互動

如果tag處理類不與body互動,tag處理類應該實現Tag介面或從TagSupport中派生,如果body要被計算,那麼doStartTag方法應返回 EVAL_BODY_INCLUDE,否則應返回SKIP_BODY。

如果tag處理類要對body反覆運算,則它應該實現IterationTag或從TagSupport中派生。如果tag處理類認為body還未計算完的話,那它的doStartTag方法和doAfterBody方法必須返回EVAL_BODY_AGAIN。

Tag處理類與body互動

如果tag處理類與body互動,那tag處理類應實現BodyTag介面或從BodyTagSupport中派生。這種tag處理類一般要實現doInitBody和doAfterBody方法。

Body允許一些方法來讀寫它的內容。Tag處理類可以調用body內容的getString或getReader方法來從body中提取資訊,也可用 writeOut(out) 方法來將body的內容寫入到out對象中。其中out對象通過tag處理類的getPreviousOut方法來獲得。

如果body的內容需要被計算,那麼doStartTag方法必須返回EVAL_BODY_BUFFERED,否則,它將返回 SKIP_BODY。

doInitBody 方法

此方法在body內容已經設好,但未被計算之前被調用。你可以根據不同的body內容來制定初始化策略。

doAfterBody方法

此方法在body內容已被計算後進行調用。

和doStartTag方法一樣,doAfterBody方法返回一個指示符指示是否要繼續計算body,如果要繼續計算,則doAfterBody應返回EVAL_BODY_BUFFERED,否則,它應返回SKIP_BODY。

release 方法

tag處理類調用此方法將它的狀態重設為初始狀態,並釋放所有的私人資源。


以下的例子讀取body的內容(其中含有一條sql語句),然後將它傳遞給一個對象,讓它進行查詢。由於此處body不須重新計算,所以doAfterBody會返回SKIP_BODY。


Public class QueryTag extends BodyTagSupport

{

public int doAfterBody() throws JspTagException

{

BodyContent bc = getBodyContent();

//將body的內容以字串的格式提取出來

String query = bc.getString();

//清除body

bc.clearBody();

try{

Statement stmt = connection.createStatement();

Result result = stmt.executeQuery(query);

}catch(SQLException e){

throw new JspTagException(“queryTag: “ + e.getMessage() );

return SKIP_BODY;

}

}


body-content元素


由於tag可能會有body,你必須用body-content元素來指定body內容的類型:

<body-content>JSP|tagdependent</body-content>


如果body的內容是定製的或內部的tag、指令碼元素、或HTML廣本,則歸類為JSP類型。其他的類型,比如上面代碼所述的?D?D將sql statement類傳給 query tag的這種類型應該標為tagdependent。

注意:實際上body-content的值並不影響tag處理類對body內容的處理,它僅僅是被tag編輯工具用來描述此body的內容。


用tags定義指令碼變數

tag處理類


tag處理類負責建立或設定頁面中定義的指令碼變數,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法來實現。一般來說,tag處理類通過指令碼變數的名稱來擷取它,指令碼變數的名稱一般可用get方法來獲得。

如果指令碼變數的值依賴於tag處理類中的上下文中某一對象,那它可用pageContext.getAttribute(name,scope)方法來找到那個對象。一般的處理過程是tag處理類先找到指令碼變數,再對其進行處理,然後用pageContext.setAttribute(name,object)的方法來設定它的新值。

對象的生存周期(scope)如下表:

對象的生存周期表

名字
可存取範圍
生存周期

page
當前頁面
一直有效,除非頁面向客戶提交響應或重新導向到一個新頁面

request
當前頁面或當前頁面重新導向到的頁面
一直有效,除非頁面向客戶提交響應

session
當前頁面或在同一瀏覽器視窗中的頁面
一直有效,除非關閉當前瀏覽器、逾時、網路故障

application
整個web應用程式的所有請求
一直有效,除非發生網路故障、伺服器故障

提供關於指令碼變數的資訊

以下樣本定義了一個名為“book”的指令碼變數,用來訪問程式中關於書的資訊:

<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” />

<font color=”red” size=”+2” >

<%= messages.getString(“CartRemoved”) %>

<strong><jsp:getProperty name=”book” property=”title” /></strong>

</font>

當包含此tag的JSP頁面被編譯時間,jsp引擎會自動產生關於此book的同步的代碼(同步可以避免幾個客戶同時訪問此book時造成的衝突),要產生同步代碼,jsp引擎需要知道此指令碼變數的如下資訊:

· 指令碼變數名稱

· 指令碼變數所屬的類

· 此指令碼變數是否引用了一個新的或已存在的對象

· 此指令碼變數的有效性

有兩種辦法可以向jsp引擎提供關於指令碼變數的資訊:在TLD中定義variable子項目,或用tei-class子項目定義一個額外tag資訊類。用variable最簡單,但可能降低了一些靈活性。

Variable元素

Variable元素有如下子項目:

· name-given ?D?D 給出的名字,是一個常量

· name-from-attribute?D?D 屬性名稱,在編譯時間給出的屬性名稱

name-given或name-from-attribute兩者必須選一,但以下子項目是可選的:

· variable-class?D?D變數的類型,預設為java.lang.String。

· declare?D?D此指令碼變數是否引用了一個新對象,預設為True。

· scope?D?D指令碼變數的範圍,預設為NESTED。下表描述了scope的幾種類型:

指令碼變數的有效範圍


有效性
方法

NESTED
在tag標籤的開始和結束之間
如果tag處理類實現BodyTag介面,則在doInitBody和doAfterBody中調用,否則在doStartTag中調用

AT_BEGIN
從tag標籤的開始一直到頁面結束
如果tag處理類實現BodyTag介面,則在doInitBody、doAfterBody和doEndTag中調用,否則在doStartTag和doEndTag中調用

AT_END
從tag標籤的結束一直到頁面結束
在doEndTag中調用

以struts為例,它的bean:define標籤的實現遵循JSP1.1規範,此規範要求使用額外tag資訊類來定義指令碼變數。Variable元素是JSP1.2規範中加入的。以bean:define標籤為例,你可以定義如下variable元素:

<tag>

<variable>

<name-from-attribute>id</name-from-attribute>

<variable-class>database.BookDetails</variable-class>

<declare>true</declare>

<scope>AT_BEGIN</scope>

</variable>

</tag>

額外tag資訊類

如果要定義一個額外tag資訊類,你要繼承javax.servlet.jsp.TagExtraInfo類。一個TagExtraInfo類必須實現getVariableInfo方法,此方法返回一個叫VariableInfo的數組類,它包括如下資訊:

· 變數名

· 變數所屬類名

· 此變數是否引用了一個新對象

· 此變數的有效範圍

jsp引擎將一個名為data的參數傳給getVariableInfo方法,data中包括tag標籤中的所有“屬性名稱?D?D屬性值”對。它可以用來向VariableInfo對象提供指令碼變數的名字和類名。

以struts為例,它在bean:define標籤中定義了一個名為DefineTei的額外tag資訊類,用來向指令碼變數提供資訊。由於指令碼變數的名稱(book)和類名(database.BookDetails)是通過tag標籤的屬性來傳遞的,它們一般定義在VariableInfo的構建代碼中,並且可用data.getAttributeString方法來得到這些資訊。如果要允許book指令碼變數能在從tag開始直到整個JSP頁面結束的範圍內都可用的話,那它的範圍應設為AT_BEGIN。如下所示:


public class DefineTei extends TagExtraInfo

{

public VariableInfo[] getVariableInfo(TagData data)

{

String type = data.getAttributeString(“type”);

If( type == null)

type = “java.lang.Object”;

return new VariableInfo[] {

new VariableInfo(data.getAttributeString(“id”), 

type,

true,

VariableInfo.AT_BEGIN)

};

}

}


注意:關於額外tag資訊類的類名必須要在TLD中的tag標籤下的tei-class子項目中定義。因此,DefineTei的tei-class中的定義看起來如下:
<tei-class>
org.apache.struts.taglib.bean.DefineTagTei
</tei-class>


具有協作關係的tag


tag通過共用對象來進行協作,JSP支援人員2種方式的對象共用。

第一種方法是使用pageContext對象進行對象的共用(可支援JSP頁面和tag處理類之間的共用),如果在一個tag處理類中要調用由另一個tag處理類建立的對象,可調用pageContext.getAttribute(name, scope)方法。

第二各方式的共用是對於tag之間有嵌套關係而言的,外層的tag所建立的對象對於內層的tag來說是可以共用的。這種形式的共用的好處是減少了可能存在的重名衝突。

要訪問一個嵌套tag建立的對象,tag處理類必須先找到此嵌套tag對象,可用TagSupport的靜態方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在當不確定此tag是否為嵌套tag對象時使用。一旦它的父類被找到,它就能訪問其所有動態或靜態建立的對象。靜態建立的對象是父類的成員,而動態建立的對象可能是父類的私人對象。諸如此類的對象可以用tag處理類的setValue方法來儲存,用getValue方法來獲得。

下例闡述了以上兩種共用對象的方法。在這個例子當中,一個查詢tag檢查一個名為connection的屬性名稱是否在doStartTag中被設定。如果connection屬性被設定,tag處理類從pageContext中得到這個connection對象。否則,此tag處理類先找到它的父tag處理類,然後從它的父tag處理類中找到connection對象。


public class QueryTag extends BodyTagSupport

{

private String connectionId;

public int doStartTag() throws JspException

{

String cid = getConnection();

if(cid != null)

{

//存在一個connection id,使用它。

connection = (Connection) pageContext.getAttribute(cid);

}

else

{

ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, 

ConnectionTag.class);

if(ancestorTag == null)

{

throw new JspTagException(“一個沒有connection屬性的查詢標籤必須被一個connection標記嵌套。”);

}

connection = ancestorTag.getConnection();

}

}


此查詢標籤在JSP頁面中的調用形式可以從以下2種定義中任選一種:

<tt:connection id=”con01” ...> ... </tt:connection>

<tt:query id=”balances” connection=”con01” >

SELECT account, balance FROM acct_table

where customer_num = <%= request.getCustno() %>

</tt:query>

<tt:connection ...>

<x:query id=”balances”>

SELECT account, balance FROM acct_table

where customer_num = <%= request.getCustno() %>

</x:query>

</tt:connection>

與此同時,在TLD中必須指定connection屬性為可選的,定義如下:

<tag>

...

<attribute>

<name>connection</name>

<required>false</required>

</attribute>

</tag>



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.