帶有body的自定義tag的開發(fā)過程
今天學習帶body的自定義標簽,嘗試寫一個標簽,這個標簽可以迭代顯示標簽主體里面的內(nèi)容,迭代的次數(shù)由標簽的屬性指定. 首先,要說明的是,其實標簽也是一個java類,它是運行一個或兩個接口的javabean,然后再配合標簽描述文件(以.tld為擴展名),兩者結合就可以作出自己的自定義標簽庫了.呵呵,是不是覺得有點眉目了? 那么下面我們開始寫一個自己的java標簽類,作為有body的標簽,這個類必須實現(xiàn)javax.servlet.jsp.tagext.BodyTag接口. 下面我們看一下BodyTag這個接口中定義了那些方法來支持tag: public void doInitBody(); public void setBodyContent(javax.servlet.jsp.tagext.BodyContent); public int doAfterBody(); 那么由于BodyTag繼承了javax.servlet.jsp.tagext.Tag接口,所以我們再來看一下Tag中的方法: public void release(); public javax.servlet.jsp.tagext.Tag getParent(); public void setParent(javax.servlet.jsp.tagext.Tag); public int doEndTag(); public int doStartTag(); public void setPageContext(javax.servlet.jsp.PageContext); 說了這么多方法,是不是有點頭暈了?呵呵,那么究竟BodyTag的處理過程是怎么樣的呢?下面我們就來說一下它的處理流程: 1.當容器創(chuàng)建一個新的標簽實例后,通過setPageContext來設置標簽的頁面上下文. 2.使用setParent方法設置這個標簽的上一級標簽,如果沒有上一級嵌套,設置為null. 3.設置標簽的屬性,這個屬性在標簽庫描述文件中定義,如果沒有定義屬性,就不調(diào)用此類方法. 4.調(diào)用doStartTag方法,這個方法可以返回EVAL_BODY_INCLUDE和SKIP_BODY,當返回EVAL_BODY_INCLUDE時,就計算標簽的body,如果返回SKIP_BODY,就不再計算標簽的body. 5.調(diào)用setBodyContent設置當前的BodyContent. 6.調(diào)用doInitBody,如果計算BodyContent時需要進行一些初始化,就在這個方法中進行. 7.每次計算完Body后調(diào)用doAfterBody,如果返回EVAL_BODY_TAG,表示繼續(xù)計算一次Body,知道返回SKIP_BODY才繼續(xù)往下執(zhí)行. 8.調(diào)用doEndTag方法,這個方法可以返回EVAL_PAGE或者SKIP_PAGE,當返回EVAL_PAGE時,容器將在標簽結束時繼續(xù)計算JSP頁面其他的部分;如果返回SKIP_PAGE,容器將在標簽結束時停止計算JSP頁面其他的部分. 9.調(diào)用release()方法釋放標簽程序占用的任何資源。 知道了標簽處理的流程了,那么下面我們就開始寫一個自己的java類了 我的標簽類的源碼:
寫完了java類,下面我們該用一個描述文件來描述我們寫的這個類了: 我的tld描述文件源碼: <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java./j2ee/dtds/web-jsptaglibrary_1_1.dtd"> <taglib> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>Application Tag Library</shortname> <uri>http://jakarta./taglibs/struts-example-1.0</uri> <info>tag loop</info> <tag> <name>loop</name> <tagclass>test.jsp.tags.BodyTagExample</tagclass> <bodycontent>JSP</bodycontent> <attribute> <name>counts</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib> 我們對這個文件進行一個小小的說明: 最重要的是上面的黑體字部分,其他的部分我們可以拷貝粘貼就可以了。 tag中的name屬性:定義了我們的tag名稱,在后面會用到。 tag中的tagclass屬性:指定了我們這個tag的實現(xiàn)類。 tage中的bodycontent屬性:指定我們的頁面內(nèi)容是什么性質(zhì)的。(注意:在jsp開發(fā)中這里必須寫JSP) tage中的attribute屬性:定義了我們的這個tag可能有的屬性。 attribute中的name屬性:指定了屬性的名稱。它和我們類中定義的“int counts;”必須一樣,并且在類中還必須包含一個setCounts(int counts)方法,否則這個屬性就不能設置。 attribute中的required屬性:表示這個屬性是否是必須的。 attribute中的rtexprvalue屬性:表示這個屬性是否可以用JSP的程序段的結果輸出。 現(xiàn)在我們的tag就寫完了,下面就是我們怎么在頁面中用了。 首先,我們要在web.xml中聲明這個tag 我的web.xml源碼:
其次,我們要在頁面中引用這個tag。 我的jsp源碼:
好了,一個tag就開發(fā)完了,下面是頁面的顯示結果: 現(xiàn)在時間是:Thu Sep 22 12:33:31 CST 2005 現(xiàn)在時間是:Thu Sep 22 12:33:31 CST 2005 現(xiàn)在時間是:Thu Sep 22 12:33:31 CST 2005 現(xiàn)在時間是:Thu Sep 22 12:33:31 CST 2005 現(xiàn)在時間是:Thu Sep 22 12:33:31 CST 2005 這里是后臺打出來的信息: doStartTag... setBodyContent... doInitBody.... do After body...5 do After body...4 do After body...3 do After body...2 do After body...1 do end Tag... 一切OK了! |
|