BodyTagSupport类别继承自TagSupport类别,除了Tag与IterationTag之外,还实作了BodyTag接口, BodyTag接口中有两个方法:doInitBody()与setBodyContent()。在BodyTagSupport类别中, doStartTag()预设是传回EVAL_BODY_BUFFERED, 然后执行setBodyContent()与doInitBody()方法, setBodyContent()会设定BodyContent对象,它包括了一些卷标本体文字信息,及在处理卷标过程中写出数据至response的物 件,在这之后会进入doAfterBody()方法,您可以传回EVAL_BODY_AGAIN或是SKIP_BODY,如果传回前者,则照以上的流程再执行一次。
BodyTagSupport类别在doStartTag()传回EVAL_BODY_BUFFERED后,可以取得本体文字相关信息,也因而您继承了 BodyTagSupport之后,可以撰写具处理本体文字能力的卷标处理类别,下面举一个简单的例子,设计一个可以处理简单JSP程序代码的标签。
首先设计标签处理类别如下:
PreCodeTag.java
package onlyfun.caterpillar;
import java.io.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
public class PreCodeTag extends BodyTagSupport {
public int doAfterBody() {
try {
BodyContent body = getBodyContent();
String code = body.getString();
JspWriter out = body.getEnclosingWriter();
code = code.replaceAll("<%", "<%");
code = code.replaceAll(" ", " ");
code = code.replaceAll("\r\n", "<br>\r\n");
out.println("<table border=1>");
out.println("\t<td bgcolor=yellow>");
out.println(code);
out.println("\t</td>");
out.println("</table>");
}
catch(Exception e) {}
return SKIP_BODY;
}
}
您可以使用getBodyContent()取得在setBodyContent()时设定的BodyContent对象,这样就可以取得本体文字,另外 为了要能在标签处理过程中先写入信息至response中,我们使用getEnclosingWriter()方法取得 JspWriter对象;这个标签处理类别将<%、空白与换行符号分别换成<%;、 与<br>等适用 于网页内容的HTML码与标签,并使用一个简单的表格来显示卷标本体间处理过后的文字;接下来在tld文件中加入标签库定义:
preCode.tld... <tag> <description>Preserve JSP Code</description> <name>precode</name> <tag-class>onlyfun.caterpillar.PreCodeTag</tag-class> <body-content>tagdependent</body-content> </tag> ...
注意<body-content>之间设定的是tagdependent,这表示对本体文字不先作任何的处理,直接传入卷标处理类别,由卷标 处理类别自行处理本体文字,之后同样的,您可以在web.xml中加入tld档与uri对应的内容,以方便管理标签库,然后可以在JSP网页中这么使用:
<%@taglib prefix="caterpillar"
uri="http://caterpillar.onlyfun.net/"%>
<html>
<body>
<caterpillar:precode>
<%
out.println("Hello! World!");
%>
</caterpillar:precode>
</body>
</html>
执行的结果如下:
<html>
<body>
<table border=1>
<td bgcolor=yellow><br>
<%<br>
out.println("Hello!&World!");<br>
%><br>
</td>
</table>
</body>
</html>