BodyTag备用

在自定义标签之HelloWorld中用Tag和TagSupport实现了简单的HelloWorld,那么这篇记录带Body的标签开发,带有Body的Tag必须要实现javax.servlet.jsp.tagext.BodyTag接口,BodyTag接口中定义了一些处理标签体的方法 。
通过实现BodyTag接口,就可以方便地操作标签体,比如可以让标签体迭代多次等。BodyTag的处理过程如下:前4步与一般的标签体一样
1:当容器创建一个新的标签实例后,通过setPageContext设置标签的页面上下文。
2:使用setParent方法设置这个标签的上一级标签。如果没有上一级嵌套,设置为空。
3:设置标签的属性。这个属性在标签库描述文件中定义。如果没有定义属性就不调用此类方法。
4:调用 doStartTag方法,这个方法可以返回EVAL_BODY_INCLUDE和SKIP_BODY。当返回EVAL_BODY_INCLUDE时,就计算标签的BODY,如果返回SKIP_BODY,就不计算标签的BODY。
5:调用setBodyContent设置当前的BodyContent
6:调用doInitBody。如果在计算BodyContent时需要进行一些初始化,就在这个方法中进行。
7:每次计算完BodyTag后调用 doAfterBody。如果返回EVAL_BODY_TAG,表示继续计算一次BodyTag,直到返回SKIP_BODY才继续执行第 8 步。
8:调用doEndTag方法,这个方法可以返回EVAL_PAGE或者SKIP_PAGE。当返回 EVAL_PAGE时,容器在标签结束时继续计算JSP页面的其他部份,如果返回SKIP_PAGE,容器将在标签结果时停止计算JSP页面的其他部分。
9:调用release()方法释放标签程序占用的任何资源

好了,废话我也不希望多说,下面来一个实例:
A:标签的实现代码

package eflylab;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.util.Hashtable;
import java.io.Writer;
import java.io.IOException;

public class BodyTagExample extends BodyTagSupport
{
    int counts;//counts为迭代的次数。
    public BodyTagExample()
    {
        super();
    }
   
    /** *//**
     *设置counts属性。这个方法由容器自动调用。
     */
    public void setCounts(int c)
    {
        this.counts=c;
    }
   
    /** *//**
     *覆盖doStartTag方法
     */
     public int doStartTag() throws JspTagException 
     {  
         System.out.println("doStartTag");
         if(counts>0)
         {
             return EVAL_BODY_TAG;
         }
         else
         {
              return SKIP_BODY;
         }
    }
   
    /** *//**
     *覆盖doAfterBody方法
     */
    public int doAfterBody() throws JspTagException
    {
        System.out.println("doAfterBody"+counts);
        if(counts>1)
        {
            counts--;
            return EVAL_BODY_TAG;
         } 
         else
         {
            return SKIP_BODY;
         }
    }
   
   /** *//**
     *覆盖doEndTag方法
     */
    public int doEndTag() throws JspTagException
    {
         System.out.println("doEndTag");
        try
        { 
             if(bodyContent != null) 
             {
                 bodyContent.writeOut(bodyContent.getEnclosingWriter());
             }
        }
        catch(java.io.IOException e)
        {
            throw new JspTagException("IO Error: " + e.getMessage()); 
        }  
        return EVAL_PAGE; 
    }
   
     public void doInitBody() throws JspTagException{
      System.out.println("doInitBody");
     }
     public void setBodyContent(BodyContent bodyContent)
     {  
          System.out.println("setBodyContent");
          this.bodyContent=bodyContent;
         
     }
       
       
}
每次计算 完Body时,都会调用 doAfterBody方法。
B:标签描述文件mytag.tld中加入    <tag>   
        <name>loop</name>
        <tag-class>eflylab.BodyTagExample</tag-class>
        <body-content>jsp</body-content><!-- 必须为jsp -->
        <attribute>
              <name>counts</name><!-- 这个是我们资源源文件中的属性,同时源文件中必须要有setCounts(int counts)方法 -->
              <required>true</required><!-- 必需要给定 -->
              <rtexprvalue>true</rtexprvalue>
          </attribute>
    </tag>C:测试页面
<%@ taglib uri="/demotag" prefix="bodytag" %>
<html>
<head>
<title>body tag</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<HR>
<bodytag:loop counts="5">
   现在的时间是: <%=new java.util.Date()%><BR>
</bodytag:loop>
<HR> 
</BODY> 
</HTML>运行:

同时控制台:

这里打印的内容就是调用标签中方法的顺序。可以看出除了doAfterBody外,其他方法都只调用了一次。doAfterBody在每次循环完后都会调用。

你可能感兴趣的:(C++,c,jsp,servlet,C#)