博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javaweb(二十四)——jsp传统标签开发
阅读量:5334 次
发布时间:2019-06-15

本文共 8853 字,大约阅读时间需要 29 分钟。

一、标签技术的API

1.1、标签技术的API类继承关系

  

二、标签API简单介绍

2.1、JspTag接口

  JspTag接口是所有自定义标签的父接口,它是JSP2.0中新定义的一个标记接口,没有任何属性和方法。JspTag接口有Tag和SimpleTag两个直接子接口,JSP2.0以前的版本中只有Tag接口,所以把实现Tag接口的自定义标签也叫做传统标签,把实现SimpleTag接口的自定义标签叫做简单标签

2.2、Tag接口

  Tag接口是所有传统标签的父接口,其中定义了两个重要方法(doStartTag、doEndTag)方法和四个常量(EVAL_BODY_INCLUDE、SKIP_BODY、EVAL_PAGE、SKIP_PAGE),这两个方法和四个常量的作用如下:

  (1)WEB容器在解释执行JSP页面的过程中,遇到自定义标签的开始标记就会去调用标签处理器的doStartTag方法,doStartTag方法执行完后可以向WEB容器返回常量EVAL_BODY_INCLUDE或SKIP_BODY。如果doStartTag方法返回EVAL_BODY_INCLUDE,WEB容器就会接着执行自定义标签的标签体;如果doStartTag方法返回SKIP_BODY,WEB容器就会忽略自定义标签的标签体,直接解释执行自定义标签的结束标记。

  (2)WEB容器解释执行到自定义标签的结束标记时,就会调用标签处理器的doEndTag方法,doEndTag方法执行完后可以向WEB容器返回常量EVAL_PAGE或SKIP_PAGE。如果doEndTag方法返回常量EVAL_PAGE,WEB容器就会接着执行JSP页面中位于结束标记后面的JSP代码;如果doEndTag方法返回SKIP_PAGE,WEB容器就会忽略JSP页面中位于结束标记后面的所有内容。

  从doStartTag和doEndTag方法的作用和返回值的作用可以看出,开发自定义标签时可以在doStartTag方法和doEndTag方法体内编写合适的Java程序代码来实现具体的功能,通过控制doStartTag方法和doEndTag方法的返回值,还可以告诉WEB容器是否执行自定义标签中的标签体内容和JSP页面中位于自定义标签的结束标记后面的内容。

2.3、IterationTag接口

  IterationTag接口继承了Tag接口,并在Tag接口的基础上增加了一个doAfterBody方法和一个EVAL_BODY_AGAIN常量。实现IterationTag接口的标签除了可以完成Tag接口所能完成的功能外,还能够通知WEB容器是否重复执行标签体内容。对于实现了IterationTag接口的自定义标签,WEB容器在执行完自定义标签的标签体后,将调用标签处理器的doAfterBody方法,doAfterBody方法可以向WEB容器返回常量EVAL_BODY_AGAIN或SKIP_BODY。如果doAfterBody方法返回EVAL_BODY_AGAIN,WEB容器就会把标签体内容再重复执行一次,执行完后接着再调用doAfterBody方法,如此往复,直到doAfterBody方法返回常量SKIP_BODY,WEB容器才会开始处理标签的结束标记和调用doEndTag方法。

  可见,开发自定义标签时,可以通过控制doAfterBody方法的返回值来告诉WEB容器是否重复执行标签体内容,从而达到循环处理标签体内容的效果。例如,可以通过一个实现IterationTag接口的标签来迭代输出一个集合中的所有元素,在标签体部分指定元素的输出格式。

  在JSP API中也提供了IterationTag接口的默认实现类TagSupport,我们在编写自定义标签的标签处理器类时,可以继承和扩展TagSupport类,这相比实现IterationTag接口将简化开发工作。

