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>