JSP自定義標(biāo)簽的開發(fā)與應(yīng)用_第1頁
JSP自定義標(biāo)簽的開發(fā)與應(yīng)用_第2頁
JSP自定義標(biāo)簽的開發(fā)與應(yīng)用_第3頁
JSP自定義標(biāo)簽的開發(fā)與應(yīng)用_第4頁
JSP自定義標(biāo)簽的開發(fā)與應(yīng)用_第5頁
已閱讀5頁,還剩92頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、jsp自定義標(biāo)簽的開發(fā)與應(yīng)用在jstl提供了四個(gè)標(biāo)簽庫(核心標(biāo)簽庫、國際化標(biāo)簽庫、數(shù)據(jù)庫標(biāo)簽庫和xml標(biāo)簽庫),涉及到了幾十個(gè)標(biāo)簽。雖然這些標(biāo)簽可以完成比較復(fù)雜的工作,但它們?nèi)匀粺o法滿足程序中的特殊需求。因此,就需要用戶根據(jù)自己的需要來定制jsp標(biāo)簽,這種由用戶自己實(shí)現(xiàn)的jsp標(biāo)簽被稱為自定義標(biāo)簽。 .1 自定義標(biāo)簽基礎(chǔ) 自定義標(biāo)簽和jstl中的標(biāo)簽從技術(shù)上看沒有任何區(qū)別,可以將這些標(biāo)簽統(tǒng)稱為jsp標(biāo)簽。jsp標(biāo)簽在jsp頁面中通過xml語法格式被調(diào)用,當(dāng)jsp引擎將jsp頁面翻譯成servlet時(shí),就將這些調(diào)用轉(zhuǎn)換成執(zhí)行相應(yīng)的java代碼。也就是說,jsp標(biāo)簽實(shí)際上就是調(diào)用了某些java代碼

2、,只是在jsp頁面中以另外一種形式(xml語法格式)表現(xiàn)出來。 1.1 編寫輸出隨機(jī)數(shù)的標(biāo)簽 開始自定義標(biāo)簽的學(xué)習(xí)之前,在這一節(jié)先來實(shí)現(xiàn)一個(gè)簡單的自定義標(biāo)簽,以使讀者做一下熱身,同時(shí)讀者通過本節(jié)的例子可以對(duì)自定義標(biāo)簽的實(shí)現(xiàn)方法和過程有一個(gè)感性的認(rèn)識(shí)。 【實(shí)例1-1】 實(shí)現(xiàn)輸出隨機(jī)數(shù)的標(biāo)簽 1. 實(shí)例說明 在本例實(shí)現(xiàn)的自定義標(biāo)簽(random標(biāo)簽)的功能是輸出一個(gè)指定范圍的隨機(jī)整數(shù)。random標(biāo)簽有如下幾個(gè)特征: 沒有標(biāo)簽體。 有兩個(gè)屬性:min和max。其中min屬性表示生成隨機(jī)數(shù)的最小值,max屬性表示生成隨機(jī)數(shù)的最大值。min屬性的默認(rèn)值是0,max屬性的默認(rèn)值是integer.max_

3、value。 生成隨機(jī)數(shù)的范圍是min = random max。 random標(biāo)簽的標(biāo)準(zhǔn)調(diào)用形式如下: 其中“ct”是調(diào)用標(biāo)簽時(shí)的前綴,通過taglib指定的prefix屬性指定。上面的代碼的功能是輸出一個(gè)在1(包括)和100(不包括)之間的隨機(jī)數(shù)。 2. 編寫標(biāo)簽類 標(biāo)簽類是自定義標(biāo)簽的核心部分。實(shí)現(xiàn)標(biāo)簽類的方法有很多,但最簡單的方法是編寫一個(gè)從javax.servlet.jsp.tagext.tagsupport類繼承的java類,并在該類中覆蓋tagsupport類的dostarttag方法。為了讀取標(biāo)簽中的屬性值,還需要在標(biāo)簽類中為每一個(gè)標(biāo)簽屬性提供一個(gè)相應(yīng)數(shù)據(jù)類型的標(biāo)簽類屬性以及該

4、屬性的setter方法(不需要getter方法)。生成隨機(jī)數(shù)的代碼需要放在標(biāo)簽類的dostarttag方法中。該標(biāo)簽類的實(shí)現(xiàn)代碼如下: package chapter1; import java.io.ioexception; import java.util.random; import javax.servlet.jsp.jspexception; import javax.servlet.jsp.tagext.tagsupport; public class randomtag extends tagsupport / 封裝random標(biāo)簽的兩個(gè)屬性的javabean屬性 private

