JSP 自定义标签 BodyTagSupport

引用
带body的自定义标签,尝试写一个标签,这个标签可以迭代显示标签主体里面的内容,迭代的次数由标签的属性指定.
     首先,要说明的是,其实标签也是一个java类,它是运行一个或两个接口的javabean,然后再配合标签描述文件(以.tld为扩展名),两者结合就可以作出自己的自定义标签库了.呵呵,是不是觉得有点眉目了?
     那么下面我们开始写一个自己的java标签类,作为有body的标签,这个类必须实现javax.servlet.jsp.tagext.BodyTag接口.
下面我们看一下BodyTag这个接口中定义了那些方法来支持tag:


Java代码   收藏代码
  1. public void doInitBody();  
  2. public void setBodyContent(javax.servlet.jsp.tagext.BodyContent);  
  3. public int doAfterBody();  

那么由于BodyTag继承了javax.servlet.jsp.tagext.Tag接口,所以我们再来看一下Tag中的方法:


Java代码   收藏代码
  1. public void release();  
  2. public javax.servlet.jsp.tagext.Tag getParent();  
  3. public void setParent(javax.servlet.jsp.tagext.Tag);  
  4. public int doEndTag();  
  5. public int doStartTag();  
  6. public void setPageContext(javax.servlet.jsp.PageContext);  
  7.   



引用
说了这么多方法,是不是有点头晕了?呵呵,那么究竟BodyTag的处理过程是怎么样的呢?下面我们就来说一下它的处理流程:
1.当容器创建一个新的标签实例后,通过setPageContext来设置标签的页面上下文.
2.使用setParent方法设置这个标签的上一级标签,如果没有上一级嵌套,设置为null.
3.设置标签的属性,这个属性在标签库描述文件中定义,如果没有定义属性,就不调用此类方法.
4.调用doStartTag方法,这个方法可以返回EVAL_BODY_INCLUDE和SKIP_BODY,当返回EVAL_BODY_INCLUDE时,就计算标签的body,如果返回SKIP_BODY,就不再计算标签的body.
5.调用setBodyContent设置当前的BodyContent.
6.调用doInitBody,如果计算BodyContent时需要进行一些初始化,就在这个方法中进行.
7.每次计算完Body后调用doAfterBody,如果返回EVAL_BODY_TAG,表示继续计算一次Body,直到返回SKIP_BODY才继续往下执行.
8.调用doEndTag方法,这个方法可以返回EVAL_PAGE或者SKIP_PAGE,当返回EVAL_PAGE时,容器将在标签结束时继续计算JSP页面其他的部分;如果返回SKIP_PAGE,容器将在标签结束时停止计算JSP页面其他的部分.
9.调用release()方法释放标签程序占用的任何资源。
知道了标签处理的流程了,那么下面我们就开始写一个自己的java类了
我的标签类的源码:

Java代码   收藏代码
  1. package test.jsp.tags;  
  2.   
  3. import javax.servlet.jsp.tagext.BodyTagSupport;  
  4. import javax.servlet.jsp.tagext.BodyContent;  
  5. import javax.servlet.jsp.JspTagException;  
  6.   
  7. public class BodyTagExample extends BodyTagSupport {  
  8.     private int counts;  
  9.   
  10.     public BodyTagExample() {  
  11.         super();  
  12.     }  
  13.   
  14.     public void setCounts(int counts) {  
  15.         this.counts = counts;  
  16.     }  
  17.   
  18.     public int doStartTag() throws JspTagException {  
  19.         System.out.println("doStartTag...");  
  20.         if (counts > 0) {  
  21.             return EVAL_BODY_TAG;  
  22.         } else {  
  23.             return SKIP_BODY;  
  24.         }  
  25.     }  
  26.   
  27.     public void setBodyContent(BodyContent bodyContent) {  
  28.         System.out.println("setBodyContent...");  
  29.         this.bodyContent = bodyContent;  
  30.     }  
  31.   
  32.     public void doInitBody() throws JspTagException {  
  33.         System.out.println("doInitBody....");  
  34.     }  
  35.   
  36.     public int doAfterBody() throws JspTagException {  
  37.         System.out.println("do After body..." + counts);  
  38.         if (counts > 1) {  
  39.             counts--;  
  40.             return EVAL_BODY_TAG;  
  41.         } else {  
  42.             return SKIP_BODY;  
  43.         }  
  44.     }  
  45.   
  46.     public int doEndTag() throws JspTagException {  
  47.         System.out.println("do end Tag...");  
  48.         try {  
  49.             if (bodyContent != null) {  
  50.                 bodyContent.writeOut(bodyContent.getEnclosingWriter());  
  51.             }  
  52.         } catch (java.io.IOException e) {  
  53.             throw new JspTagException("IO Error: " + e.getMessage());  
  54.         }  
  55.         return EVAL_PAGE;  
  56.     }  
  57. }  

