在jsp開發(fā)時(shí),當(dāng)jsp內(nèi)置標(biāo)簽以及JSTL標(biāo)簽庫都滿足不了需求時(shí),可以根據(jù)自己的需求來自定義標(biāo)簽。其實(shí)在jsp頁面使用標(biāo)簽就等同于調(diào)用某個(gè)對(duì)象的某個(gè)方法。
自定義標(biāo)簽步驟:先定義標(biāo)簽處理類(如繼承SimpleTagSupport類),再編寫TLD文件(標(biāo)簽庫描述庫文件)。
定義標(biāo)簽類可以編寫一個(gè)實(shí)現(xiàn)SimpleTag接口的類,
public class MyTag1 implements SimpleTag {
private PageContext context;
private JspFragment body;
@Override
public void doTag() throws JspException, IOException {
context.getOut().print("這是一個(gè)自定義標(biāo)簽");
}
@Override
public JspTag getParent() {
return null;
}
//下面三個(gè)方法都在doTag方法之前被tomcat之前調(diào)用,所以在doTag方法中就可以使用傳遞過來的對(duì)象
//設(shè)置標(biāo)簽體
@Override
public void setJspBody(JspFragment body) {
this.body =body;
}
//設(shè)置jsp上下文對(duì)象,它子類是PageContext
@Override
public void setJspContext(JspContext context) {
this.context = (PageContext) context;
}
//設(shè)置父標(biāo)簽
@Override
public void setParent(JspTag arg0) {
}
}
上面代碼中的doTag()的方法是每次執(zhí)行標(biāo)簽都會(huì)調(diào)用的方法,在這個(gè)方法之前有setJspBody()、setJspContext()以及setParent()方法都會(huì)比doTag先給Tomcat(服務(wù)器)調(diào)用,所以把傳遞過來的對(duì)象賦值給成員變量后,就可以在doTag方法里面就可以使用傳過來的對(duì)象了(這里沒有用到父標(biāo)簽所以setParent方法體沒寫代碼),其中在doTag方法里面使用PageContext對(duì)象獲取輸出流輸出了一句字符串。
編寫好標(biāo)簽處理類后,還需要在配置tld文件。
一般tld文件都放在WEB-INF下,這樣可以保證客戶端訪問不到
tld文件代碼(其實(shí)是一個(gè)xml)
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<tlib-version>1.0</tlib-version><!-- 自定義標(biāo)簽庫的版本號(hào) -->
<short-name>tag</short-name><!-- 自定義標(biāo)簽庫的簡(jiǎn)稱 -->
<uri>http://www.tianye.cn/tag1.0</uri><!-- 自定義標(biāo)簽庫的uri -->>
<tag>
<name>MyTag1</name><!—指定當(dāng)前標(biāo)簽名稱 -->
<tag-class>cn.tianye.tag.MyTag1</tag-class><!—指定當(dāng)前對(duì)應(yīng)標(biāo)簽出處理類 -->
<body-content>empty</body-content><!-- 標(biāo)簽體內(nèi)容格式 -->
</tag>
</taglib>
上面需要這注意的是<body-content>元素的可選值有
empty:也就是沒有標(biāo)簽體(如果在這里設(shè)置的是empty,那么在jsp頁面上就不能有標(biāo)簽體。)
JSP:傳統(tǒng)標(biāo)簽支持它,SimpleTag已經(jīng)不支持使用<body-content>JSP</body-content>
(標(biāo)簽內(nèi)容是可以有任何東西,比如EL,JSTL,HTML以及<%%>等)
scriptless:標(biāo)簽體內(nèi)容不能是java腳本,可以是EL,JSTL,字符串等,在SimpleTag中需要標(biāo)簽體可以使用這選項(xiàng)。
tagdependent:標(biāo)簽體內(nèi)容不作運(yùn)算,全由標(biāo)簽處理類自行處理,無論標(biāo)簽體內(nèi)容是EL,JSTL等,都不會(huì)作運(yùn)算。(這個(gè)基本沒有人會(huì)使用,因?yàn)橛闷饋硖闊?,什么都要自己處理?/strong>
配置好tld文件后就可以在jsp頁面上使用了,在使用自定義標(biāo)簽之前,需要先使用指令導(dǎo)入標(biāo)簽庫。
使用taglib導(dǎo)入標(biāo)簽庫,uri是tld文件的存放位置
<%@taglib prefix="t" uri="/WEB-INF/tlds/tianye.tag.tld" %>
使用自定義標(biāo)簽
<hr>
<h1><t:MyTag1/></h1>
<hr>
效果
自定義有標(biāo)簽體的標(biāo)簽
首先需要獲取標(biāo)簽體對(duì)象(JspBody)、把標(biāo)簽體內(nèi)容輸出到頁面、tld中指定標(biāo)簽內(nèi)容格式為scriptless。
標(biāo)簽處理類代碼
public class MyTag3 extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
this.getJspContext().getOut().print("***************<br>");
//執(zhí)行標(biāo)簽體的內(nèi)容,把結(jié)果輸出到頁面
Writer writer = this.getJspContext().getOut();
this.getJspBody().invoke(writer);
this.getJspContext().getOut().print("<br>***************");
}
}注:上面的類繼承了SimpleTagSupport類(SimpleTagSupport類實(shí)現(xiàn)了SimpleTag接口,也就是它已經(jīng)把所有Tomcat(服務(wù)器)傳遞的對(duì)象保存了,不需要我們自己操作保存?zhèn)鬟f過來的對(duì)象了,同時(shí)也提供了get方法供子類調(diào)用),重寫了doTag()方法,然后調(diào)用對(duì)象獲取當(dāng)前jsp輸出流,執(zhí)行標(biāo)簽體內(nèi)容,把結(jié)果寫入指定流中即輸出到頁面上。
tld文件(也就是<body-content>可選項(xiàng)改為scriptless,其他跟前面的一樣)
<tag>
<name>MyTag3</name>
<tag-class>cn.tianye.tag.MyTag3</tag-class>
<body-content>scriptless</body-content>
</tag>
在jsp頁面上使用標(biāo)簽(可以標(biāo)簽體可以是EL,也可以是字符串)
<%request.setAttribute("title", "It doesn't matter where you came from,"); %>
<h1><t:MyTag3>${requestScope.title }</t:MyTag3></h1>
<h1><t:MyTag3>what matters is who you choose to be.</t:MyTag3></h1>
效果
其中還可以自定義帶有屬性的標(biāo)簽,這里就不過多描述
聯(lián)系客服