|
|
內文: |
|
所需軟體 |
Tag Library基本結構 |
您的第一個標籤 |
描述您的標籤 |
測試並使用您的標籤 |
參考資料 |
|
|
|
簡介 使用JavaServer Pages來產生動態的網頁,大體可以分為兩種方式,一是 Scripting & Bean,這是利用 script 來撰寫程式,並在其中嵌入 JavaBean 來處理比較複雜的部份,另一種方式則是使用Tag Library,以 Tag 來取代一般常用的函式及運算,甚至用來連結資料庫(JDBC)、處理郵件(JavaMail)以及連結訊息伺服器(JMS)等。 在這部分的練習中,我們將會建立您的第一組Jsp Tag Library,這組Tag Library包含最簡單的功能–它將在您的JSP頁面中顯示一組字串。在整個練習過程中我們首先為您介紹一個Tag Library的基本結構與運作流程,接下來我們將為這個Tag撰寫描述子並將其部署到我們的Web Server,最後則是測試此Tag是否正常地運作。 所需軟體 可執行JSP頁面之WebServer:
本練習中我們使用Apache Tomcat 4.1.12 Tag Library基本結構 首先,我們所建立的每一個Tag都必須實作javax.servlet.jsp.tagext.Tag這個Interface Tag大約可分為兩大類型:Body Tag或Tag(有時稱Simple Tag),在本文中,我們將以Simple Tag作為練習。 下圖為一個Tag標籤的生命週期: 當使用者請求一張JSP頁面時,Container開始解析這張JSP頁面,而當解析至一個Tag時,Container將執行以下的動作:
- 使用此Tag的setPageContext()方法,設定目前的PageContext,以便於往後使用。
- 使用setParent()方法來設定Container所解析到包含此Tag的外層Tag標籤(假如沒有則傳入null)。
- 設定所有定義於此標籤內之屬性值。
- 呼叫doStartTag(),此方法將回傳EVAL_BODY_INCLUDE或SKIP_BODY整數值。假如回傳值為EVAL_BODY_INCLUDE時,兩Tag(Body Tag)標籤中的內容將繼續被解析,假如回傳值為SKIP_BODY,則Container將會略過此Tag之內容部分。
- 呼叫doEndTag(),這個方法將回傳EVAL_PAGE或SKIP_PAGE整數值,回傳值為EVAL_PAGE時,Container在結束此標籤後,將繼續解析剩餘的JSP內容;而當回傳值為SKIP_PAGE時,Container在解析完此標籤後,將停止解析剩餘的JSP內容。
- 最後,則會呼叫release()方法,您可以使用此方法來釋放此標籤所使用過的任何資源
下圖則為Tag Library的例外處理機制: 當呼叫doStartTag()或doEndTag()方法時出現錯誤,Container將發出一個JspTagException。 您的第一個標籤 由於這是我們的第一個標籤,我們將一步一步實作Tag介面中的每一個方法,而暫時先不使用一些J2EE中所提供較為便利的類別檔(例如:TagSupport或BodyTagSupport)。 首先,在您所建立的Web Project目錄中(例如 “C:\Tomcat4.1.12\webapps\taglib”)底下的 ”WEB-INF/classes” 新增一 'HelloWorldTag.java' 的檔案,其說明如下:
import javax.servlet.jsp.*;import javax.servlet.jsp.tagext.*;/*** A simple Tag that displays a Hello World message.*/public class HelloWorldTag implements Tag {
|
首先,我們要使此類別檔實作javax.servlet.jsp.tagext.Tag介面。
private PageContext pageContext;private Tag parent;
|
加入此兩變數以儲存目前之PageContext以及外層的Tag標籤。
/*** Constructor*/public HelloWorldTag() { super();}
|
實作此標籤之建構子。
/*** Method called at start of Tag* @return either a EVAL_BODY_INCLUDE or a SKIP_BODY*/public int doStartTag() throws javax.servlet.jsp.JspTagException { return SKIP_BODY;}
|
接下來,我們實作doStartTag()方法,並回傳SKIP_BODY代表我們將不考慮此標籤中所包含之JSP內容。
/*** Method Called at end of Tag* @return either EVAL_PAGE or SKIP_PAGE*/public int doEndTag() throws javax.servlet.jsp.JspTagException { try { pageContext.getOut().write("Hello World!"); } catch(java.io.IOException e) { throw new JspTagException("IO Error: " + e.getMessage()); } return EVAL_PAGE;}
|
以上的內容表示,我們使用PageContext將 "Hello World!" 此字串寫回client端中,也就是我們的JSP Page並且注意到,我們所回傳的值為EVAL_PAGE,表示Container將繼續完成剩餘的JSP內容,假如我們想讓此JSP在執行完此標籤後即停止顯示,則可將回傳值替換為SKIP_PAGE。
/*** Method called to releases all resources*/public void release() {}
|
由於此標籤結構簡單,所以我們並不需在此作任何釋放資源的動作。
/** Method used by the JSP container to set the current PageContext* @param pageContext, the current PageContext*/public void setPageContext(final javax.servlet.jsp.PageContext pageContext) { this.pageContext=pageContext;} /** Method used by the JSP container to set the parent of the Tag* @param parent, the parent Tag*/public void setParent(final javax.servlet.jsp.tagext.Tag parent) { this.parent=parent;}
|
以上兩方法由JSP Container所呼叫,用來設置此標籤之PageContext以及外層標籤。
** Method for retrieving the parent* @return the parent*/public javax.servlet.jsp.tagext.Tag getParent() { return parent;}}
|
最後,我們也要實作getParent()此方法。 接著請編譯您的程式碼。 描述您的標籤 當您的第一個標籤編譯完成後,我們需要一個描述子(descriptor)來描述這個標籤,以便讓您的JSP Page能夠認得這個標籤:
<taglib> <taglib-uri>mytags</taglib-uri> <taglib-location>/WEB-INF/taglib.tld</taglib-location> </taglib>
|
測試並使用您的標籤 為了測試您的標籤,請在您的Web Project目錄下加入如下的JSP Page
<%@ taglib uri="mytags" prefix="mt" %><HTML> <HEAD> <TITLE>Hello World!</TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF"> <HR> <mt:helloWorld/> <HR> </BODY> </HTML>
|
最後,開啟您的Web Server,並在瀏覽器中鍵入http://localhost/taglib/helloWorld.jsp 看到以上的畫面時,代表您已經完成了第一個Tag了。
|