5、 int min = 0; private int max = integer.max_value; / min屬性的setter方法 public void setmin(int min) this.min = min; / max屬性的setter方法 public void setmax(int max) this.max = max; / 覆蓋tagsupport類的dostarttag方法 / 當(dāng)遇到標(biāo)簽(也就是)的開始標(biāo)記時(shí)調(diào)用該方法 override public int dostarttag() throws jspexception try random random = n

6、ew random(); / 生成一個(gè)在min和max之間的隨機(jī)數(shù) int result = min + random.nextint(max - min); / 將生成的隨機(jī)數(shù)輸出到客戶端 pagecontext.getout().write(string.valueof(result); catch (ioexception e) / tagsupport類的dostarttag方法默認(rèn)返回skip_body,表示忽略自定義標(biāo)簽體 return super.dostarttag(); 在randomtag類的dostarttag方法中使用了一個(gè)pagecontext變量來獲得jspwrit

7、er對(duì)象(jsp的out內(nèi)置對(duì)象)。pagecontext變量是在tagsupport類中定義的一個(gè)類變量,該變量通過tagsupport類中的setpagecontext方法進(jìn)行賦值。實(shí)際上,setpagecontext方法是在tag接口中定義的,而tagsupport實(shí)現(xiàn)了tag接口的setpagecontext方法。servlet容器在調(diào)用dostarttag方法之前,會(huì)先調(diào)用tag接口的setpagecontext方法來初始化pagecontext變量。tag接口將在1.1.3節(jié)介紹,在這里只要知道所有的標(biāo)簽類都必須實(shí)現(xiàn)tag接口。為了簡化標(biāo)簽類的實(shí)現(xiàn),jsp api提供了一個(gè)tags

8、upport類,有了tagsupport類,用戶在編寫標(biāo)簽類時(shí)就不需要實(shí)現(xiàn)tag接口的所有方法了。 3. 編寫標(biāo)簽庫描述符文件(tld文件) 在jstl中有若干tld文件(詳見圖9.1),其中tld是tag library descriptor(標(biāo)簽庫描述符)的縮寫。要想使一個(gè)自定義標(biāo)簽正常工作,必須在tld文件中對(duì)該標(biāo)簽進(jìn)行配置。在tld文件中主要配置如下兩部分內(nèi)容: 標(biāo)簽庫的配置信息、標(biāo)簽庫中具體標(biāo)簽的配置信息 標(biāo)簽庫的配置信息主要包括如下的內(nèi)容: 標(biāo)簽庫的版本:使用標(biāo)簽設(shè)置。 正常使用標(biāo)簽庫中的標(biāo)簽所需要的最低jsp版本:使用標(biāo)簽設(shè)置。 標(biāo)簽庫的默認(rèn)前綴:使用標(biāo)簽設(shè)置。 標(biāo)簽庫的uri:

9、使用標(biāo)簽設(shè)置。 標(biāo)簽庫的描述信息:使用標(biāo)簽設(shè)置。 標(biāo)簽的配置信息主要包括如下的內(nèi)容: 標(biāo)簽名:使用標(biāo)簽設(shè)置。 標(biāo)簽對(duì)應(yīng)的java類:使用標(biāo)簽設(shè)置。 標(biāo)簽體的類型:使用標(biāo)簽設(shè)置。 標(biāo)簽的描述信息:使用標(biāo)簽設(shè)置。 標(biāo)簽屬性的信息:每一個(gè)標(biāo)簽屬性對(duì)應(yīng)一個(gè)標(biāo)簽。在標(biāo)簽中可以指定標(biāo)簽名(使用標(biāo)簽設(shè)置)、該屬性是否必須指定(使用標(biāo)簽設(shè)置)、該屬性是否支持動(dòng)態(tài)屬性值(使用標(biāo)簽指定)等配置信息。 在web-inf目錄中建立一個(gè)jsp-taglib.tld文件,并在該文件中輸入如下的內(nèi)容: 自定義標(biāo)簽庫 1.1 ct 產(chǎn)生一個(gè)指定范圍的隨機(jī)數(shù) random chapter1.randomtag empty mi

10、n false false max false false 上面的配置代碼分為三部分:標(biāo)簽庫描述符文件頭、標(biāo)簽庫配置信息和random標(biāo)簽的配置信息。其中描述庫文件頭的內(nèi)容并不需要讀者去記憶,讀者只需要將jstl中的任何一個(gè)tld文件打開,將其中的標(biāo)簽庫描述文件頭部分復(fù)制過來即可。如果在標(biāo)簽庫描述符文件中包含中文,需要將encoding屬性改成“utf-8”或“gbk”。 標(biāo)簽庫的uri被元素指定為“”,該標(biāo)簽值就是taglib指令的uri屬性值。元素指定了標(biāo)簽庫的默認(rèn)前綴。要注意的是,該默認(rèn)前綴并不等于taglib指令的prefix屬性值,也就是說,taglib指令的prefix屬性值和元素

11、的值毫無關(guān)系。元素值實(shí)際上只是個(gè)推薦的標(biāo)簽庫前綴,如國際化標(biāo)簽庫的描述符文件(fmt.tld)中的元素值是“fmt”。在使用taglib指令引用某個(gè)標(biāo)簽庫時(shí),應(yīng)盡量使用元素推薦的標(biāo)簽庫前綴,當(dāng)然,也可以設(shè)置其他的前綴名。 random標(biāo)簽的標(biāo)簽體類型為“empty”(元素的值),表示該標(biāo)簽不支持標(biāo)簽體。關(guān)于元素支持的其他值,將在后面的部分詳細(xì)介紹。random標(biāo)簽的min屬性和max屬性都被設(shè)置可選的屬性,并且都不支持動(dòng)態(tài)屬性值。因此,在jsp頁面中設(shè)置random標(biāo)簽的這兩個(gè)屬性時(shí)只能直接為它們賦值。 4. 測試random標(biāo)簽 在chapter1目錄建立一個(gè)random.jsp文件(在本章

12、的所有jsp文件都放在該目錄下),并輸入如下的內(nèi)容: 在瀏覽器地址欄中輸入如下的url: http:/localhost:8080/demo/chapter1/random.jsp 瀏覽器顯示的輸出結(jié)果如圖1.1所示。 圖1.1 使用random標(biāo)簽產(chǎn)生1個(gè)10至200之間的隨機(jī)數(shù) 5. 程序總結(jié) 在部署和安裝自定義標(biāo)簽時(shí),tld文件應(yīng)放在web-inf目錄或其子目錄中(包括classes和lib目錄)。根據(jù)本例實(shí)現(xiàn)的random標(biāo)簽,可以將開發(fā)自定義標(biāo)簽的基本步驟總結(jié)如下: 實(shí)現(xiàn)一個(gè)標(biāo)簽類。該標(biāo)簽類可以實(shí)現(xiàn)tag接口、繼承tagsupport類或?qū)崿F(xiàn)其他的接口(這些接口將在后面的部分詳細(xì)介紹

13、)。 在標(biāo)簽庫描述符文件(tld文件)中配置自定義標(biāo)簽。 部署和安裝自定義標(biāo)簽。主要是將.class文件放在web-infclasses目錄中,并且將tld文件放在web-inf目錄或其子目錄中。 1.1.2 自定義標(biāo)簽?zāi)茏鍪裁?自定義標(biāo)簽除了可以讀取標(biāo)簽的屬性值外,還可以完成如下的工作: 單次執(zhí)行標(biāo)簽體中的內(nèi)容、重復(fù)執(zhí)行標(biāo)簽體中的內(nèi)容。 修改標(biāo)簽體中的內(nèi)容。 忽略jsp頁面中位于自定義標(biāo)簽后面的內(nèi)容。 在上一節(jié)介紹了tag接口中的dostarttag方法,該方法在web容器執(zhí)行到自定義標(biāo)簽的開始標(biāo)記時(shí)被調(diào)用。除了這個(gè)方法,在tag接口中還有doendtag方法,該方法在web容器中執(zhí)行到自定

