<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    IT人生
    專注于java相關(guān)技術(shù).
    posts - 53,comments - 87,trackbacks - 0
    準(zhǔn)的JSP 標(biāo)記可以調(diào)用JavaBeans組件或者執(zhí)行客戶的請(qǐng)求,這大大降低了JSP開(kāi)發(fā)的復(fù)雜度和維護(hù)量。JSP技術(shù)也允許你自定義taglib,其實(shí)換句話說(shuō),taglib可以看成是對(duì)JSP標(biāo)記的一種擴(kuò)展,正如xml是對(duì)html的一種擴(kuò)展一樣。taglib通常定義在tag標(biāo)簽庫(kù)中,這種標(biāo)簽庫(kù)存放著你自己定義的tag標(biāo)簽。簡(jiǎn)而言之,如果使用taglib,那么你可以設(shè)計(jì)自己的JSP標(biāo)記!

    一般來(lái)說(shuō),自定義tag標(biāo)簽主要用于操作隱藏對(duì)象、處理html提交表單、訪問(wèn)數(shù)據(jù)庫(kù)或其它企業(yè)級(jí)的服務(wù),諸如郵件和目錄操作等等。自定義tag標(biāo)簽的使用者一般都是那些對(duì)java編程語(yǔ)言非常精通,而且對(duì)數(shù)據(jù)訪問(wèn)和企業(yè)級(jí)服務(wù)訪問(wèn)都非常熟悉的程序員,對(duì)于HTML設(shè)計(jì)者來(lái)說(shuō),使得他可以不去關(guān)注那些較復(fù)雜的商業(yè)邏輯,而將精力放在網(wǎng)頁(yè)設(shè)計(jì)上。同時(shí),它也將庫(kù)開(kāi)發(fā)者和庫(kù)使用者進(jìn)行合理分工,自定義tag標(biāo)簽將那些重復(fù)工作進(jìn)行封裝,從而大大提高了生產(chǎn)力,而且可以使得tag庫(kù)可用于不同的項(xiàng)目中,完美地體現(xiàn)了軟件復(fù)用的思想。

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

    · 什么是自定義tag標(biāo)簽?

    · 怎么使用tag標(biāo)簽?

    o 聲明要使用的tag庫(kù)

    o 找到與之對(duì)應(yīng)的tag處理類(lèi)

    o tag標(biāo)簽的類(lèi)型

    · 自定義tag標(biāo)簽

    o tag處理類(lèi)

    o tag庫(kù)描述

    o tag標(biāo)簽示例

    o 帶屬性的tag

    o 帶body的tag

    o 定義了腳本變量的tag

    o 具有協(xié)作關(guān)系的tag

    · 自定義tag標(biāo)簽

    o 一個(gè)迭代tag的例子

    o 一個(gè)模板tag庫(kù)

    o tag處理類(lèi)到底是怎樣被調(diào)用的?


    什么是自定義的tag?

    一個(gè)自定義的tag標(biāo)簽是用戶定義的一種JSP標(biāo)記。當(dāng)一個(gè)含有自定義的tag標(biāo)簽的JSP頁(yè)面被jsp引擎編譯成servlet時(shí),tag標(biāo)簽被轉(zhuǎn)化成了對(duì)一個(gè)稱為tag處理類(lèi)的對(duì)象進(jìn)行的操作。于是當(dāng)JSP頁(yè)面被jsp引擎轉(zhuǎn)化為servlet后,實(shí)際上tag標(biāo)簽被轉(zhuǎn)化成為了對(duì)tag處理類(lèi)的操作。

    自定義tag標(biāo)簽有很多特色,諸如:

    · 可以在JSP頁(yè)面中自定義tag標(biāo)簽的屬性

    · 訪問(wèn)JSP頁(yè)面中的所有對(duì)象

    · 可以動(dòng)態(tài)地修改頁(yè)面輸出

    · 彼此這間可以相互通信。你可以先創(chuàng)建一個(gè)JavaBeans組件,然后在一個(gè)tag中調(diào)用此JavaBeans組件,同時(shí)可以在另一個(gè)tag中調(diào)用它。

    · tag允許相互嵌套,可以在一個(gè)JSP頁(yè)面中完成一些復(fù)雜的交互。


    使用tag標(biāo)簽


    本節(jié)主要描述怎樣在JSP頁(yè)面中使用tag標(biāo)簽,以及tag標(biāo)簽的不同類(lèi)型。

    要使用tag標(biāo)簽,JSP程序員必須做2件事:

    · 聲明此tag標(biāo)簽的tag庫(kù)

    · 實(shí)現(xiàn)此tag標(biāo)簽

    聲明tag標(biāo)簽所在的tag庫(kù)

    如果要使用tag標(biāo)簽,則應(yīng)用JSP的taglib指示符來(lái)指定其tag庫(kù)(注意:taglib要在在使用此tag標(biāo)簽之前聲明)

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

    uri屬性定義了唯一的標(biāo)簽庫(kù)描述(以下簡(jiǎn)稱TLD),它可以是直接是tld文件名或一個(gè)獨(dú)一無(wú)二的名字。prefix是用來(lái)區(qū)別其它TLD中和本TLD中有重名的tag的一種手段。

    TLD必須以.tld作為擴(kuò)展名,并且存放在當(dāng)前應(yīng)用的WEB-INF目錄或其子目錄下。你可以通過(guò)它的文件名直接引用它,也可以通過(guò)別的方式間接地引用它。

    以下taglib指示符直接引用一個(gè)TLD:

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

    以下的taglib指示符通過(guò)一個(gè)邏輯名稱間接地引用一個(gè)TLD:

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

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

    <taglib>

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

    <taglib-location>

    /WEB-INF/tutorial-template.tld

    </taglib-location>

    </taglib>


    實(shí)現(xiàn)此tag標(biāo)簽


    為了實(shí)現(xiàn)tag標(biāo)簽,你有2種方法來(lái)存放tag處理類(lèi)。一、讓tag處理類(lèi)以.class的方式存放于當(dāng)前應(yīng)用的WEB-INF/class子目錄下,二、如果tag處理類(lèi)是以JAR包的形式存在的話,那可以放在當(dāng)前應(yīng)用的WEB-INF/lib目錄下,如果tag處理類(lèi)要在多個(gè)應(yīng)用中共享,那么它就應(yīng)放在jsp服務(wù)器上的common/lib目錄下,對(duì)于tomcat來(lái)說(shuō),就是tomcat/common/lib目錄下。


    tag標(biāo)簽類(lèi)型


    自定義的tag標(biāo)簽遵循XML語(yǔ)法。它有一個(gè)開(kāi)始標(biāo)記和一個(gè)結(jié)束標(biāo)記,有的還有body(即文本節(jié)點(diǎn)):

    <tt:tag>

    body

    </tt:tag>


    一個(gè)不帶body的tag標(biāo)簽如下:

    <tt:tag />


    簡(jiǎn)單的tag標(biāo)簽

    一個(gè)沒(méi)有body和屬性的tag標(biāo)簽如下:

    <tt:simple />


    帶屬性的tag標(biāo)簽


    自定義標(biāo)簽可以有自己的屬性。屬性一般在開(kāi)始標(biāo)記中定義,語(yǔ)法為 attr=”value”。屬性的作用相當(dāng)于自定義標(biāo)簽的一個(gè)參數(shù),它影響著tag處理類(lèi)的行為。你可以在TLD中詳細(xì)定義它。

    你可以用一個(gè)String常量給一個(gè)屬性賦值,也可以通過(guò)表達(dá)式給它賦值,如<%= ...%>。以struts為例,它的logic:present標(biāo)簽就是用的String常量來(lái)給屬性賦值:

    <loglic:present parameter = “Clear”>

    而另一個(gè)標(biāo)簽logic:iterate是用表達(dá)式來(lái)給屬性賦值:

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

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


    帶body的tag標(biāo)簽

    一個(gè)自定義標(biāo)簽可以包含其它自定義標(biāo)簽、腳本變量、HTML標(biāo)記或其它內(nèi)容。

    在下述例子中,此JSP頁(yè)面使用了struts的logic:present標(biāo)簽,如果些標(biāo)簽定義了parameter=”Clear”的屬性,則將清除購(gòu)物車(chē)的內(nèi)容,然后打印出一條信息:

    <logic:present parameter=”Clear”>

    <% cart.clear(); %>

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

    你選擇了清除購(gòu)物車(chē)!

    </strong></font>

    </logic:present>


    到底是用屬性還是用body來(lái)傳遞信息?

    如上所述,我們既可以通過(guò)屬性,也可以通過(guò)body來(lái)傳遞信息。但一般來(lái)說(shuō),比較簡(jiǎn)單的類(lèi)型,如字符串或簡(jiǎn)單表達(dá)式最好采用屬性來(lái)傳遞信息。


    定義腳本變量的tag標(biāo)簽

    所謂腳本變量,是指JSP中可以調(diào)用的變量或?qū)ο蟆K捎蓆ag標(biāo)簽產(chǎn)生。以下示例闡述了一個(gè)tag標(biāo)簽定義了一個(gè)名為tx的由JNDI所定義的事務(wù)處理對(duì)象。腳本變量可以是ejb對(duì)象、事務(wù)、數(shù)據(jù)庫(kù)連接等等:

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

    <% tx.begin(); %>

    ...


    具有協(xié)作關(guān)系的tag標(biāo)簽

    自定義tag標(biāo)簽之間可以通過(guò)共享對(duì)象來(lái)實(shí)現(xiàn)協(xié)作。在下述例子中,標(biāo)簽tag1創(chuàng)建了一個(gè)名為obj1的對(duì)象,在標(biāo)簽tag2仍可以重復(fù)使用obj。

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

    <tt:tag2 attr1=”obj1” />

    在以下這個(gè)例子當(dāng)中,如果外層的tag標(biāo)簽創(chuàng)建了一個(gè)對(duì)象,那么其內(nèi)層的所有tag標(biāo)簽都可以使用這個(gè)對(duì)象。由于這樣產(chǎn)生的對(duì)象沒(méi)有一個(gè)指定的名字,那么就可以將少重名的沖突。這個(gè)例子闡述了一系列協(xié)作的嵌套對(duì)象。

    <tt:outerTag>

    <tt:innerTag />

    </tt:outerTag>

     

    Tag處理類(lèi)


    Tag處理類(lèi)必須實(shí)現(xiàn)Tag接口或BodyTag接口,不過(guò)現(xiàn)在一般都流行從TagSupport或BodyTagSupport類(lèi)中繼承,這些類(lèi)或接口都可以在javax.servlet.jsp.tagext包中找到。

    當(dāng)JSP引擎看到自己的JSP頁(yè)面中包含有tag標(biāo)簽時(shí),它會(huì)調(diào)用doStartTag方法來(lái)處理tag標(biāo)簽的開(kāi)頭,調(diào)用doEndTag方法來(lái)處理tag標(biāo)簽的結(jié)束。

    下表說(shuō)明不同類(lèi)型的tag所需要不同的處理過(guò)程:

    Tag處理類(lèi)的方法

    Tag標(biāo)簽類(lèi)型
    所調(diào)用的方法

    基本標(biāo)簽
    doStartTag, doEndTag, release

    帶屬性的標(biāo)簽
    doStartTag, doEndTag, set/getAttribute1...N, release

    帶內(nèi)容的標(biāo)簽
    doStartTag, doEndTag, release

    帶內(nèi)容的標(biāo)簽,且內(nèi)容重復(fù)循環(huán)
    doStartTag, doAfterBody, doEndTag, release

    帶內(nèi)容的標(biāo)簽,且內(nèi)容與JSP交互
    doStartTag, doEndTag, release, doInitBody, doAfterBody, release

    一個(gè)tag處理類(lèi)可以通過(guò)javax.servlet.jsp.PageContext來(lái)與JSP交互,通過(guò)javax.servlet.jsp.PageContext類(lèi),tag處理類(lèi)可以訪問(wèn)JSP中的request、session和application對(duì)像。

    如果tag標(biāo)簽是互相嵌套的,那內(nèi)層的tag處理類(lèi)可以通過(guò)它的parent屬性來(lái)訪問(wèn)上層的tag處理類(lèi)。

    一般情況都將所有的tag處理類(lèi)打成了JAR的包,以便于發(fā)布。


    Tag庫(kù)描述(簡(jiǎn)稱TLD)


    Tag庫(kù)是用xml語(yǔ)言描述的,TLD包括了tag庫(kù)中所有tag標(biāo)簽的描述,它一般用來(lái)被jsp服務(wù)器用來(lái)校驗(yàn)tag的語(yǔ)法正確性,或者被jsp開(kāi)發(fā)者用來(lái)開(kāi)發(fā)新的標(biāo)簽。

    TLD的文件擴(kuò)展名必須為.tld,而且必須放在當(dāng)前WEB應(yīng)用的WEB-INF目錄或其子目錄中。

    一個(gè)TLD的內(nèi)容的開(kāi)頭必須遵守標(biāo)準(zhǔn)的XML開(kāi)頭,用于描述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>來(lái)作為它的根元素,<taglib>的子元素如下表:


    <taglib>的子元素

    Element
    Description

    tlib-version
    Tag庫(kù)的版本

    jsp-version
    Tag庫(kù)所需要的jsp的版本

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

    uri
    用于確定一個(gè)唯一的tag庫(kù)

    display-name
    被可視化工具(諸如Jbuilder)用來(lái)顯示的名稱(可選)

    small-icon
    被可視化工具(諸如Jbuilder)用來(lái)顯示的小圖標(biāo)(可選)

    large-icon
    被可視化工具(諸如Jbuilder)用來(lái)顯示的大圖標(biāo)(可選)

    description
    對(duì)tag庫(kù)的描述(可選)

    listener
    參見(jiàn)下面listener元素

    tag
    參見(jiàn)下面tag 元素

    Listener元素

    一個(gè)tag庫(kù)可能定義一些類(lèi)做為它的事件偵聽(tīng)類(lèi),這些類(lèi)在TLD中被稱為listener 元素,jsp服務(wù)器將會(huì)實(shí)例化這些偵聽(tīng)類(lèi),并且注冊(cè)它們。Listener元素中有一個(gè)叫l(wèi)istener-class的子元素,這個(gè)元素的值必須是該偵聽(tīng)類(lèi)的完整類(lèi)名。

    Tag元素

    每個(gè)tag元素在tag庫(kù)中都要指出它的名字、類(lèi)名、腳本變量、tag的屬性。其中腳本變量的值可以直接在TLD中定義或通過(guò)tag附加信息的類(lèi)來(lái)取得。每個(gè)屬性描述了這個(gè)屬性是否可以省略,它的值是否可以通過(guò)<%= …%>這樣的JSP語(yǔ)法來(lái)獲得,以及屬性的類(lèi)型。

    每一個(gè)tag在TLD中對(duì)應(yīng)一個(gè)tag元素,下表是tag元素的子元素:

    Tag元素的子元素

    元素名稱
    描述

    name
    獨(dú)一無(wú)二的元素名

    tag-class
    Tag標(biāo)簽對(duì)應(yīng)的tag處理類(lèi)

    tei-class
    javax.servlet.jsp.tagext.TagExtraInfo的子類(lèi),用于表達(dá)腳本變量(可選)

    body-content
    Tag標(biāo)簽body的類(lèi)型

    display-name
    被可視化工具(諸如Jbuilder)用來(lái)顯示的名稱(可選)

    small-icon
    被可視化工具(諸如Jbuilder)用來(lái)顯示的小圖標(biāo)(可選)

    large-icon
    被可視化工具(諸如Jbuilder)用來(lái)顯示的大圖標(biāo)(可選)

    description
    此tag標(biāo)簽的描述

    variable
    提供腳本變量的信息(同tei-class)(可選)

    attribute
    Tag標(biāo)簽的屬性名

    以下章節(jié)介紹對(duì)于不同類(lèi)型的tag,如何具體地實(shí)現(xiàn)它們。


    簡(jiǎn)單的tag


    tag處理類(lèi)

    簡(jiǎn)單的tag處理類(lèi)必須實(shí)現(xiàn)Tag接口的doStartTag和doEndTag方法。當(dāng)jsp引擎碰到tag標(biāo)簽的開(kāi)頭時(shí),doStartTag被調(diào)用,因?yàn)楹?jiǎn)單的tag沒(méi)有body,所以此方法將返回 SKIP_BODY。當(dāng)jsp引擎碰到tag標(biāo)簽的結(jié)尾時(shí),doEndTag被調(diào)用,如果余下的頁(yè)面還要被計(jì)算,那它將返回EVAL_PAGE,否則將會(huì)返回SKIP_PAGE。

    以下是例子:對(duì)于標(biāo)簽 <tt:simple /> ,它的tag處理類(lèi)實(shí)現(xiàn)如下:


    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標(biāo)簽沒(méi)有內(nèi)容的話,那必須定義body-content元素為空,例如

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


    帶屬性的tag標(biāo)簽
    tag處理類(lèi)

    對(duì)于tag標(biāo)簽的每個(gè)屬性,你必須依照J(rèn)avaBeans規(guī)范來(lái)定義其屬性,以及get和set方法。以struts的logic:present 標(biāo)簽為例,

    <logic:present parameter=”Clear”>

    與此相應(yīng),此tag處理類(lèi)應(yīng)有如下方法和定義:


    protected String parameter = null;

    public String getParameter()

    {

    return this.parameter;

    }

    public void setParameter(String parameter)

    {

    this.parameter = parameter;

    }


    注意:如果你的屬性名為id,而且你的tag處理類(lèi)是從TagSupport類(lèi)繼承的,那你就不需要定義它的屬性和set和get方法,因?yàn)樗麄冊(cè)缫言赥agSupport被定義過(guò)了。

    Attribute元素

    對(duì)于tag標(biāo)簽的每個(gè)屬性,你必須定義它是否必須的,它的值是否可以用諸如<%= …%>的表達(dá)式來(lái)獲得,以及它的類(lèi)型(可選),如果不指定它的類(lèi)型,那就默認(rèn)為是java.lang.String類(lèi)型。如果rtexprvalue元素被定義為true或yes,那么在type元素中就定義了attribute的返回類(lèi)型。

    <attribute>

    <name>attr1</name>

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

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

    <type>attribute的返回類(lèi)型(只用當(dāng)rtexprvalue為真是才有效)</type>

    </attribute>

    如果tag的某個(gè)屬性不是必須的,那tag處理類(lèi)會(huì)自動(dòng)提供一個(gè)缺省值。

    例如,在logic:present這個(gè)tag標(biāo)簽中定義了一個(gè)屬性叫parameter,但它不是必須的,而且它可以被諸如<%= …%>的表達(dá)式來(lái)賦值。

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


    屬性元素的校驗(yàn)


    有關(guān)于tag標(biāo)簽的有效值可以從tag庫(kù)的說(shuō)明文檔中獲得,當(dāng)JSP頁(yè)面被編譯時(shí),jsp引擎會(huì)強(qiáng)制性地參照TLD中定義的規(guī)則進(jìn)行檢查。

    還有一個(gè)方法也可以進(jìn)行屬性元素的校驗(yàn),就是先繼承類(lèi)TagExtraInfo,然后調(diào)用它的isValid方法。這個(gè)類(lèi)同時(shí)也起到提供tag中定義的腳本變量信息的作用。

    IsValid方法通過(guò)TagData對(duì)象來(lái)傳遞屬性信息,它包括著tag的所有的屬性名-值的信息。由于校驗(yàn)發(fā)生在運(yùn)行時(shí)刻,因此這個(gè)屬性的值將被賦值為T(mén)agData.REQUEST_TIME_VALUE。

    例如tag標(biāo)簽<tt:twa attr1=”value1” />在TLD中定義如下:

    <attribute>

    <name>attr1</name>

    <required>true</required>

    <rtexprvalue>true</rtexprvalue>

    </attribute>


    這個(gè)定義說(shuō)明了attr1能在運(yùn)行期間被賦值。

    以下的isValid方法檢查attr1屬性的值是否屬于Boolean類(lèi)型。注意由于attr1能在運(yùn)行刻被賦值,那么isValid方法必須檢查tag用戶是否對(duì)此tag進(jìn)行了運(yùn)行時(shí)刻賦值。


    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處理類(lèi)


    如果tag標(biāo)簽含有內(nèi)容,那處理方式會(huì)略微有些不同,而且還要視tag處理類(lèi)是否要與body交互的情況而定。如果要與body交互,那我們認(rèn)為tag處理類(lèi)要可能要對(duì)body進(jìn)行操作。

    Tag處理類(lèi)不與body交互

    如果tag處理類(lèi)不與body交互,tag處理類(lèi)應(yīng)該實(shí)現(xiàn)Tag接口或從TagSupport中派生,如果body要被計(jì)算,那么doStartTag方法應(yīng)返回 EVAL_BODY_INCLUDE,否則應(yīng)返回SKIP_BODY。

    如果tag處理類(lèi)要對(duì)body反復(fù)運(yùn)算,則它應(yīng)該實(shí)現(xiàn)IterationTag或從TagSupport中派生。如果tag處理類(lèi)認(rèn)為body還未計(jì)算完的話,那它的doStartTag方法和doAfterBody方法必須返回EVAL_BODY_AGAIN。

    Tag處理類(lèi)與body交互

    如果tag處理類(lèi)與body交互,那tag處理類(lèi)應(yīng)實(shí)現(xiàn)BodyTag接口或從BodyTagSupport中派生。這種tag處理類(lèi)一般要實(shí)現(xiàn)doInitBody和doAfterBody方法。

    Body允許一些方法來(lái)讀寫(xiě)它的內(nèi)容。Tag處理類(lèi)可以調(diào)用body內(nèi)容的getString或getReader方法來(lái)從body中提取信息,也可用 writeOut(out) 方法來(lái)將body的內(nèi)容寫(xiě)入到out對(duì)象中。其中out對(duì)象通過(guò)tag處理類(lèi)的getPreviousOut方法來(lái)獲得。

    如果body的內(nèi)容需要被計(jì)算,那么doStartTag方法必須返回EVAL_BODY_BUFFERED,否則,它將返回 SKIP_BODY。

    doInitBody 方法

    此方法在body內(nèi)容已經(jīng)設(shè)好,但未被計(jì)算之前被調(diào)用。你可以根據(jù)不同的body內(nèi)容來(lái)制定初始化策略。

    doAfterBody方法

    此方法在body內(nèi)容已被計(jì)算后進(jìn)行調(diào)用。

    和doStartTag方法一樣,doAfterBody方法返回一個(gè)指示符指示是否要繼續(xù)計(jì)算body,如果要繼續(xù)計(jì)算,則doAfterBody應(yīng)返回EVAL_BODY_BUFFERED,否則,它應(yīng)返回SKIP_BODY。

    release 方法

    tag處理類(lèi)調(diào)用此方法將它的狀態(tài)重置為初始狀態(tài),并釋放所有的私有資源。


    以下的例子讀取body的內(nèi)容(其中含有一條sql語(yǔ)句),然后將它傳遞給一個(gè)對(duì)象,讓它進(jìn)行查詢。由于此處body不須重新計(jì)算,所以doAfterBody會(huì)返回SKIP_BODY。


    Public class QueryTag extends BodyTagSupport

    {

    public int doAfterBody() throws JspTagException

    {

    BodyContent bc = getBodyContent();

    //將body的內(nèi)容以字符串的格式提取出來(lái)

    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可能會(huì)有body,你必須用body-content元素來(lái)指定body內(nèi)容的類(lèi)型:

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


    如果body的內(nèi)容是定制的或內(nèi)部的tag、腳本元素、或HTML廣本,則歸類(lèi)為JSP類(lèi)型。其他的類(lèi)型,比如上面代碼所述的?D?D將sql statement類(lèi)傳給 query tag的這種類(lèi)型應(yīng)該標(biāo)為tagdependent。

    注意:實(shí)際上body-content的值并不影響tag處理類(lèi)對(duì)body內(nèi)容的處理,它僅僅是被tag編輯工具用來(lái)描述此body的內(nèi)容。


    用tags定義腳本變量

     

    tag處理類(lèi)


    tag處理類(lèi)負(fù)責(zé)創(chuàng)建或設(shè)置頁(yè)面中定義的腳本變量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法來(lái)實(shí)現(xiàn)。一般來(lái)說(shuō),tag處理類(lèi)通過(guò)腳本變量的名稱來(lái)獲取它,腳本變量的名稱一般可用get方法來(lái)獲得。

    如果腳本變量的值依賴于tag處理類(lèi)中的上下文中某一對(duì)象,那它可用pageContext.getAttribute(name,scope)方法來(lái)找到那個(gè)對(duì)象。一般的處理過(guò)程是tag處理類(lèi)先找到腳本變量,再對(duì)其進(jìn)行處理,然后用pageContext.setAttribute(name,object)的方法來(lái)設(shè)置它的新值。

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

    對(duì)象的生存周期表

    名字
    可訪問(wèn)范圍
    生存周期

    page
    當(dāng)前頁(yè)面
    一直有效,除非頁(yè)面向客戶提交響應(yīng)或重定向到一個(gè)新頁(yè)面

    request
    當(dāng)前頁(yè)面或當(dāng)前頁(yè)面重定向到的頁(yè)面
    一直有效,除非頁(yè)面向客戶提交響應(yīng)

    session
    當(dāng)前頁(yè)面或在同一瀏覽器窗口中的頁(yè)面
    一直有效,除非關(guān)閉當(dāng)前瀏覽器、超時(shí)、網(wǎng)絡(luò)故障

    application
    整個(gè)web應(yīng)用程序的所有請(qǐng)求
    一直有效,除非發(fā)生網(wǎng)絡(luò)故障、服務(wù)器故障

    提供關(guān)于腳本變量的信息

    以下示例定義了一個(gè)名為“book”的腳本變量,用來(lái)訪問(wèn)程序中關(guān)于書(shū)的信息:

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

    當(dāng)包含此tag的JSP頁(yè)面被編譯時(shí),jsp引擎會(huì)自動(dòng)生成關(guān)于此book的同步的代碼(同步可以避免幾個(gè)客戶同時(shí)訪問(wèn)此book時(shí)造成的沖突),要生成同步代碼,jsp引擎需要知道此腳本變量的如下信息:

    · 腳本變量名稱

    · 腳本變量所屬的類(lèi)

    · 此腳本變量是否引用了一個(gè)新的或已存在的對(duì)象

    · 此腳本變量的有效性

    有兩種辦法可以向jsp引擎提供關(guān)于腳本變量的信息:在TLD中定義variable子元素,或用tei-class子元素定義一個(gè)額外tag信息類(lèi)。用variable最簡(jiǎn)單,但可能降低了一些靈活性。

    Variable元素

    Variable元素有如下子元素:

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

    · name-from-attribute?D?D 屬性名,在編譯時(shí)給出的屬性名

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

    · variable-class?D?D變量的類(lèi)型,缺省為java.lang.String。

    · declare?D?D此腳本變量是否引用了一個(gè)新對(duì)象,缺省為T(mén)rue。

    · scope?D?D腳本變量的范圍,缺省為NESTED。下表描述了scope的幾種類(lèi)型:

    腳本變量的有效范圍


    有效性
    方法

    NESTED
    在tag標(biāo)簽的開(kāi)始和結(jié)束之間
    如果tag處理類(lèi)實(shí)現(xiàn)BodyTag接口,則在doInitBody和doAfterBody中調(diào)用,否則在doStartTag中調(diào)用

    AT_BEGIN
    從tag標(biāo)簽的開(kāi)始一直到頁(yè)面結(jié)束
    如果tag處理類(lèi)實(shí)現(xiàn)BodyTag接口,則在doInitBody、doAfterBody和doEndTag中調(diào)用,否則在doStartTag和doEndTag中調(diào)用

    AT_END
    從tag標(biāo)簽的結(jié)束一直到頁(yè)面結(jié)束
    在doEndTag中調(diào)用

    以struts為例,它的bean:define標(biāo)簽的實(shí)現(xiàn)遵循JSP1.1規(guī)范,此規(guī)范要求使用額外tag信息類(lèi)來(lái)定義腳本變量。Variable元素是JSP1.2規(guī)范中加入的。以bean:define標(biāo)簽為例,你可以定義如下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信息類(lèi)

    如果要定義一個(gè)額外tag信息類(lèi),你要繼承javax.servlet.jsp.TagExtraInfo類(lèi)。一個(gè)TagExtraInfo類(lèi)必須實(shí)現(xiàn)getVariableInfo方法,此方法返回一個(gè)叫VariableInfo的數(shù)組類(lèi),它包括如下信息:

    · 變量名

    · 變量所屬類(lèi)名

    · 此變量是否引用了一個(gè)新對(duì)象

    · 此變量的有效范圍

    jsp引擎將一個(gè)名為data的參數(shù)傳給getVariableInfo方法,data中包括tag標(biāo)簽中的所有“屬性名?D?D屬性值”對(duì)。它可以用來(lái)向VariableInfo對(duì)象提供腳本變量的名字和類(lèi)名。

    以struts為例,它在bean:define標(biāo)簽中定義了一個(gè)名為DefineTei的額外tag信息類(lèi),用來(lái)向腳本變量提供信息。由于腳本變量的名稱(book)和類(lèi)名(database.BookDetails)是通過(guò)tag標(biāo)簽的屬性來(lái)傳遞的,它們一般定義在VariableInfo的構(gòu)建代碼中,并且可用data.getAttributeString方法來(lái)得到這些信息。如果要允許book腳本變量能在從tag開(kāi)始直到整個(gè)JSP頁(yè)面結(jié)束的范圍內(nèi)都可用的話,那它的范圍應(yīng)設(shè)為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)

    };

    }

    }


    注意:關(guān)于額外tag信息類(lèi)的類(lèi)名必須要在TLD中的tag標(biāo)簽下的tei-class子元素中定義。因此,DefineTei的tei-class中的定義看起來(lái)如下:
    <tei-class>
    org.apache.struts.taglib.bean.DefineTagTei
    </tei-class>


    具有協(xié)作關(guān)系的tag


    tag通過(guò)共享對(duì)象來(lái)進(jìn)行協(xié)作,JSP技術(shù)支持2種方式的對(duì)象共享。

    第一種方法是使用pageContext對(duì)象進(jìn)行對(duì)象的共享(可支持JSP頁(yè)面和tag處理類(lèi)之間的共享),如果在一個(gè)tag處理類(lèi)中要調(diào)用由另一個(gè)tag處理類(lèi)創(chuàng)建的對(duì)象,可調(diào)用pageContext.getAttribute(name, scope)方法。

    第二各方式的共享是對(duì)于tag之間有嵌套關(guān)系而言的,外層的tag所創(chuàng)建的對(duì)象對(duì)于內(nèi)層的tag來(lái)說(shuō)是可以共用的。這種形式的共享的好處是減少了可能存在的重名沖突。

    要訪問(wèn)一個(gè)嵌套tag創(chuàng)建的對(duì)象,tag處理類(lèi)必須先找到此嵌套tag對(duì)象,可用TagSupport的靜態(tài)方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在當(dāng)不確定此tag是否為嵌套tag對(duì)象時(shí)使用。一旦它的父類(lèi)被找到,它就能訪問(wèn)其所有動(dòng)態(tài)或靜態(tài)創(chuàng)建的對(duì)象。靜態(tài)創(chuàng)建的對(duì)象是父類(lèi)的成員,而動(dòng)態(tài)創(chuàng)建的對(duì)象可能是父類(lèi)的私有對(duì)象。諸如此類(lèi)的對(duì)象可以用tag處理類(lèi)的setValue方法來(lái)保存,用getValue方法來(lái)獲得。

    下例闡述了以上兩種共享對(duì)象的方法。在這個(gè)例子當(dāng)中,一個(gè)查詢tag檢查一個(gè)名為connection的屬性名是否在doStartTag中被設(shè)置。如果connection屬性被設(shè)置,tag處理類(lèi)從pageContext中得到這個(gè)connection對(duì)象。否則,此tag處理類(lèi)先找到它的父tag處理類(lèi),然后從它的父tag處理類(lèi)中找到connection對(duì)象。


    public class QueryTag extends BodyTagSupport

    {

    private String connectionId;

    public int doStartTag() throws JspException

    {

    String cid = getConnection();

    if(cid != null)

    {

    //存在一個(gè)connection id,使用它。

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

    }

    else

    {

    ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, 

    ConnectionTag.class);

    if(ancestorTag == null)

    {

    throw new JspTagException(“一個(gè)沒(méi)有connection屬性的查詢標(biāo)簽必須被一個(gè)connection標(biāo)記嵌套。”);

    }

    connection = ancestorTag.getConnection();

    }

    }

     


    此查詢標(biāo)簽在JSP頁(yè)面中的調(diào)用形式可以從以下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>

     

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

    <tag>

    ...

    <attribute>

    <name>connection</name>

    <required>false</required>

    </attribute>

    </tag>



    減肥瘦身品總匯     值得信賴*脈脈美妝*正品現(xiàn)貨謝絕講價(jià)     〓深港商盟〓名品歐衣坊(美國(guó)休閑品牌AF系列)     QQ三國(guó)游戲幣及道具專賣(mài)店     小臉紅紅的瘦身旗艦店
    posted on 2009-04-20 12:46 龍華城 閱讀(231) 評(píng)論(0)  編輯  收藏

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 国产91色综合久久免费| 国产精品黄页免费高清在线观看 | 亚洲精品无码久久久久秋霞| 一区二区三区在线免费看| 亚洲人成人77777网站| 好吊色永久免费视频大全| 久久久久亚洲爆乳少妇无 | 中国一级全黄的免费观看| 国产亚洲AV夜间福利香蕉149| 美女18毛片免费视频| 亚洲精品高清在线| 国产黄在线观看免费观看不卡| 亚洲日产韩国一二三四区| 免费人成激情视频在线观看冫| 亚洲AV无码一区东京热| 2020因为爱你带字幕免费观看全集 | 污视频在线免费观看| 亚洲精品影院久久久久久| 成年午夜视频免费观看视频| 亚洲国产成人久久一区二区三区| 国产精品免费看香蕉| 一区二区三区免费看| 久久久久亚洲AV成人无码网站| 国内精品免费麻豆网站91麻豆| 亚洲精品成a人在线观看☆| 亚洲裸男gv网站| 久久久久久毛片免费播放| 亚洲男人天堂2018av| 国产乱辈通伦影片在线播放亚洲| 麻豆精品成人免费国产片| 国产成人精品日本亚洲18图| 一本久到久久亚洲综合| 暖暖免费日本在线中文| 亚洲真人无码永久在线观看| 亚洲精品无码av天堂| xx视频在线永久免费观看| 亚洲国产精品成人午夜在线观看| 亚洲综合色自拍一区| 无码国产精品一区二区免费式影视| 性色av极品无码专区亚洲| 亚洲AV无码乱码国产麻豆穿越|