写完了java类,下面我们该用一个描述文件来描述我们写的这个类了:
我的tld描述文件源码:


Java代码   收藏代码
  1. <?xml version="1.0" encoding="ISO-8859-1" ?>  
  2. <!DOCTYPE taglibPUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN""http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">  
  3. <taglib>  
  4. <tlibversion>1.0</tlibversion>  
  5. <jspversion>1.1</jspversion>  
  6. <shortname>Application Tag Library</shortname>  
  7. <uri>http://jakarta.apache.org/taglibs/struts-example-1.0</uri>  
  8. <info>tag loop</info>  
  9. <tag>  
  10. <name>loop</name>  
  11. <tagclass>test.jsp.tags.BodyTagExample</tagclass>  
  12. <bodycontent>JSP</bodycontent>  
  13. <attribute>  
  14. <name>counts</name>  
  15. <required>true</required>  
  16. <rtexprvalue>true</rtexprvalue>  
  17. </attribute>  
  18. </tag>  
  19. </taglib>  


我们对这个文件进行一个小小的说明:
引用
最重要的是上面的黑体字部分,其他的部分我们可以拷贝粘贴就可以了。
tag中的name属性:定义了我们的tag名称,在后面会用到。
tag中的tagclass属性:指定了我们这个tag的实现类。
tage中的bodycontent属性:指定我们的页面内容是什么性质的。(注意:在jsp开发中这里必须写JSP)
tage中的attribute属性:定义了我们的这个tag可能有的属性。
attribute中的name属性:指定了属性的名称。它和我们类中定义的“int counts;”必须一样,并且在类中还必须包含一个setCounts(int counts)方法,否则这个属性就不能设置。
attribute中的required属性:表示这个属性是否是必须的。
attribute中的rtexprvalue属性:表示这个属性是否可以用JSP的程序段的结果输出。
现在我们的tag就写完了,下面就是我们怎么在页面中用了。
首先,我们要在web.xml中声明这个tag
我的web.xml源码:

Java代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">   
  3. <web-app>   
  4. <taglib>   
  5. <taglib-uri>demotag</taglib-uri>   
  6. <taglib-location>/WEB-INF/tld/mytag.tld</taglib-location>   
  7. </taglib>  
  8. </web-app>  

其次,我们要在页面中引用这个tag。
我的jsp源码:



Java代码   收藏代码
  1. <%@ page contentType="text/html; charset=GBK" language="java"%>   
  2. <%@ taglib uri="demotag" prefix="demo" %>   
  3. <html>   
  4. <body>   
  5. <br>  
  6.  <demo:loop counts="5"> 现在时间是:<%=new java.util.Date().toString()%>  
  7. <br>   
  8. </demo:loop>  
  9.  <br>  
  10.  </body>  
  11.  </html>  

好了,一个tag就开发完了,下面是页面的显示结果:
现在时间是:Thu Sep 22 12:33:31 CST 2005
现在时间是:Thu Sep 22 12:33:31 CST 2005
现在时间是:Thu Sep 22 12:33:31 CST 2005
现在时间是:Thu Sep 22 12:33:31 CST 2005
现在时间是:Thu Sep 22 12:33:31 CST 2005
这里是后台打出来的信息:
doStartTag...
setBodyContent...
doInitBody....
do After body...5
do After body...4
do After body...3
do After body...2
do After body...1
do end Tag...
一切OK了!

如果要写没有标签体的自定义标签,直接继承 TagSupport,实现doStartTag,doEndStart就可以了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值