14、義標(biāo)簽的結(jié)束標(biāo)記時(shí)被調(diào)用。 dostarttag方法可以通過返回如下兩個(gè)值來控制web容器是否執(zhí)行自定義標(biāo)簽的標(biāo)簽體: eval_body_include:執(zhí)行自定義標(biāo)簽的標(biāo)簽體。 skip_body:忽略(不執(zhí)行)自定義標(biāo)簽的標(biāo)簽體。 doendtag方法可以通過返回如下兩個(gè)值來控制web容器是否忽略jsp頁面中位于自定義標(biāo)簽后面的內(nèi)容: eval_page:繼續(xù)執(zhí)行自定義標(biāo)簽后面的內(nèi)容。 skip_page:忽略自定義標(biāo)簽后面的內(nèi)容。 其中eval_body_include、skip_body、eval_page和skip_page是在tag接口中定義的整型常量,所有實(shí)現(xiàn)tag接口的類都可

15、以直接使用這些常量。 除此之外,實(shí)現(xiàn)iterationtag接口的標(biāo)簽類還可以重復(fù)執(zhí)行標(biāo)簽體。iterationtag是tag接口的子接口。在iterationtag接口中有一個(gè)doafterbody方法,該方法可以通過返回如下兩個(gè)值來決定是否重復(fù)執(zhí)行自定義標(biāo)簽體的內(nèi)容: eval_body_again:重復(fù)執(zhí)行標(biāo)簽體的內(nèi)容。 skip_body:不再執(zhí)行標(biāo)簽體的內(nèi)容。 其中eval_body_again是在iterationtag接口中定義的整型常量。如果doafterbody方法返回skip_body,web容器會(huì)繼續(xù)執(zhí)行自定義標(biāo)簽的結(jié)束標(biāo)記,同時(shí)會(huì)調(diào)用doendtag方法。 從上面的描述