2.4、BodyTag接口

  BodyTag接口继承了IterationTag接口,并在IterationTag接口的基础上增加了两个方法(setBodyContent、doInitBody)和一个EVAL_BODY_BUFFERED常量。实现BodyTag接口的标签除了可以完成IterationTag接口所能完成的功能,还可以对标签体内容进行修改。对于实现了BodyTag接口的自定义标签,标签处理器的doStartTag方法不仅可以返回前面讲解的常量EVAL_BODY_INCLUDE或SKIP_BODY,还可以返回常量EVAL_BODY_BUFFERED。如果doStartTag方法返回EVAL_BODY_BUFFERED,WEB容器就会创建一个专用于捕获标签体运行结果的BodyContent对象,然后调用标签处理器的setBodyContent方法将BodyContent对象的引用传递给标签处理器,WEB容器接着将标签体的执行结果写入到BodyContent对象中。在标签处理器的后续事件方法中,可以通过先前保存的BodyContent对象的引用来获取标签体的执行结果,然后调用BodyContent对象特有的方法对BodyContent对象中的内容(即标签体的执行结果)进行修改和控制其输出。

  在JSP API中也提供了BodyTag接口的实现类BodyTagSupport,我们在编写能够修改标签体内容的自定义标签的标签处理器类时,可以继承和扩展BodyTagSupport类,这相比实现BodyTag接口将简化开发工作。

2.5、 SimpleTag接口

  SimpleTag接口是JSP2.0中新增的一个标签接口。由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广,因此,SUN公司为降低标签技术的学习难度,在JSP 2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口。SimpleTag接口与传统标签接口最大的区别在于,SimpleTag接口只定义了一个用于处理标签逻辑的doTag方法,该方法在WEB容器执行自定义标签时调用,并且只被调用一次。那些使用传统标签接口所完成的功能,例如是否执行标签体、迭代标签体、对标签体内容进行修改等功能都可以在doTag方法中完成。

  在JSP API中也提供了SimpleTag接口的实现类SimpleTagSupport,我们在编写简单标签时,可以继承和扩展SimpleTagSupport类,这相比实现SimpleTag接口将简化开发工作。

2.6、传统标签接口中的各个方法可以返回的返回值说明

  下图列举了Tag接口、IterationTag接口和BodyTag接口中的主要方法及它们分别可以返回的返回值的说明。

  

三、开发传统标签实现页面逻辑

  开发人员在编写Jsp页面时,经常还需要在页面中引入一些逻辑,例如:

  • 控制jsp页面某一部分内容是否执行。
  • 控制整个jsp页面是否执行。
  • 控制jsp页面内容重复执行。
  • 修改jsp页面内容输出。

  自定义标签除了可以移除jsp页面java代码外,它也可以实现以上功能。

3.1、控制jsp页面某一部分内容是否执行  

  编写一个类实现tag接口,控制doStartTag()方法的返回值,如果这个方法返回EVAL_BODY_INCLUDE,则执行标签体,如果返回SKIP_BODY,则不执行标签体。

  SUN公司针对tag接口提供了一个默认的实现类TagSupport,TagSupport类中实现了tag接口的所有方法,因此我们可以编写一个类继承TagSupport类,然后再重写doStartTag方法。

示例代码如下:

TagDemo1.java

