如何建立一個簡單的標記處理器?
需要做三件事:
一、編寫標簽處理器(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》