16、可以將web容器執(zhí)行自定義標(biāo)簽的過程總結(jié)如下: 1. web容器首先會(huì)執(zhí)行自定義標(biāo)簽的開始標(biāo)記,同時(shí)會(huì)調(diào)用標(biāo)簽類的dostarttag方法。 2. 如果dostarttag方法返回eval_body_include,web容器在執(zhí)行完標(biāo)簽體的內(nèi)容后,會(huì)調(diào)用標(biāo)簽類的doafterbody方法;如果dostarttag方法返回skip_body,doafterbody方法不會(huì)被調(diào)用,web容器會(huì)直接調(diào)用標(biāo)簽類的doendtag方法。 3. 如果doafterbody方法被調(diào)用,并且該方法返回eval_body_again,web容器會(huì)再次執(zhí)行標(biāo)簽體的內(nèi)容;如果doafterbody方法返回skip

17、_body,web容器會(huì)調(diào)用標(biāo)簽類的doendtag方法。 4. 如果doendtag方法返回eval_page,web容器會(huì)執(zhí)行自定義標(biāo)簽后面的內(nèi)容;如果doendtag方法返回skip_page,web容器會(huì)忽略自定義標(biāo)簽后面的內(nèi)容。 1.1.3 自定義標(biāo)簽api 自定義標(biāo)簽api中除了前面介紹的tag接口和iterationtag接口外,還有另外三個(gè)核心接口:jsptag、bodytag和simpletag。為了簡化自定義標(biāo)簽的編程工作,在自定義標(biāo)簽api中提供了tagsupport類、simpletagsupport類和bodytagsupport類。其中tagsupport類實(shí)現(xiàn)了i

18、terationtag接口,simpletagsupport類實(shí)現(xiàn)了simpletag接口,bodytagsupport類是tagsupport的子類,并實(shí)現(xiàn)了bodytag接口。上述五個(gè)接口和三個(gè)類的關(guān)系如圖1.2所示。 圖1.2 自定義標(biāo)簽api的核心接口和類的關(guān)系圖 上述的接口和類都在javax.servlet.jsp.tagext包中,讀者可以從如下的網(wǎng)址來查詢這些接口和類的詳細(xì)介紹: 訪問上面的網(wǎng)址將得到如圖1.3所示的頁面。 圖1.3 自定義標(biāo)簽api的官方文檔 上述五個(gè)接口的功能和作用如下: 1. jsptag接口 jsptag接口是所有自定義標(biāo)簽的父接口。它沒有任何屬性和方法。

19、tag接口和simpletag接口是jsptag的兩個(gè)直接子接口。其中jsptag和simpletag是jsp2.0新增的接口。在jsp2.0之前的版本的所有自定義標(biāo)簽的父接口是tag。因此,可以將所有實(shí)現(xiàn)tag接口的自定義標(biāo)簽稱為傳統(tǒng)標(biāo)簽,把所有實(shí)現(xiàn)simpletag接口的標(biāo)簽稱為簡單標(biāo)簽。在本章主要介紹傳統(tǒng)標(biāo)簽,簡單標(biāo)簽將在下一章詳細(xì)介紹。 2. tag接口 tag接口是所有傳統(tǒng)標(biāo)簽的父接口。該接口有兩個(gè)核心方法(dostarttag和doendtag)以及四個(gè)常量(eval_body_include、skip_body、eval_page和skip_page)。其中dostarttag方

20、法可以返回eval_body_include和skip_body,用于控制web容器是否執(zhí)行標(biāo)簽體的內(nèi)容;doendtag方法可以返回eval_page和skip_page,用于控制web容器是否執(zhí)行自定義標(biāo)簽后面的內(nèi)容。 3. iterationtag接口 iterationtag接口繼承了tag接口。iterationtag接口可用于實(shí)現(xiàn)需要循環(huán)執(zhí)行標(biāo)簽體內(nèi)容的自定義標(biāo)簽。在iterationtag接口中只有一個(gè)doafterbody方法和一個(gè)eval_body_again常量。doafterbody方法通過返回eval_body_again常量或tag接口中的skip_body常量來控制

