自訂JSP標籤(tag)淺議

來源:互聯網
上載者:User
js 因為版本變化的關係,這篇文章未必有普適性



看這篇文章之前應該先看Sun的文章並最好動手實踐之

http://java.sun.com/developer/technicalArticles/xml/WebAppDev3/

並且知道J2EE API文檔的位置在

http://java.sun.com/j2ee/sdk_1.3/techdocs/api/index.html



自訂Tag其實並不是一件很困難的事情,就是猛一接觸,不知道該從何下手。推薦先看看Sun公司的一篇文章,看完了,大致就有了一個印象。在這裡無意去翻譯這篇簡單的文章,而是從這篇文章展開去說說。要說明的一點就是sun的文檔中代碼都是完全可用的,但是因為排版問題,代碼的分行有些地方不正確,直接copy的時候要仔細整理一下代碼,否則有可能會通不過編譯,部署的時候會給你一大堆異常。



自訂Tag使用的包是javax.servlet.jsp.tagext,如果編譯有問題,可以去Tomcat的\common\lib檔案夾下面找jsp-api.jar引用上就可以了。



這個包裡面的類和介面,基本上我們主要關心的就是以“Tag”結尾的那幾個,介面Tag和BodyTag,類TagSupport和BodyTagSupport,還有一個介面IterationTag,不過一般不會用到。其他的我們都可以看作是輔助類,協助擷取資訊什麼的。我們可以仔細看看J2EE的API文檔裡面關於這個包的類說明。



上面類名裡面的Body的意思可能一下子比較難理解。tag指的就是像<tagname></tagname>這樣的東西,Body就是夾在tag中間的東西,比如<tagname>I am Body</tagname>。這麼一來,這個tag也就成了BodyTag,因為它可以帶Body。所以設計tag也要事先考慮好帶不帶Body,不過現實考慮,好像沒有Body的tag應該也比較少吧。



Tag介面是這些類裡面的根,所以先看看裡面有什麼。API文檔裡面那個Lifecycle圖畫的很粗糙,不過也能大致看清楚。我們也不過分糾纏細節,大致關心的就是doStartTag() 和doEndTag() 這一段。每當你寫的tag在Jsp頁面裡面要被解釋的時候,伺服器就自動調用你的類裡面的doStartTag()函數來完成你定義的邏輯,當解析完標籤後調用doEndTag()。實現Tag介面來定製自己的tag無疑是最靈活的。但是,難度也比較大,我們定義自己的tag的時候完全不必要搞得這麼有內涵。

BodyTag跟Tag類也差別不大,BodyTag繼承自Tag和IterationTag,因為涉及了Body的原因,邏輯要複雜一些。API文檔裡面的Lifecycle圖也比較清晰。有必要好好看看。裡面主要說明的就是函數調用的順序。但是在具體應用中,不一定都要按部就班的走完這整個Lifecycle,如果要想控制這些調用的路線。就要借用函數的傳回值了,在上一個函數返回特定的值(都是已經定義好的常數)就可以改變伺服器調用下一個函數的行為來完成你自己的邏輯。看到這裡我也不禁佩服這些寫類庫的人,能想出這麼個辦法來解決問題。



為了方便我們開發,又提供了兩個帶“Support”的類來“支援”我們,方便我們開發。一般情況下我們只要繼承這兩個類中的一個,而且我覺得BodyTagSupport也更常用一些好像。要說明的一點就是兩個Support類中TagSupport是BodyTagSupport的父類。類中的getId()和setId()這兩個函數名並不是死的,這兩個“Id”應該在你的程式中替換成你的標籤名,比如你的tag名字是tagname,就是<tagname>,那麼函數名就變成了getTagname ()和getTagname ()。這樣的搞法原來在其他地方也有領教。(注意tagname第一個字母在函數名中大寫)變化的名字有伺服器自己去處理,無需編程者自己操心。原來函數名都是可以變化的,一定要注意。



說到這裡可以結合Sun的文檔的代碼看看,就明白了。



至於部署和.tlb檔案的格式,Sun文檔上也都有。不再贅述。最後附上整理的傳回值列表,這個我認為比較重要。



英文Evaluate大致是“評估,求值”的意思,這裡我們可以理解為伺服器“讀取,讀入,處理”的意思,翻譯的時候我就隨語境變通一下,下面加了底線,如果有不當,請指正。




EVAL_BODY_INCLUDE:把Body讀入存在的輸出資料流中,doStartTag()函數可用


EVAL_PAGE:繼續處理頁面,doEndTag()函數可用


SKIP_BODY:忽略對Body的處理,doStartTag()和doAfterBody()函數可用


SKIP_PAGE:忽略對餘下頁面的處理,doEndTag()函數可用


EVAL_BODY_TAG:已經廢止,由EVAL_BODY_BUFFERED取代


EVAL_BODY_BUFFERED:申請緩衝區,由setBodyContent()函數得到的BodyContent對象來處理tag的body,如果類實現了BodyTag,那麼doStartTag()可用,否則非法


EVAL_BODY_AGAIN:請求繼續處理body,返回自doAfterBody(),這個傳回值在你製作迴圈tag的時候是很有用的。我觀察了一下JSTL的原始碼,想看看它的ForEach怎麼編製的,但是一看裡面邏輯異常複雜,短時間不能看出頭緒,所以在這裡也不敢妄言,如果哪位仁兄有研究,還請不吝賜教。



:包裡面的其他類還沒有研究,如果有研究再另行寫個文檔。




相關文章

Cloud Intelligence Leading the Digital Future

Alibaba Cloud ACtivate Online Conference, Nov. 20th & 21st, 2019 (UTC+08)

Register Now >

Starter Package

SSD Cloud server and data transfer for only $2.50 a month

Get Started >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

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

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