jsp自定义标签(taglib)编写的原理和实现
生活随笔
收集整理的這篇文章主要介紹了
jsp自定义标签(taglib)编写的原理和实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
jsp自定義標簽(taglib)編寫的原理和實現
轉:http://www.javaeye.com/topic/157737
個tag就是一個普通的java類,它惟一特別之處是它必須繼承TagSupport或者BodyTagSupport類。這兩個類提供了一些方法,負責jsp頁面和你編寫的類之間的交互,例如輸入,輸出。而這兩個類是由jsp容器提供的,無須開發人員自己實現。換句話說,你只需把實現了業務邏輯的類繼承TagSupport或者BodyTagSupport,再做一些特別的工作,你的類就是一個Tag。并且它自己負責和jsp 頁面的交互,不用你多操心。?
“特別的工作”通常有以下幾個步驟:?
[1]提供屬性的set方法,此后這個屬性就可以在jsp頁面設置。以jstl標簽為例 c:out value=""/,這個value就是jsp數據到tag之間的入口。所以tag里面必須有一個setValue方法,具體的屬性可以不叫value。例如setValue(String data){this.data = data;}?
這個“value”的名稱是在tld里以attribute元素存在的。?
取什么名字都可以,只需tag里提供相應的set方法即可。?
[2]處理 doStartTag 或 doEndTag 。這兩個方法是 TagSupport提供的。 還是以c:out value=""/為例,當jsp解析這個標簽的時候,在“<”處觸發 doStartTag 事件,在“>”時觸發 doEndTag 事件。通常在 doStartTag 里進行初始化,流程選擇操作,在 doEndTag 里后續頁面輸出控制。?
[3]編寫tld文件,就是把編寫的tag組件的信息以mxl形式告訴容器,它才好以一定步驟解釋tag組件?
[4]在jsp頁面導入tld。這樣,你的jsp頁面就可以使用自己的tag組件了。?
通常你會發現自己絕大多數活動都集中在 doStartTag 或 doEndTag方法里,如果在服務器端處理標簽中的正文或則是嵌套標簽時的話,還是過問一下doAfterBody。?
一個簡單的例子:OutputTag?
package test;?
import javax.servlet.jsp.JspException;?
import javax.servlet.jsp.JspWriter;?
import javax.servlet.jsp.tagext.TagSupport;?
public class OutputTag extends TagSupport {?
private String name=null;?
public void setName(String name) {?
this.name = name;?
}?
public int doEndTag() throws JspException?
{?
try {?
JspWriter out = pageContext.getOut();?
out.print("Hello! " + name);?
} catch (Exception e) { throw new JspException(e); }?
return EVAL_PAGE;?
}?
}?
簡要說明:?
1 如何輸出到jsp頁面:調用JspWriter JspWriter out = pageContext.getOut();out.print......記住這個方法就可以了。?
2 輸出后如何作處理,函數會返回幾個值之一。EVAL_PAGE 表示tag已處理完畢,返回jsp頁面。還有幾個值,例如 EVAL_BODY_AGAIN 和EVAL_BODY_INCLUDE等 跟流程控制有關.?
編寫tld?
<?xml version="1.0" encoding="ISO-8859-1" ?>?
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">?
<taglib>?
<tlib-version>1.0</tlib-version>?
<jsp-version>1.2</jsp-version>?
<short-name>test</short-name>?
<!--OutputTag-->?
<tag>?
<name>out</name>?
<tag-class>test.OutputTag</tag-class>?
<body-content>empty</body-content>?
<attribute>?
<name>name</name>?
<required>false</required>?
<rtexprvalue>false</rtexprvalue>?
</attribute>?
</tag>?
</taglib>?
在WEB-INF下新建tlds文件夾,把這個文件取名為test.tld,放到tlds文件夾下。引用時的路徑應該這樣:WEB-INF\tlds\test.tld?
關于tld的簡單說明:?
short-name:taglib的名稱,也稱為前綴。比如“c:out value=""/” 里的“c”?
name:tag的名字。例如“c:out value=""/” 里的"out”,我們的類也取名為out,由于有前綴作區分,不會同其他庫的同名tag組件混淆?
tag-class:完整的tag組件路徑,記著帶包名?
body-content:指tag之間的內容。例如c:out value="" ...... /c 起始和關閉標簽之間就是body-content。由于沒有處理body-content ,所以上面設為empty,如果是嵌套標簽,或則是要在服務器端處理標簽體的話,就是jsp了?
“attribute”里的name:屬性名字。例如c:out value=""/里的value。名字可任意取,只要類里提供相應的set方法即可。?
required:是否必填屬性。?
rtexprvalue:是否支持運行時表達式取值就是是否可以<%=%>或則是${}方式傳值。?
這是tag的強大功能。?
編寫jsp頁面?
<%@ page language="java"%>?
<%@ taglib uri="/WEB-INF/tlds/test.tld" prefix="test"%>?
<html>?
<body>?
Test Tag: <test:out name="TEST"/>?
</body>?
</html>?
啟動服務器,如果一切按照上面步驟的話,就能看到 Test Tag: Hello! TEST 字樣。最簡單的tag就這么出來了。并不難,是不是??
------------------------------------------------------------------?
Tag系列的Interface里定義的靜態int,通過他們也能一窺tag組鍵的執行流程,這幾個靜態值分別是:?
SKIP_BODY : 跳過了開始和結束標簽之間的代碼,一般是在doStartTag中使用?
EVAL_BODY_INCLUDE :處理嵌套的標簽,一般是在doStartTag中使用,由負責處理標簽正文的tag接口提供?
EVAL_BODY_BUFFERED :對包含的內容進行解析 一般是在doStartTag中使用,由負責處理標簽正文的bodyTag接口提供,目的是通知jsp容器作好讀取正文的工作(創建一個body-content包裝正文和獲取存放操作結果的out對象,便于以后的操作和輸出).?
EVAL_BODY_AGAIN:處理標簽正文,嵌套標簽的iteratorTag接口的使用?
SKIP_PAGE : 忽略剩下的頁面,一般是在doEndTag中使用?
EVAL_PAGE : 繼續執行下面的頁, 一般是在doEndTag中使用
個tag就是一個普通的java類,它惟一特別之處是它必須繼承TagSupport或者BodyTagSupport類。這兩個類提供了一些方法,負責jsp頁面和你編寫的類之間的交互,例如輸入,輸出。而這兩個類是由jsp容器提供的,無須開發人員自己實現。換句話說,你只需把實現了業務邏輯的類繼承TagSupport或者BodyTagSupport,再做一些特別的工作,你的類就是一個Tag。并且它自己負責和jsp 頁面的交互,不用你多操心。?
“特別的工作”通常有以下幾個步驟:?
[1]提供屬性的set方法,此后這個屬性就可以在jsp頁面設置。以jstl標簽為例 c:out value=""/,這個value就是jsp數據到tag之間的入口。所以tag里面必須有一個setValue方法,具體的屬性可以不叫value。例如setValue(String data){this.data = data;}?
這個“value”的名稱是在tld里以attribute元素存在的。?
取什么名字都可以,只需tag里提供相應的set方法即可。?
[2]處理 doStartTag 或 doEndTag 。這兩個方法是 TagSupport提供的。 還是以c:out value=""/為例,當jsp解析這個標簽的時候,在“<”處觸發 doStartTag 事件,在“>”時觸發 doEndTag 事件。通常在 doStartTag 里進行初始化,流程選擇操作,在 doEndTag 里后續頁面輸出控制。?
[3]編寫tld文件,就是把編寫的tag組件的信息以mxl形式告訴容器,它才好以一定步驟解釋tag組件?
[4]在jsp頁面導入tld。這樣,你的jsp頁面就可以使用自己的tag組件了。?
通常你會發現自己絕大多數活動都集中在 doStartTag 或 doEndTag方法里,如果在服務器端處理標簽中的正文或則是嵌套標簽時的話,還是過問一下doAfterBody。?
一個簡單的例子:OutputTag?
package test;?
import javax.servlet.jsp.JspException;?
import javax.servlet.jsp.JspWriter;?
import javax.servlet.jsp.tagext.TagSupport;?
public class OutputTag extends TagSupport {?
private String name=null;?
public void setName(String name) {?
this.name = name;?
}?
public int doEndTag() throws JspException?
{?
try {?
JspWriter out = pageContext.getOut();?
out.print("Hello! " + name);?
} catch (Exception e) { throw new JspException(e); }?
return EVAL_PAGE;?
}?
}?
簡要說明:?
1 如何輸出到jsp頁面:調用JspWriter JspWriter out = pageContext.getOut();out.print......記住這個方法就可以了。?
2 輸出后如何作處理,函數會返回幾個值之一。EVAL_PAGE 表示tag已處理完畢,返回jsp頁面。還有幾個值,例如 EVAL_BODY_AGAIN 和EVAL_BODY_INCLUDE等 跟流程控制有關.?
編寫tld?
<?xml version="1.0" encoding="ISO-8859-1" ?>?
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">?
<taglib>?
<tlib-version>1.0</tlib-version>?
<jsp-version>1.2</jsp-version>?
<short-name>test</short-name>?
<!--OutputTag-->?
<tag>?
<name>out</name>?
<tag-class>test.OutputTag</tag-class>?
<body-content>empty</body-content>?
<attribute>?
<name>name</name>?
<required>false</required>?
<rtexprvalue>false</rtexprvalue>?
</attribute>?
</tag>?
</taglib>?
在WEB-INF下新建tlds文件夾,把這個文件取名為test.tld,放到tlds文件夾下。引用時的路徑應該這樣:WEB-INF\tlds\test.tld?
關于tld的簡單說明:?
short-name:taglib的名稱,也稱為前綴。比如“c:out value=""/” 里的“c”?
name:tag的名字。例如“c:out value=""/” 里的"out”,我們的類也取名為out,由于有前綴作區分,不會同其他庫的同名tag組件混淆?
tag-class:完整的tag組件路徑,記著帶包名?
body-content:指tag之間的內容。例如c:out value="" ...... /c 起始和關閉標簽之間就是body-content。由于沒有處理body-content ,所以上面設為empty,如果是嵌套標簽,或則是要在服務器端處理標簽體的話,就是jsp了?
“attribute”里的name:屬性名字。例如c:out value=""/里的value。名字可任意取,只要類里提供相應的set方法即可。?
required:是否必填屬性。?
rtexprvalue:是否支持運行時表達式取值就是是否可以<%=%>或則是${}方式傳值。?
這是tag的強大功能。?
編寫jsp頁面?
<%@ page language="java"%>?
<%@ taglib uri="/WEB-INF/tlds/test.tld" prefix="test"%>?
<html>?
<body>?
Test Tag: <test:out name="TEST"/>?
</body>?
</html>?
啟動服務器,如果一切按照上面步驟的話,就能看到 Test Tag: Hello! TEST 字樣。最簡單的tag就這么出來了。并不難,是不是??
------------------------------------------------------------------?
Tag系列的Interface里定義的靜態int,通過他們也能一窺tag組鍵的執行流程,這幾個靜態值分別是:?
SKIP_BODY : 跳過了開始和結束標簽之間的代碼,一般是在doStartTag中使用?
EVAL_BODY_INCLUDE :處理嵌套的標簽,一般是在doStartTag中使用,由負責處理標簽正文的tag接口提供?
EVAL_BODY_BUFFERED :對包含的內容進行解析 一般是在doStartTag中使用,由負責處理標簽正文的bodyTag接口提供,目的是通知jsp容器作好讀取正文的工作(創建一個body-content包裝正文和獲取存放操作結果的out對象,便于以后的操作和輸出).?
EVAL_BODY_AGAIN:處理標簽正文,嵌套標簽的iteratorTag接口的使用?
SKIP_PAGE : 忽略剩下的頁面,一般是在doEndTag中使用?
EVAL_PAGE : 繼續執行下面的頁, 一般是在doEndTag中使用
總結
以上是生活随笔為你收集整理的jsp自定义标签(taglib)编写的原理和实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: eVC++就是eVC++啊
- 下一篇: CowNew开源-sql解析引擎和cow