21、web容器是否重復(fù)執(zhí)行標(biāo)簽體中的內(nèi)容。dostarttag方法、doafterbody方法和doendtag方法的調(diào)用關(guān)系詳見1.1.2節(jié)中的介紹。 并不是每一個(gè)自定義標(biāo)簽都需要循環(huán)執(zhí)行標(biāo)簽體的內(nèi)容,或是控制自定義標(biāo)簽后面的內(nèi)容是否被執(zhí)行。因此,jsp api中提供了一個(gè)實(shí)現(xiàn)iterationtag接口的tagsupport類。在tagsupport類中對(duì)tag接口和iterationtag接口中定義的方法都提供了默認(rèn)的實(shí)現(xiàn)。如dostarttag方法、doendtag方法和doafterbody方法都提供了默認(rèn)的返回值,代碼如下: public class tagsupport implem

22、ents iterationtag, serializable public tagsupport() public int dostarttag() throws jspexception return skip_body; public int doendtag() throws jspexception return eval_page; public int doafterbody() throws jspexception return skip_body; / 此處省略了tagsupport類中的其他方法和屬性 . . 標(biāo)簽類通過繼承tagsupport類,就不需要實(shí)現(xiàn)tag接口和

23、iteration接口中的每一個(gè)方法了,這樣將大大簡化自定義標(biāo)簽的開發(fā)工作。 4. bodytag接口 bodytag接口繼承了iterationtag接口。bodytag接口不僅擁有iterationtag接口的所有功能,而且還可以初始化和修改標(biāo)簽體的內(nèi)容。在bodytag接口中定義了兩個(gè)方法(doinitbody和setbodycontent)和兩個(gè)常量(eval_body_buffered和eval_body_tag),這兩個(gè)常量的含義相同。其中eval_body_tag常量是在jsp1.2中的遺留產(chǎn)物,在jsp的后續(xù)版本中可能不支持該常量,因此,建議使用eval_body_buffer

24、e常量。如果dostarttag方法返回eval_body_buffere,web容器就會(huì)將標(biāo)簽體的執(zhí)行結(jié)果保存在bodycontent對(duì)象中,然后web容器在處理標(biāo)簽時(shí)會(huì)調(diào)用標(biāo)簽類的setbodycontent方法將bodycontent對(duì)象傳入標(biāo)簽類的對(duì)象實(shí)例,接下來就可以在標(biāo)簽類的對(duì)象實(shí)例中處理標(biāo)簽體的執(zhí)行結(jié)果了。 由于bodytag接口及其父接口中定義了很多方法,為了在實(shí)現(xiàn)bodytag接口的類中不用再實(shí)現(xiàn)所有的方法,jsp api提供了一個(gè)bodytagsupport類,該類是tagsupport類的子類,并且實(shí)現(xiàn)了bodytag接口。在bodytagsupport類中改變了dost

25、arttag方法的默認(rèn)返回值,并且覆蓋了其他的核心方法,代碼如下: public class bodytagsupport extends tagsupport implements bodytag protected bodycontent bodycontent; public bodytagsupport() super(); public void setbodycontent(bodycontent b) this.bodycontent = b; public bodycontent getbodycontent() return bodycontent; / 改變了dostart

26、tag方法的默認(rèn)返回值 public int dostarttag() throws jspexception return eval_body_buffered; public int doendtag() throws jspexception return super.doendtag(); public void doinitbody() throws jspexception public int doafterbody() throws jspexception return skip_body; / 此處省略了bodytagsupport類的其他方法和屬性 . . 從前面的內(nèi)容可

