top
Loading...
Taglib原理和實現之什么是Taglib
1、問題:Tag究竟是什么?如何實現一個Tag?

一個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里定義的。取什么名字都可以,只需tag里提供相應的set方法即可。

2)處理 doStartTag 或 doEndTag 。這兩個方法是 TagSupport提供的。 還是以<c:out value=""/>為例,當jsp解析這個標簽的時候,在“<”處觸發 doStartTag 事件,在“>”時觸發 doEndTag 事件。通常在 doStartTag 里進行邏輯操作,在 doEndTag 里控制輸出。

3)編寫tld文件。

4)在jsp頁面導入tld

這樣,你的jsp頁面就可以使用自己的tag了。

通常你會發現自己絕大多數活動都集中在 doStartTag 或 doEndTag 方法里。確實如此,熟悉一些接口和類之后,寫taglib很容易。正如《jsp設計》的作者所言:里面的邏輯稍微有點復雜,但畢竟沒有火箭上天那么難。

2、一個簡單的例子:OutputTag

package diegoyun;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
/**
* @author chenys
*/
public class OutputTag extends TagSupport
{
private String name=null;
public void setName(String name)
{
this.name = name;
}

public int doStartTag() 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>diego</short-name>
<!--OutputTag-->
<tag>
<name>out</name>
<tag-class>diegoyun.OutputTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>

在WEB-INF下新建tlds文件夾,把這個文件取名為diego.tld,放到tlds文件夾下。路徑應該這樣:WEB-INFldsdiego.tld
關于tld的簡單說明:

short-name:taglib的名稱,也稱為前綴。比如<c:out value=""/> 里的“c”

name:tag的名字。例如<c:out value=""/> 里的"out”,我們的類也取名為out,由于有前綴作區分,不會混淆

tag-class:具體的tag類。帶包名

body-content:指tag之間的內容。例如<c:out value=""> ...... </c> 起始和關閉標簽之間就是body-content。由于沒有處理body-content,所以上面設為empty

<attribute>里的name:屬性名字。例如<c:out value=""/>里的value。名字可任意取,只要類里提供相應的set方法即可。

required:是否必填屬性。

rtexprvalue:是否支持運行時表達式取值。這是tag的強大功能。以后我們會討論。暫時設為false

編寫jsp頁面

<%@ page language="java"%>
<%@ taglib uri="/WEB-INF/tlds/diego.tld" prefix="diego"%>
<html>
<body>
Test Tag:
<diego:out name="diegoyun"/>
</body>
</html>

我的編程環境是eclipse+tomcat.啟動服務器,如果一切按照上面步驟的話,就能看到 Test Tag: Hello! diegoyun 字樣

最簡單的tag就這么出來了。并不難,是不是?

作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