现在的位置: 首页 > 综合 > 正文

自定义标签之 带Body的标签库

2011年11月03日 ⁄ 综合 ⁄ 共 3368字 ⁄ 字号 评论关闭

自定义标签之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在每次循环完后都会调用。

抱歉!评论已关闭.