1 package me.gacl.web.tag; 2  3 import javax.servlet.jsp.JspException; 4 import javax.servlet.jsp.tagext.Tag; 5 import javax.servlet.jsp.tagext.TagSupport; 6 7 /** 8 * @author gacl 9 * TagSupport类实现了Tag接口,TagDemo1继承TagSupport类 10 * 11 */ 12 public class TagDemo1 extends TagSupport { 13 14 /* 重写doStartTag方法,控制标签体是否执行 15 * @see javax.servlet.jsp.tagext.TagSupport#doStartTag() 16 */ 17 @Override 18 public int doStartTag() throws JspException { 19 //如果这个方法返回EVAL_BODY_INCLUDE,则执行标签体,如果返回SKIP_BODY,则不执行标签体 20 //return Tag.EVAL_BODY_INCLUDE; 21 return Tag.SKIP_BODY; 22 } 23 }

  在WEB-INF目录下的tld文件中添加对该标签处理类的描述,如下:

1 
2
demo1
3
me.gacl.web.tag.TagDemo1
4
5
JSP
6

  在jsp页面中导入并使用自定义标签,如下:

1 <%@ page language="java" pageEncoding="UTF-8"%> 2 <%--在jsp页面中导入自定义标签库 --%> 3 <%@taglib uri="/gacl" prefix="gacl" %> 4  5  6  7 控制标签体是否执行 8  9 10  11 <%--在jsp页面中使用自定义标签 demo1标签是带有标签体的,标签体的内容是"孤傲苍狼"这几个字符串--%> 12 
13 孤傲苍狼 14
15 16

  运行效果如下:

 

3.2、控制整个jsp页面是否执行

  编写一个类实现tag接口,控制doEndTag()方法的返回值,如果这个方法返回EVAL_PAGE,则执行标签余下的jsp页面,如果返回SKIP_PAGE,则不执行余下的jsp。

示例代码如下:

TagDemo2.java

1 package me.gacl.web.tag; 2  3 import javax.servlet.jsp.JspException; 4 import javax.servlet.jsp.tagext.Tag; 5 import javax.servlet.jsp.tagext.TagSupport; 6 7 /** 8 * @author gacl 9 * TagSupport类实现了Tag接口,TagDemo2继承TagSupport类 10 */ 11 public class TagDemo2 extends TagSupport{ 12 13 /* 重写doEndTag方法,控制jsp页面是否执行 14 * @see javax.servlet.jsp.tagext.TagSupport#doEndTag() 15 */ 16 @Override 17 public int doEndTag() throws JspException { 18 //如果这个方法返回EVAL_PAGE,则执行标签余下的jsp页面,如果返回SKIP_PAGE,则不执行余下的jsp 19 return Tag.SKIP_PAGE; 20 //return Tag.EVAL_PAGE; 21 } 22 23 24 }

  在WEB-INF目录下的tld文件中添加对该标签处理类的描述,如下:

1 
2
demo2
3
me.gacl.web.tag.TagDemo2
4
5
empty
6

  在jsp页面中导入并使用自定义标签,如下:

1 <%@ page language="java" pageEncoding="UTF-8"%> 2 <%--在jsp页面中导入自定义标签库 --%> 3 <%@taglib uri="/gacl" prefix="gacl" %> 4  5  6  7 控制jsp页面是否执行 8  9 10  11 

jsp页面的内容1

12 <%--在jsp页面中使用自定义标签 demo2标签是不带标签体的--%> 13
14

jsp页面的内容2

15 16

  运行效果如下:

 

3.3、控制jsp页面内容重复执行

  编写一个类实现Iterationtag接口,控制doAfterBody()方法的返回值,如果这个方法返回EVAL_BODY_AGAIN, 则web服务器又执行一次标签体,依次类推,一直执行到doAfterBody方法返回SKIP_BODY,则标签体才不会重复执行。

示例代码如下:

TagDemo3.java

1 package me.gacl.web.tag; 2  3 import javax.servlet.jsp.JspException; 4 import javax.servlet.jsp.tagext.IterationTag; 5 import javax.servlet.jsp.tagext.Tag; 6 import javax.servlet.jsp.tagext.TagSupport; 7 8 public class TagDemo3 extends TagSupport { 9 10 int x = 5; 11 @Override 12 public int doStartTag() throws JspException { 13 return Tag.EVAL_BODY_INCLUDE; 14 } 15 16 /* 控制doAfterBody()方法的返回值, 17 * 如果这个方法返回EVAL_BODY_AGAIN, 则web服务器又执行一次标签体, 18 * 依次类推,一直执行到doAfterBody方法返回SKIP_BODY,则标签体才不会重复执行。 19 * @see javax.servlet.jsp.tagext.TagSupport#doAfterBody() 20 */ 21 @Override 22 public int doAfterBody() throws JspException { 23 x--; 24 if(x>0){ 25 return IterationTag.EVAL_BODY_AGAIN; 26 }else{ 27 return IterationTag.SKIP_BODY; 28 } 29 } 30 31 }

  在WEB-INF目录下的tld文件中添加对该标签处理类的描述,如下:

1 
2
demo3
3
me.gacl.web.tag.TagDemo3
4
5
JSP
6

  在jsp页面中导入并使用自定义标签,如下:

1 <%@ page language="java" pageEncoding="UTF-8"%> 2 <%--在jsp页面中导入自定义标签库 --%> 3 <%@taglib uri="/gacl" prefix="gacl" %> 4  5  6  7 控制页面内容重复执行5次 8  9 10  11 <%--在jsp页面中使用自定义标签 demo3标签--%> 12 
13

jsp页面的内容

14
15 16

  运行效果如下:

  

3.4、修改jsp页面内容输出

  编写一个类实现BodyTag接口,控制doStartTag()方法返回EVAL_BODY_BUFFERED,则web服务器会创建BodyContent对象捕获标签体,然后在doEndTag()方法体内,得到代表标签体的bodyContent对象,从而就可以对标签体进行修改操作。

  SUN公司针对BodyTag接口提供了一个默认的实现类BodyTagSupport,BodyTagSupport类中实现了BodyTag接口的所有方法,因此我们可以编写一个类继承BodyTagSupport类,然后再根据需要重写doStartTag方法和doEndTag()方法。

示例代码如下:

TagDemo4.java

1 package me.gacl.web.tag; 2  3 import java.io.IOException; 4 5 import javax.servlet.jsp.JspException; 6 import javax.servlet.jsp.tagext.BodyContent; 7 import javax.servlet.jsp.tagext.BodyTag; 8 import javax.servlet.jsp.tagext.BodyTagSupport; 9 import javax.servlet.jsp.tagext.Tag; 10 11 /** 12 * @author gacl 13 * BodyTagSupport类实现了BodyTag接口接口,TagDemo4继承 BodyTagSupport类 14 */ 15 public class TagDemo4 extends BodyTagSupport { 16 17 /* 控制doStartTag()方法返回EVAL_BODY_BUFFERED 18 * @see javax.servlet.jsp.tagext.BodyTagSupport#doStartTag() 19 */ 20 @Override 21 public int doStartTag() throws JspException { 22 return BodyTag.EVAL_BODY_BUFFERED; 23 } 24 25 @Override 26 public int doEndTag() throws JspException { 27 28 //this.getBodyContent()得到代表标签体的bodyContent对象 29 BodyContent bodyContent = this.getBodyContent(); 30 //拿到标签体 31 String content = bodyContent.getString(); 32 //修改标签体里面的内容,将标签体的内容转换成大写 33 String result = content.toUpperCase(); 34 try { 35 //输出修改后的内容 36 this.pageContext.getOut().write(result); 37 } catch (IOException e) { 38 throw new RuntimeException(e); 39 } 40 41 return Tag.EVAL_PAGE; 42 } 43 }

  在WEB-INF目录下的tld文件中添加对该标签处理类的描述,如下:

1 
2
demo4
3
me.gacl.web.tag.TagDemo4
4
5
JSP
6

  在jsp页面中导入并使用自定义标签,如下:

1 <%@ page language="java" pageEncoding="UTF-8"%> 2 <%--在jsp页面中导入自定义标签库 --%> 3 <%@taglib uri="/gacl" prefix="gacl" %> 4  5  6  7 修改jsp页面内容输出 8  9 10  11 <%--在jsp页面中使用自定义标签 demo4标签--%> 12 
13

xdp_gacl

14
15 16

  运行效果如下:

  

四、jsp传统标签开发总结

  在现在的jsp标签开发中,很少直接使用传统标签来开发了,目前用得较多的都是简单标签,所以Jsp的传统标签开发了解一下即可,下一篇重点介绍jsp简单标签的开发

转载于:https://www.cnblogs.com/zy-jiayou/p/7373564.html

你可能感兴趣的文章
selenium-窗口切换
查看>>
使用vue的v-model自定义 checkbox组件
查看>>
[工具] Sublime Text 使用指南
查看>>
Hangfire在ASP.NET CORE中的简单实现方法
查看>>
Algorithm——何为算法?
查看>>
Web服务器的原理
查看>>
小强升职计读书笔记
查看>>
常用的107条Javascript
查看>>
#10015 灯泡(无向图连通性+二分)
查看>>
忘记root密码,怎么办
查看>>
linux设备驱动归纳总结(三):1.字符型设备之设备申请【转】
查看>>
《黑客与画家》 读书笔记
查看>>
bzoj4407: 于神之怒加强版
查看>>
mysql统计一张表中条目个数的方法
查看>>
ArcGIS多面体(multipatch)解析——引
查看>>
css3渐变画斜线 demo
查看>>
JS性能DOM优化
查看>>
设计模式 单例模式 使用模板及智能指针
查看>>
c#的const可以用于引用类型吗
查看>>
手动实现二值化
查看>>