27、知,自定義標(biāo)簽api涉及到了三個(gè)方法(dostarttag、doafterbody和doendtag)以及這三個(gè)方法可能返回的六個(gè)常量(eval_body_include、eval_body_buffere、skip_body、eval_body_again、eval_page和skip_page)。表1.1給出了這三個(gè)方法的返回值和這六個(gè)常量的關(guān)系。 表1.1 dostarttag、doafterbody和doendtag方法的返回值及其作用 方法名 返回值 dostarttag doafterbody doendtag eval_body_include 執(zhí)行標(biāo)簽體中的內(nèi)容(直接將標(biāo)簽體的

28、執(zhí)行結(jié)果輸出到out對(duì)象的緩沖區(qū)中) eval_body_buffere 執(zhí)行標(biāo)簽體中的內(nèi)容,并將標(biāo)簽體的執(zhí)行結(jié)果保存在bodycontent對(duì)象中,以備后續(xù)處理和加工 skip_body 忽略標(biāo)簽體的內(nèi)容 不再重復(fù)執(zhí)行標(biāo)簽體的內(nèi)容 * eval_body_again * 重復(fù)執(zhí)行標(biāo)簽體的內(nèi)容 * eval_page * * 繼續(xù)執(zhí)行自定義標(biāo)簽后面的內(nèi)容 skip_page * * 忽略自定義標(biāo)簽后面的內(nèi)容 5. simpletag接口 simpletag是jsp2.0新增的一個(gè)接口。該接口只有一個(gè)dotag方法,這個(gè)方法只在web容器執(zhí)行自定義標(biāo)簽時(shí)調(diào)用一次。所有的處理邏輯(包括是否執(zhí)行標(biāo)簽

29、體、重復(fù)執(zhí)行標(biāo)簽體等)都要寫在dotag方法中,因此,simpletag接口的功能相當(dāng)于bodytag接口,只是simpletag接口要比bodytag接口更容易使用。為了更進(jìn)一步簡化自定義標(biāo)簽的開發(fā)工作,jsp api提供了一個(gè)實(shí)現(xiàn)simpletag接口的simpletagsupport類,建議讀者在編寫簡單標(biāo)簽時(shí),標(biāo)簽類從simpletagsupport類繼承。 1.2 實(shí)現(xiàn)基本的自定義標(biāo)簽 一個(gè)自定義標(biāo)簽最基本的功能就是控制是否執(zhí)行標(biāo)簽體的內(nèi)容,以及控制是否執(zhí)行自定義標(biāo)簽后面的內(nèi)容。通過實(shí)現(xiàn)tag接口的dostarttag方法和doendtag方法可以很容易地完成這兩個(gè)功能。在tag接口

30、中還有定義了一些其他的方法(setpagecontext、setparent等),通過實(shí)現(xiàn)這些方法,可以編寫更高級(jí)的自定義標(biāo)簽。 1.2.1 tag接口 javax.servlet.jsp.tagext.tag接口是所有傳統(tǒng)標(biāo)簽的父接口,該接口定義了web容器處理自定義標(biāo)簽的基本方法。這些方法主要包括web容器執(zhí)行到標(biāo)簽的開始標(biāo)記時(shí)發(fā)生的標(biāo)簽開始事件(調(diào)用tag接口的dostarttag方法)和執(zhí)行到標(biāo)簽的結(jié)束標(biāo)記時(shí)發(fā)生的標(biāo)簽結(jié)束事件(調(diào)用tag接口的doendtag方法)。在tag接口中定義了四個(gè)常量,并由dostarttag方法和doendtag方法返回相應(yīng)的常量以通知web容器如何執(zhí)行自

31、定義標(biāo)簽。tag接口中定義的常量和方法如下所示: 1. tag接口中定義的常量 在tag接口中定義了如下四個(gè)整型常量: eval_body_include skip_body eval_page skip_page 其中eval_body_include和skip_body將作為dostarttag方法的返回值返回給web容器, web容器根據(jù)dostarttag方法的返回值來決定是否執(zhí)行自定義標(biāo)簽的標(biāo)簽體。eval_page和skip_page將作為doendtag方法的返回值返回給web容器, web容器根據(jù)doendtag方法的返回值決定是否執(zhí)行的自定義標(biāo)簽后面的內(nèi)容。 2. setpa

32、gecontext方法 在web容器創(chuàng)建標(biāo)簽類的對(duì)象實(shí)例后,會(huì)首先調(diào)用標(biāo)簽類的setpagecontext方法將pagecontext對(duì)象實(shí)例傳入標(biāo)簽類的對(duì)象實(shí)例,然后會(huì)調(diào)用標(biāo)簽類中的其他方法,這樣在標(biāo)簽類中的其他方法就可以使用pagecontext對(duì)象了。setpagecontext方法的定義如下: public void setpagecontext(pagecontext pagecontext) 3. setparent方法和getparent方法 web容器在調(diào)用標(biāo)簽類的setpagecontext方法后,會(huì)調(diào)用標(biāo)簽類的setparent方法,該方法用來設(shè)置當(dāng)前標(biāo)簽的父標(biāo)簽的對(duì)象實(shí)例

33、。通過getparent標(biāo)簽可以獲得當(dāng)前標(biāo)簽的父標(biāo)簽的對(duì)象實(shí)例。如果當(dāng)前標(biāo)簽沒有父標(biāo)簽,setparent方法的參數(shù)值為null。setparent方法和getparent方法的定義如下: public void setparent(tag t) public tag getparent() 4. dostarttag方法 web容器在依次調(diào)用setpagecontext方法、setparent方法以及設(shè)置當(dāng)前標(biāo)簽屬性的setter方法后,就會(huì)調(diào)用標(biāo)簽類的dostarttag方法。當(dāng)web容器調(diào)用dostarttag方法時(shí),就意味著web容器已經(jīng)開始處理當(dāng)前標(biāo)簽的開始標(biāo)記。如果dostartt

