JSP自定义标签的开发与应用.docx
- 文档编号:29431508
- 上传时间:2023-07-23
- 格式:DOCX
- 页数:103
- 大小:56.24KB
JSP自定义标签的开发与应用.docx
《JSP自定义标签的开发与应用.docx》由会员分享,可在线阅读,更多相关《JSP自定义标签的开发与应用.docx(103页珍藏版)》请在冰豆网上搜索。
JSP自定义标签的开发与应用
JSP自定义标签的开发与应用
在JSTL提供了四个标签库(核心标签库、国际化标签库、数据库标签库和XML标签库),涉及到了几十个标签。
虽然这些标签可以完成比较复杂的工作,但它们仍然无法满足程序中的特殊需求。
因此,就需要用户根据自己的需要来定制JSP标签,这种由用户自己实现的JSP标签被称为自定义标签。
.1自定义标签基础
自定义标签和JSTL中的标签从技术上看没有任何区别,可以将这些标签统称为JSP标签。
JSP标签在JSP页面中通过XML语法格式被调用,当JSP引擎将JSP页面翻译成Servlet时,就将这些调用转换成执行相应的Java代码。
也就是说,JSP标签实际上就是调用了某些Java代码,只是在JSP页面中以另外一种形式(XML语法格式)表现出来。
1.1编写输出随机数的标签
开始自定义标签的学习之前,在这一节先来实现一个简单的自定义标签,以使读者做一下热身,同时读者通过本节的例子可以对自定义标签的实现方法和过程有一个感性的认识。
【实例1-1】实现输出随机数的标签
1.实例说明
在本例实现的自定义标签(random标签)的功能是输出一个指定范围的随机整数。
random标签有如下几个特征:
没有标签体。
有两个属性:
min和max。
其中min属性表示生成随机数的最小值,max属性表示生成随机数的最大值。
min属性的默认值是0,max属性的默认值是Integer.MAX_VALUE。
生成随机数的范围是min<=random random标签的标准调用形式如下: randommin="1"max="100"/> 其中“ct”是调用标签时的前缀,通过taglib指定的prefix属性指定。 上面的代码的功能是输出一个在1(包括)和100(不包括)之间的随机数。 2.编写标签类 标签类是自定义标签的核心部分。 实现标签类的方法有很多,但最简单的方法是编写一个从 javax.servlet.jsp.tagext.TagSupport类继承的Java类,并在该类中覆盖TagSupport类的doStartTag方法。 为了读取标签中的属性值,还需要在标签类中为每一个标签属性提供一个相应数据类型的标签类属性以及该属性的setter方法(不需要getter方法)。 生成随机数的代码需要放在标签类的doStartTag方法中。 该标签类的实现代码如下: packagechapter1; importjava.io.IOException; importjava.util.Random; importjavax.servlet.jsp.JspException; importjavax.servlet.jsp.tagext.TagSupport; publicclassRandomTagextendsTagSupport { //封装random标签的两个属性的JavaBean属性 privateintmin=0; privateintmax=Integer.MAX_VALUE; //min属性的setter方法 publicvoidsetMin(intmin) { this.min=min; } //max属性的setter方法 publicvoidsetMax(intmax) { this.max=max; } //覆盖TagSupport类的doStartTag方法 //当遇到标签(也就是 random>)的开始标记时调用该方法 @Override publicintdoStartTag()throwsJspException { try { Randomrandom=newRandom(); //生成一个在min和max之间的随机数 intresult=min+random.nextInt(max-min); //将生成的随机数输出到客户端 pageContext.getOut().write(String.valueOf(result)); } catch(IOExceptione) { } //TagSupport类的doStartTag方法默认返回SKIP_BODY,表示忽略自定义标签体 returnsuper.doStartTag(); } } 在RandomTag类的doStartTag方法中使用了一个pageContext变量来获得JspWriter对象(JSP的out 内置对象)。 pageContext变量是在TagSupport类中定义的一个类变量,该变量通过TagSupport类中的 setPageContext方法进行赋值。 实际上,setPageContext方法是在Tag接口中定义的,而TagSupport实现了 Tag接口的setPageContext方法。 Servlet容器在调用doStartTag方法之前,会先调用Tag接口的setPageContext方法来初始化pageContext变量。 Tag接口将在1.1.3节介绍,在这里只要知道所有的标签类都必须实现Tag接口。 为了简化标签类的实现,JSPAPI提供了一个TagSupport类,有了TagSupport类,用户在编写标签类时就不需要实现Tag接口的所有方法了。 3.编写标签库描述符文件(TLD文件) 在JSTL中有若干TLD文件(详见图9.1),其中tld是TagLibraryDescriptor(标签库描述符)的缩写。 要想使一个自定义标签正常工作,必须在TLD文件中对该标签进行配置。 在TLD文件中主要配置如下两部分内容: 标签库的配置信息、标签库中具体标签的配置信息 标签库的配置信息主要包括如下的内容: 标签库的版本: 使用 正常使用标签库中的标签所需要的最低JSP版本: 使用 标签库的默认前缀: 使用 标签库的URI: 使用 标签库的描述信息: 使用 标签的配置信息主要包括如下的内容: 标签名: 使用 标签对应的Java类: 使用 标签体的类型: 使用 标签的描述信息: 使用 标签属性的信息: 每一个标签属性对应一个 在 在WEB-INF目录中建立一个jsp-taglib.tld文件,并在该文件中输入如下的内容: --标签库描述符文件头--> xmlversion="1.0"encoding="UTF-8"? > xmlns: xsi="http: //www.w3.org/2001/XMLSchema-instance" xsi: schemaLocation=" version="2.0"> --标签库的配置信息--> --random标签的配置信息--> 上面的配置代码分为三部分: 标签库描述符文件头、标签库配置信息和random标签的配置信息。 其中描述库文件头的内容并不需要读者去记忆,读者只需要将JSTL中的任何一个TLD文件打开,将其中的标签库描述文件头部分复制过来即可。 如果在标签库描述符文件中包含中文,需要将encoding属性改成“UTF-8”或“GBK”。 标签库的URI被 要注意的是,该默认前缀并不等于taglib指令的prefix属性值,也就是说,taglib指令的prefix属性值和 在使用taglib指令引用某个标签库时,应尽量使用 random标签的标签体类型为“empty”( 关于 random标签的min属性和max属性都被设置可选的属性,并且都不支持动态属性值。 因此,在JSP页面中设置random标签的这两个属性时只能直接为它们赋值。 4.测试random标签 在 <%@pagelanguage="java"contentType="text/html;charset=UTF-8"%> <%@tagliburi=""prefix="ct"%> <%@tagliburi="prefix="c"%> --使用forEach标签产生1个10至200之间的随机数--> forEachbegin="1"end="1"> --调用random标签--> randommin="10"max="200"/> forEach> 在浏览器地址栏中输入如下的URL: http: //localhost: 8080/demo/chapter1/random.jsp 浏览器显示的输出结果如图1.1所示。 图1.1使用random标签产生1个10至200之间的随机数 5.程序总结 在部署和安装自定义标签时,TLD文件应放在WEB-INF目录或其子目录中(包括classes和lib目录)。 根据本例实现的random标签,可以将开发自定义标签的基本步骤总结如下: 实现一个标签类。 该标签类可以实现Tag接口、继承TagSupport类或实现其他的接口(这些接口将在后面的部分详细介绍)。 在标签库描述符文件(TLD文件)中配置自定义标签。 部署和安装自定义标签。 主要是将.class文件放在WEB-INF\classes目录中,并且将TLD文件放在WEB-INF目录或其子目录中。 1.1.2自定义标签能做什么 自定义标签除了可以读取标签的属性值外,还可以完成如下的工作: 单次执行标签体中的内容、重复执行标签体中的内容。 修改标签体中的内容。 忽略JSP页面中位于自定义标签后面的内容。 在上一节介绍了Tag接口中的doStartTag方法,该方法在Web容器执行到自定义标签的开始标记时被调用。 除了这个方法,在Tag接口中还有doEndTag方法,该方法在Web容器中执行到自定义标签的结束标记时被调用。 doStartTag方法可以通过返回如下两个值来控制Web容器是否执行自定义标签的标签体: EVAL_BODY_INCLUDE: 执行自定义标签的标签体。 SKIP_BODY: 忽略(不执行)自定义标签的标签体。 doEndTag方法可以通过返回如下两个值来控制Web容器是否忽略JSP页面中位于自定义标签后面的内容: EVAL_PAGE: 继续执行自定义标签后面的内容。 SKIP_PAGE: 忽略自定义标签后面的内容。 其中EVAL_BODY_INCLUDE、SKIP_BODY、EVAL_PAGE和SKIP_PAGE是在Tag接口中定义的整型常量,所有实现Tag接口的类都可以直接使用这些常量。 除此之外,实现IterationTag接口的标签类还可以重复执行标签体。 IterationTag是Tag接口的子接口。 在IterationTag接口中有一个doAfterBody方法,该方法可以通过返回如下两个值来决定是否重复执行自定义标签体的内容: EVAL_BODY_AGAIN: 重复执行标签体的内容。 SKIP_BODY: 不再执行标签体的内容。 其中EVAL_BODY_AGAIN是在IterationTag接口中定义的整型常量。 如果doAfterBody方法返回SKIP_BODY,Web容器会继续执行自定义标签的结束标记,同时会调用doEndTag方法。 从上面的描述可以将Web容器执行自定义标签的过程总结如下: 1.Web容器首先会执行自定义标签的开始标记,同时会调用标签类的doStartTag方法。 2.如果doStartTag方法返回EVAL_BODY_INCLUDE,Web容器在执行完标签体的内容后,会调用标签类的doAfterBody方法;如果doStartTag方法返回SKIP_BODY,doAfterBody方法不会被调用,Web容器会直接调用标签类的doEndTag方法。 3.如果doAfterBody方法被调用,并且该方法返回EVAL_BODY_AGAIN,Web容器会再次执行标签体的内容;如果doAfterBody方法返回SKIP_BODY,Web容器会调用标签类的doEndTag方法。 4.如果doEndTag方法返回EVAL_PAGE,Web容器会执行自定义标签后面的内容;如果doEndTag方法返回SKIP_PAGE,Web容器会忽略自定义标签后面的内容。 1.1.3自定义标签API 自定义标签API中除了前面介绍的Tag接口和IterationTag接口外,还有另外三个核心接口: JspTag、 BodyTag和SimpleTag。 为了简化自定义标签的编程工作,在自定义标签API中提供了TagSupport类、SimpleTagSupport类和BodyTagSupport类。 其中TagSupport类实现了IterationTag接口,SimpleTagSupport类实现了SimpleTag接口,BodyTagSupport类是TagSupport的子类,并实现了BodyTag接口。 上述五个接口和三个类的关系如图1.2所示。 图1.2自定义标签API的核心接口和类的关系图 上述的接口和类都在javax.servlet.jsp.tagext包中,读者可以从如下的网址来查询这些接口和类的详细介绍: 访问上面的网址将得到如图1.3所示的页面。 图1.3自定义标签API的官方文档 上述五个接口的功能和作用如下: 1.JspTag接口 JspTag接口是所有自定义标签的父接口。 它没有任何属性和方法。 Tag接口和SimpleTag接口是JspTag的两个直接子接口。 其中JspTag和SimpleTag是JSP2.0新增的接口。 在JSP2.0之前的版本的所有自定义标签的父接口是Tag。 因此,可以将所有实现Tag接口的自定义标签称为传统标签,把所有实现SimpleTag接口的标签称为简单标签。 在本章主要介绍传统标签,简单标签将在下一章详细介绍。 2.Tag接口 Tag接口是所有传统标签的父接口。 该接口有两个核心方法(doStartTag和doEndTag)以及四个常量(EVAL_BODY_INCLUDE、SKIP_BODY、EVAL_PAGE和SKIP_PAGE)。 其中doStartTag方法可以返回EVAL_BODY_INCLUDE和SKIP_BODY,用于控制Web容器是否执行标签体的内容;doEndTag方法可以返回EVAL_PAGE和SKIP_PAGE,用于控制Web容器是否执行自定义标签后面的内容。 3.IterationTag接口 IterationTag接口继承了Tag接口。 IterationTag接口可用于实现需要循环执行标签体内容的自定义标签。 在IterationTag接口中只有一个doAfterBody方法和一个EVAL_BODY_AGAIN常量。 doAfterBody方法通过返回EVAL_BODY_AGAIN常量或Tag接口中的SKIP_BODY常量来控制Web容器是否重复执行标签体中的内容。 doStartTag方法、doAfterBody方法和doEndTag方法的调用关系详见1.1.2节中的介绍。 并不是每一个自定义标签都需要循环执行标签体的内容,或是控制自定义标签后面的内容是否被执行。 因此,JSPAPI中提供了一个实现IterationTag接口的TagSupport类。 在TagSupport类中对Tag接口和IterationTag接口中定义的方法都提供了默认的实现。 如doStartTag方法、doEndTag方法和doAfterBody方法都提供了默认的返回值,代码如下: publicclassTagSupportimplementsIterationTag,Serializable { publicTagSupport(){} publicintdoStartTag()throwsJspException { returnSKIP_BODY; } publicintdoEndTag()throwsJspException { returnEVAL_PAGE; } publicintdoAfterBody()throwsJspException { returnSKIP_BODY; } //此处省略了TagSupport类中的其他方法和属性 ...... } 标签类通过继承TagSupport类,就不需要实现Tag接口和Iteration接口中的每一个方法了,这样将大大简化自定义标签的开发工作。 4.BodyTag接口 BodyTag接口继承了IterationTag接口。 BodyTag接口不仅拥有IterationTag接口的所有功能,而且还可以初始化和修改标签体的内容。 在BodyTag接口中定义了两个方法(doInitBody和setBodyContent)和两个常量(EVAL_BODY_BUFFERED和EVAL_BODY_TAG),这两个常量的含义相同。 其中EVAL_BODY_TAG常量是在JSP1.2中的遗留产物,在JSP的后续版本中可能不支持该常量,因此,建议使用EVAL_BODY_BUFFERE常量。 如果doStartTag方法返回EVAL_BODY_BUFFERE,Web容器就会将标签体的执行结果保存在BodyContent对象中,然后Web容器在处理标签时会调用标签类的setBodyContent方法将BodyContent对象传入标签类的对象实例,接下来就可以在标签类的对象实例中处理标签体的执行结果了。 由于BodyTag接口及其父接口中定义了很多方法,为了在实现BodyTag接口的类中不用再实现所有的方法,JSPAPI提供了一个BodyTagSupport类,该类是TagSupport类的子类,并且实现了BodyTag接口。 在BodyTagSupport类中改变了doStartTag方法的默认返回值,并且覆盖了其他的核心方法,代码如下: publicclassBodyTagSupportextendsTagSupportimplementsBodyTag { protectedBodyContentbodyContent; publicBodyTagSupport() { super(); } publicvoidsetBodyContent(BodyContentb) { this.bodyContent=b; } publicBodyContentgetBodyContent() { returnbodyContent; } //改变了doStartTag方法的默认返回值 publicintdoStartTag()throwsJspException { returnEVAL_BODY_BUFFERED; } publicintdoEndTag()throwsJspException { returnsuper.doEndTag(); } publicvoiddoInitBody()throwsJspException { } publicintdoAfterBody()throwsJspException { returnSKIP_BODY; } //此处省略了BodyTagSupport类的其他方法和属性 ...... } 从前面的内容可知,自定义标签API涉及到了三个方法(doStartTag、doAfterBody和doEndTag)以及这三个方法可能返回的六个常量(EVAL_BODY_INCLUDE、EVAL_BODY_BUFFERE、SKIP_BODY、EVAL_BODY_AGAIN、EVAL_PAGE和SKIP_PAGE)。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- JSP 自定义 标签 开发 应用
![提示](https://static.bdocx.com/images/bang_tan.gif)