如何建立一個簡單的標記處理器?
需要做三件事:
一、編寫標簽處理器(java文件)
二、在標簽庫描述符文件中描述該標簽 (TLD文件)
三、在jsp文件中引用該標簽
具體步驟:
step1:編寫一個擴展SimpleTagSupport的類
package foo; import javax.servlet.jsp.tagext.SimpleTagSupport; //mort import... public class SimpleTagTest1 extands SimpleTagSupport{ //這裡放標記處理代碼 }
step2: 實現doTag()方法
public void doTag() throws JspException, IOException { //在response中打印 "This is xxxxxx" getJspContext().getOut().print("This is xxxxxx"); }
step3: 為標記創建一個TLD (taglib description, 標簽庫描述符)
<?xml version="1.0" encoding="ISO-8859-1" ?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/jsee/web-jsptagLibrary_2_0.xsd" version="2.0"> <tlib-version>1.2</tlib-version> <uri>simpleTags</uri> <tag> <name>simple1</name> <description>xxxxxxxx</description> <tag-class>foo.SimpleTagTest1</tag-class> <body-content>empty</body-content> </tag> </taglib>
step4: 部署標記處理器和TLD
把TLD文件放在WEB-INF下,並把標記處理器放在WEB-INF/classes下,這裡當然還要遵循包目錄結構。換句話說,標記處理器類要與所有其他web應用Java類放在同一個位置上。
step5: 編寫一個使用標記的JSP
<%@ taglib prefix="myTags" uri="simpleTags" %> <html> <body> <myTags:simple1 %> </body> </html>
uri中的名稱要與TLD文件中的uri的名稱一致。
至此,就建立了一個簡單的自定義標簽。
自定義標簽還有幾種常見的情況,分別為:
一、有體的標記 (如,<x:label>...</x:label>,"..."為標簽的body)
二、標記體中使用了表達式 (如,<x:label> ${movie} </x:label>, "${movie}"為標簽的體中出現的EL表達式)
三、循環執行標簽體
四、含有屬性的簡單標簽 (如,<x:label movie="${movie}" />)
以下,將分別介紹這幾種情況:
情況一:編寫的是有體(body)的標記,如:
<myTags:simple2> This is the body //這個就是標記的body </myTags:simple2>
那麼在這種情況下,為了執行body內的語句就需要加入這樣一句話到doTag()方法中:
getJspBody().invoke(null);
invoke的意思是“處理標記的body,並把它打印到響應(response)中”。
null的意思是把內容輸出到響應(response),而不是輸出到什麼別的書寫器(Writer)上。
除此以外,TLD中的 “<body-content>empty</body-content>” 一欄也需要改動,要改為:
<body-content>scriptless</body-content>
之後會介紹四種不同的body-content的參數。
情況二、如果標記體使用了表達式,如:
<myTags:simple3> Message is : ${message} </myTags:simple3>
那麼這個表達式的賦值需要在標簽處理器的doTag()中完成,如:
getJspContext().setAttribute("message","wear sunscreen"); getJspBody().invoke(null);//一定要記得寫這句,否則標簽體不會執行
情況三、若想要循環輸出一個集合的數據,應該如何實現?如:
<table> <myTags:simple3> <tr><td>${movie}</td></tr> </myTags:simple3> </table>
顯然,希望通過循環輸出不同的movie來形成 一個表格。那麼標記處理器的doTag()方法應該改為:
String[] movies = {"Monsoon Wedding", "Saved!", ".. ..."}; public void doTag() throws JspException, IOException { for(int i = 0; i < movies.length; i++){ getJspContext().setAttribute("movie",movies[i]); getJspBody().invoke(null);//每次invoke,都會執行一次標簽body } }
情況四、如果這個簡單標記是有屬性的,怎麼辦?如:
<table> <myTags:simple5 movieList="${movieCollection}"> <tr> <td>${movie.name}</td> <td>${movie.genre}</td> </tr> </myTags:simple5> </table>
由於標記中出現了屬性,所以TLD中的描述必須反映這一情況,因此TLD應調整為:
<?xml version="1.0" encoding="ISO-8859-1" ?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/jsee/web-jsptagLibrary_2_0.xsd" version="2.0"> <tlib-version>1.2</tlib-version> <uri>simpleTags</uri> <tag> <name>simple1</name> <description>xxxxxxxx</description> <tag-class>foo.SimpleTagTest1</tag-class> <body-content>empty</body-content> <attribute> <name>movieList</name> <required>true</required><!-- 說明movieList屬性是必需的 --> <rtexprvalue>true</rtexprvalue><!-- 說明movieList屬性可以是一個運行時表達式(不用非得是一個常量String) --> </attribute> </tag> </taglib>
另外,在標記處理器類中,也要對這一屬性有相應的體現:
public class SimpleTagTest5 extends SimpleTagSupport{ private List movieList; public void setMovieList(List movieList){ this.movieList = movieList; } public void doTag() .... }
補充:
<body-content></body-content>中可以寫入的參數有四種:
① empty
即標記體為空
② scriptless
這個標記不能有腳本元素,但可以有模板文本和EL, 還可以是定制和標准動作
③ tagdependent
標記體要看做是純文本,所以不會計算EL,也不會出發標記/動作
④ JSP
能放在JSP中的東西都能放在這個標記體中
《轉自:http://www.cnblogs.com/elaron/archive/2012/10/10/2717797.html》