34、ag方法返回eval_body_include,web容器會(huì)在執(zhí)行完標(biāo)簽體后調(diào)用標(biāo)簽類的doendtag方法;如果doendtag方法返回skip_body,web容器并不會(huì)執(zhí)行標(biāo)簽體,而是直接調(diào)用標(biāo)簽類的doendtag方法。dostarttag方法的定義如下: int dostarttag() throws jspexception 5. doendtag方法 web容器在遇到標(biāo)簽的結(jié)束標(biāo)記時(shí),會(huì)調(diào)用標(biāo)簽類的doendtag方法。如果doendtag方法返回eval_page,web容器會(huì)繼續(xù)執(zhí)行結(jié)束標(biāo)記后面的內(nèi)容;如果doendtag方法返回skip_page,結(jié)束標(biāo)簽后面的內(nèi)容都不會(huì)被

35、執(zhí)行,也就是說,web容器在執(zhí)行當(dāng)前jsp頁面時(shí),執(zhí)行到標(biāo)簽的結(jié)束標(biāo)記處就會(huì)終止執(zhí)行當(dāng)前的jsp頁面。doendtag方法的定義如下: int doendtag() throws jspexception 6. release方法 jsp規(guī)范要求web容器必須在垃圾回收器回收標(biāo)簽類的對(duì)象實(shí)例時(shí)調(diào)用release方法,以便自定義標(biāo)簽可以利用該方法釋放所占用的相關(guān)資源。但jsp規(guī)范并沒有規(guī)定web容器調(diào)用release方法的具體時(shí)間,因此,release方法的調(diào)用時(shí)間由具體的web容器廠商決定。release方法的定義如下: public void release() 1.2.2 標(biāo)簽類中方法的調(diào)

36、用順序 在本節(jié)給出一個(gè)例子來測試標(biāo)簽類中方法的調(diào)用順序。本示例測試了web容器在調(diào)用自定義標(biāo)簽時(shí)調(diào)用標(biāo)簽類中的setpagecontext方法、setparent方法、設(shè)置標(biāo)簽屬性的setter方法、dostarttag方法、doendtag方法和release方法的順序。 【實(shí)例1-2】 測試標(biāo)簽類中方法的調(diào)用順序 1. 編寫invokeordertag類 invokeordertag是一個(gè)標(biāo)簽類,在該類中覆蓋了tagsupport類中的相關(guān)方法,并在這些方法的調(diào)用軌跡輸出到控制臺(tái)。invokeordertag類的實(shí)現(xiàn)代碼如下: package chapter1; import javax.

37、servlet.jsp.jspexception; import javax.servlet.jsp.pagecontext; import javax.servlet.jsp.tagext.tag; import javax.servlet.jsp.tagext.tagsupport; public class invokeordertag extends tagsupport / 定義了兩個(gè)屬性,用于設(shè)置和讀取標(biāo)簽的相應(yīng)屬性值 private string attr1; private string attr2; / 設(shè)置attr1屬性的值 public void setattr1(str

38、ing attr1) system.out.println(setattr1); this.attr1 = attr1; / 設(shè)置attr2屬性的值 public void setattr2(string attr2) system.out.println(setattr2); this.attr2 = attr2; override public void setpagecontext(pagecontext pagecontext) system.out.println(pagecontext); super.setpagecontext(pagecontext); override pu

39、blic void setparent(tag t) system.out.println(setparent); system.out.print(父標(biāo)簽:); system.out.println(t); super.setparent(t); public int dostarttag() throws jspexception system.out.println(dostarttag); return super.dostarttag(); public int doendtag() throws jspexception system.out.println(doendtag);

40、return super.doendtag(); override public void release() system.out.println(release); super.release(); 2. 安裝invokeorder標(biāo)簽 在jsp-taglib.tld文件中添加如下的內(nèi)容來安裝invokeorder標(biāo)簽: 測試標(biāo)簽類中方法的調(diào)用順序 invokeorder chapter1.invokeordertag empty attr1 false false attr2 false false 3. 編寫invokeorder.jsp頁面 invokeorder.jsp頁面用來調(diào)用

41、invokeorder標(biāo)簽。當(dāng)訪問invokeorder.jsp頁面后,就會(huì)在tomcat控制臺(tái)輸出相應(yīng)的方法調(diào)用軌跡。invokeorder.jsp頁面的代碼如下: 4. 測試invokeorder標(biāo)簽 在瀏覽器地址欄中輸入如下的url: http:/localhost:8080/demo/chapter1/invokeorder.jsp tomcat的控制臺(tái)將輸出如下的信息: pagecontext setparent 父標(biāo)簽:org.apache.taglibs.standard.tag.rt.core.iftag8c436b setattr2 setattr1 dostarttag d

