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

自定义标签之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:标签的实现代码

None.gif package  eflylab;
None.gif
import  javax.servlet.jsp. * ;
None.gif
import  javax.servlet.jsp.tagext. * ;
None.gif
import  java.util.Hashtable;
None.gif
import  java.io.Writer;
None.gif
import  java.io.IOException;
None.gif
None.gif
public   class  BodyTagExample  extends  BodyTagSupport
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
int counts;//counts为迭代的次数。
InBlock.gif
    public BodyTagExample()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
super();
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** *//**
InBlock.gif     *设置counts属性。这个方法由容器自动调用。
ExpandedSubBlockEnd.gif     
*/

InBlock.gif    
public void setCounts(int c)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
this.counts=c;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** *//**
InBlock.gif     *覆盖doStartTag方法
ExpandedSubBlockEnd.gif     
*/

InBlock.gif     
public int doStartTag() throws JspTagException  
ExpandedSubBlockStart.gifContractedSubBlock.gif     
dot.gif{   
InBlock.gif         System.out.println(
"doStartTag");
InBlock.gif         
if(counts>0
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif
InBlock.gif             
return EVAL_BODY_TAG;
ExpandedSubBlockEnd.gif         }
 
InBlock.gif         
else 
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif
InBlock.gif              
return SKIP_BODY;
ExpandedSubBlockEnd.gif         }
 
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** *//**
InBlock.gif     *覆盖doAfterBody方法
ExpandedSubBlockEnd.gif     
*/

InBlock.gif    
public int doAfterBody() throws JspTagException 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        System.out.println(
"doAfterBody"+counts);
InBlock.gif        
if(counts>1)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            counts
--;
InBlock.gif            
return EVAL_BODY_TAG; 
ExpandedSubBlockEnd.gif         }
  
InBlock.gif         
else
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif
InBlock.gif            
return SKIP_BODY; 
ExpandedSubBlockEnd.gif         }
 
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif   
/** *//**
InBlock.gif     *覆盖doEndTag方法
ExpandedSubBlockEnd.gif     
*/

InBlock.gif    
public int doEndTag() throws JspTagException 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif         System.out.println(
"doEndTag");
InBlock.gif        
try 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{  
InBlock.gif             
if(bodyContent != null)  
ExpandedSubBlockStart.gifContractedSubBlock.gif             
dot.gif{
InBlock.gif                 bodyContent.writeOut(bodyContent.getEnclosingWriter()); 
ExpandedSubBlockEnd.gif             }

ExpandedSubBlockEnd.gif        }
 
InBlock.gif        
catch(java.io.IOException e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
throw new JspTagException("IO Error: " + e.getMessage());  
ExpandedSubBlockEnd.gif        }
   
InBlock.gif        
return EVAL_PAGE;  
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gifContractedSubBlock.gif     
public void doInitBody() throws JspTagExceptiondot.gif{
InBlock.gif      System.out.println(
"doInitBody");
ExpandedSubBlockEnd.gif     }

InBlock.gif     
public void setBodyContent(BodyContent bodyContent) 
ExpandedSubBlockStart.gifContractedSubBlock.gif     
dot.gif{   
InBlock.gif          System.out.println(
"setBodyContent");
InBlock.gif          
this.bodyContent=bodyContent; 
InBlock.gif          
ExpandedSubBlockEnd.gif     }

InBlock.gif        
InBlock.gif        
ExpandedBlockEnd.gif}

每次计算 完Body时,都会调用 doAfterBody方法。
B:标签描述文件mytag.tld中加入
None.gif     < tag >     
None.gif        
< name > loop </ name >
None.gif        
< tag-class > eflylab.BodyTagExample </ tag-class >
None.gif        
< body-content > jsp </ body-content > <!--  必须为jsp  -->
None.gif        
< attribute >
None.gif              
< name > counts </ name > <!--  这个是我们资源源文件中的属性,同时源文件中必须要有setCounts(int counts)方法  -->
None.gif              
< required > true </ required > <!--  必需要给定  -->
None.gif              
< rtexprvalue > true </ rtexprvalue >
None.gif          
</ attribute >
None.gif    
</ tag >
C:测试页面
ExpandedBlockStart.gif ContractedBlock.gif <% dot.gif @ taglib uri="/demotag" prefix="bodytag"  %>
None.gif
< html >
None.gif
< head >
None.gif
< title > body tag </ title >
None.gif
< meta  http-equiv ="Content-Type"  content ="text/html; charset=gb2312" >
None.gif
</ head >
None.gif
< body >
None.gif 
< HR >
None.gif 
< bodytag:loop  counts ="5" >  
None.gif   现在的时间是: 
<% = new  java.util.Date() %> < BR >
None.gif
</ bodytag:loop >  
None.gif 
< HR >   
None.gif 
</ BODY >   
None.gif
</ HTML >
运行:

同时控制台:

这里打印的内容就是调用标签中方法的顺序。可以看出除了doAfterBody外,其他方法都只调用了一次。doAfterBody在每次循环完后都会调用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值