帶有Body的Tag必須實(shí)現(xiàn)javax.servlet.jsp.tagext.BodyTag接口。
BodyTag的處理過程:
1.當(dāng)容器創(chuàng)建一個(gè)新的標(biāo)簽實(shí)例后,通過setPageContext來設(shè)置標(biāo)簽的頁面上下文。
2.使用setParent方法設(shè)置這個(gè)標(biāo)簽的上一級(jí)標(biāo)簽,如果沒有上一級(jí)嵌套,設(shè)置為null。
3.設(shè)置標(biāo)簽的屬性,這個(gè)屬性在標(biāo)簽庫(kù)描述文件中定義,如果沒有定義屬性,就不用調(diào)用此類方法。
4.調(diào)用doStartTag方法,這個(gè)方法可以返回EVAL_BODY_INCLUDE和SKIP_BODY,當(dāng)返回EVAL_BODY_INCLUDE時(shí),就計(jì)算標(biāo)簽的Body,如果返回SKIP_BODY,就不再計(jì)算標(biāo)簽的Body。
5.調(diào)用setBodyContent設(shè)置當(dāng)前的BodyContent。
6.調(diào)用doInitBody,如果在計(jì)算BodyContent時(shí)需要進(jìn)行一些初始化,就在這個(gè)方法中進(jìn)行。
7.每次計(jì)算完BodyTag后調(diào)用doAfterBody,如果返回EVAL_BODY_TAG(新的為EVAL_BODY_AGAIN),就表示繼續(xù)計(jì)算一次BodyTag,直到返回SKIP_BODY才繼續(xù)執(zhí)行第8步。
8.調(diào)用doEndTag方法,這個(gè)方法可以返回EVAL_PAGE或者SKIP_PAGE,當(dāng)返回EVAL_PAGE時(shí),容器將在標(biāo)簽結(jié)束時(shí)繼續(xù)計(jì)算JSP頁面其他的部分;如果返回SKIP_PAGE,容器將在標(biāo)簽結(jié)束時(shí)停止計(jì)算JSP頁面其他的部分。
9.調(diào)用release()方法釋放標(biāo)簽程序占用的任何資源。
下面是一個(gè)迭代器標(biāo)簽例子:
package com.rain.tag;
import Java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class BodyTagExample extends BodyTagSupport {
int counts; //counts為迭代的次數(shù)
public BodyTagExample(){
super();
}
/*
* 設(shè)置counts屬性,這個(gè)方法由容器自動(dòng)調(diào)用
*/
public void setCounts(int c){
this.counts=c;
}
@Override
public int doAfterBody() throws JspException {
// TODO Auto-generated method stub
System.out.println("doAfterBody"+counts);
if(counts>1){
counts--;
return EVAL_BODY_AGAIN;
}else{
return SKIP_BODY;
}
}
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
System.out.println("doEndTag");
try{
if(bodyContent!=null){
bodyContent.writeOut(bodyContent.getEnclosingWriter());
}
}catch(IOException e){
throw new JspTagException("IO Error:"+e.getMessage());
}
return EVAL_PAGE;
}
@Override
public void doInitBody() throws JspException {
// TODO Auto-generated method stub
System.out.println("doInitBody");
}
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
System.out.println("doStartTag");
if(counts>0){
return EVAL_BODY_AGAIN;
}else{
return SKIP_BODY;
}
}
@Override
public void setBodyContent(BodyContent arg0) {
// TODO Auto-generated method stub
System.out.println("setBodyContent");
this.bodyContent=arg0;
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns=" xmlns:xsi=" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>A tag library exercising SimpleTag handlers.</description>
<tlib-version>1.0</tlib-version>
<short-name>examples</short-name>
<uri>/demotag</uri>
<description>JSP應(yīng)用開發(fā)</description>
<tag>
<name>loop</name>
<tag-class>com.rain.tag.BodyTagExample</tag-class>
<body-content>jsp</body-content> Body-Content必須為JSP
<attribute>
<name>counts</name> 定義中必須有setCounts(int counts)方法
<required>true</required> 表示這個(gè)屬性是必須的
<rtexprvalue>true</rtexprvalue> 支持JSP表達(dá)式
</attribute>
</tag>
</taglib>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "<web-app>
<taglib>
<taglib-uri>/demotag</taglib-uri>
<taglib-location>/WEB-INF/mytag.tld</taglib-location>
</taglib>
</web-app>
<%@ page language="Java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="/demotag" prefix="bodytag" %>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<bodytag:loop counts="5">
現(xiàn)在時(shí)間是:<%=new Java.util.Date()%><br>
</bodytag:loop>
</body>
</html>
執(zhí)行結(jié)果:
控制臺(tái)打印出
doStartTag
setBodyContent
doInitBody
doAfterBody5
doAfterBody4
doAfterBody3
doAfterBody2
doAfterBody1
doEndTag
頁面顯示
現(xiàn)在時(shí)間是:Mon Jan 22 14:52:43 CST 2007
現(xiàn)在時(shí)間是:Mon Jan 22 14:52:43 CST 2007
現(xiàn)在時(shí)間是:Mon Jan 22 14:52:43 CST 2007
現(xiàn)在時(shí)間是:Mon Jan 22 14:52:43 CST 2007
現(xiàn)在時(shí)間是:Mon Jan 22 14:52:43 CST 2007