42、oendtag 從上面的輸出信息可知,web容器會(huì)根據(jù)使用標(biāo)簽時(shí)屬性的位置來調(diào)用設(shè)置屬性值的setter方法(在invokeorder.jsp頁面中調(diào)用invokeorder標(biāo)簽時(shí),attr2屬性在attr1屬性前面)。 1.2.3 控制是否執(zhí)行標(biāo)簽體 在本節(jié)的例子通過dostarttag方法的返回值來控制web容器是否執(zhí)行標(biāo)簽體的內(nèi)容。 【實(shí)例1-3】 控制是否執(zhí)行標(biāo)簽體 1. 實(shí)例說明 本示例根據(jù)是否存在body請(qǐng)求參數(shù)來決定dostarttag方法的返回值。如果存在body請(qǐng)求參數(shù),dostarttag方法返回eval_body_include,否則返回skip_body。 2. 編寫d

43、isplaybodytag類 displaybodytag是一個(gè)標(biāo)簽類。該類負(fù)責(zé)判斷是否存在body請(qǐng)求參數(shù),并根據(jù)判斷結(jié)果決定dostarttag方法的返回值。displaybodytag類的實(shí)現(xiàn)代碼如下: package chapter1; import javax.servlet.jsp.jspexception; import javax.servlet.jsp.pagecontext; import javax.servlet.jsp.tagext.tag; import javax.servlet.jsp.tagext.tagsupport; public class displa

44、ybodytag extends tagsupport public int dostarttag() throws jspexception / 獲得body請(qǐng)求參數(shù)的值 string body = pagecontext.getrequest().getparameter(body); / 存在body請(qǐng)求參數(shù),返回eval_body_include if(body != null) return this.eval_body_include; / 不存在body請(qǐng)求參數(shù),返回skip_body else return this.skip_body; 3. 安裝displaybody標(biāo)簽

45、在jsp-taglib.tld文件中添加如下的內(nèi)容來安裝displaybody標(biāo)簽: 顯示標(biāo)簽體的內(nèi)容 displaybody chapter1.displaybodytag jsp 在上面的配置代碼中的元素的值是jsp,該值表示標(biāo)簽體的內(nèi)容可以是任意jsp頁面元素,jsp也是元素的默認(rèn)值。 4. 編寫displaybody.jsp頁面 displaybody.jsp頁面用來調(diào)用displaybody標(biāo)簽,在displaybody的標(biāo)簽體中有一行字符串,如果訪問displaybody.jsp頁面時(shí)包含body請(qǐng)求參數(shù),則displaybody標(biāo)簽會(huì)顯示這行字符串。displaybody.jsp

46、頁面的代碼如下: displaybody標(biāo)簽體的內(nèi)容: 如果存在請(qǐng)求參數(shù)body,則輸出標(biāo)簽體的內(nèi)容 5. 測試displaybody標(biāo)簽 在瀏覽器地址欄中輸入如下的url: http:/localhost:8080/demo/chapter1/displaybody.jsp?body 瀏覽器顯示的信息如圖1.4所示。 圖1.4 訪問displaybody.jsp頁面時(shí)帶body請(qǐng)求參數(shù) 如果在訪問displaybody.jsp頁面時(shí)不帶body請(qǐng)求參數(shù),則在瀏覽器中輸出的信息如圖1.5所示。 圖1.5 訪問displaybody.jsp頁面時(shí)不帶body請(qǐng)求參數(shù) 從圖1.5所示的輸出結(jié)果可以

47、看出,當(dāng)訪問displaybody.jsp頁面的url不包含body請(qǐng)求時(shí),標(biāo)簽體中的內(nèi)容并沒有輸出。 1.2.4 控制是否執(zhí)行標(biāo)簽后面的內(nèi)容 在本節(jié)的例子通過doendtag方法的返回值來控制web容器是否執(zhí)行標(biāo)簽后面的內(nèi)容。 【實(shí)例1-4】 控制是否執(zhí)行標(biāo)簽后面的內(nèi)容 1. 實(shí)例說明 本示例根據(jù)訪問jsp頁面的客戶端ip地址來決定是否執(zhí)行l(wèi)ocalpage標(biāo)簽后面的內(nèi)容。如果ip地址為,則允許執(zhí)行l(wèi)ocalpage標(biāo)簽后面的內(nèi)容,否則,web容器只執(zhí)行到localpage標(biāo)簽的結(jié)束標(biāo)記為止。 2. 編寫localpagetag標(biāo)簽 localpagetag是一個(gè)標(biāo)簽類,負(fù)責(zé)驗(yàn)證客戶端的ip地址,并根據(jù)驗(yàn)證結(jié)果決定是否執(zhí)行l(wèi)ocalpage標(biāo)簽后面的內(nèi)容。localpag

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論