J2EE平台WEB组件开发中如何使用定制标签

j2ee|web|组件开发

摘要:
J2EE PLATFORM WEB组件开发涉及SERVLET 和JSP技术,SERVLET和JSP各有其优缺点。JVAVABEAN和定制标签对JSP的表示能力提供了很好的扩展,大大提高了JSP的表示能力,同时它们的引入使WEB开发可以很好的进行分工,提高开发效率,降低开发成本,同时提高了JSP页面的可读性、重用性、可维护性。本文将介绍J2EE平台WEB组件开发中如何使用定制标签,主要介绍开发定制标签的意义,原理、步骤、在TOMCAT上的发布并给出一个典型的标签实例以加深理解和提高实战性。引用请保留作者和文章来源
关键词:
J2EE、SERVLET、JSP、WEB组件、定制标签。
一、 为什么要使用定制标签?
开发过Servlet和JSP的人都知道,从表示层来看,Servlet和JSP 是J2EE 平台两中生成动态WEB内容的技术,它们都能产生相同的结果,但它们采用了不同的机制来建立WEB组件。Sverlet是在逻辑中嵌入内容,并夹带服务器方处理逻辑,而JSP是在内容中嵌入逻辑。
JSP像HTML一样是标签化的,适合内容的表示和描述,但需要JAVA脚本才能处理表示逻辑和业务逻辑,然而JAVA代码的嵌入大大降低了JSP页面表示代码的可读性和可维护性,也不利于重复功能的可复用性。同样的Servlet是实现特定接口的JAVA类,它是用JAVA语言写的,是高度编程的,它适合处理表示逻辑和业务逻辑,但在Servlet内加入表示和描述内容的页面代码,一方面使逻辑处理混乱,可读性差,另一方面也给表示内容的维护带来不利。
JavaBean的引入很好的解决了JSP和Servlet面临的两难处境,使J2EE平台WEB组件的开发很好的实现了内容和表示逻辑、业务逻辑的分离。可以高度剥离JSP页面层的JAVA代码、业务逻辑层次的内容描述和表示代码。
但JavaBean存在先天的不足,它只是可复用组件,独立于运行环境而包装了一些数据和业务逻辑功能,无法获得运行环境信息。
在JSP 1.1和 JSP1.2 中相继引入了定制标签这种机制,解决了JavaBean的这种缺陷,从而彻底解决了WEB组件开发中的表示和业务逻辑代码的分离,大大增强了代码的可读性、可维护性、可复用性。
二、 JSP页面与定制标签之间的通讯
在JSP 1.1引入了包javax.servlet.jsp.tagext,定制标签时需要实现特定的接口或继承相应的类,其中Tag接口定义了JSP页面和标签处理器之间基本的通讯合约,即通讯的API接口。JSP规范中规定了WEB容器调用这些方法处理它们通讯的流程,从而实现对标签的生命周期的管理,其时序图如下:

三、 定制标签的原理
1、 定制标签运行所需的四个组件
定制标签需要开发四个组件以确保其能正常运行,它们是:
TagName.class:通常称之为标签处理器,它是实现标签功能的JAVA类。它必须实现特定的JAVA 接口,这些接口和抽象类在包javax.servlet.jsp.tagext中,实现对标签的生命周期的管理。
TaglibName.tld:定义一个标签库的XML文件。其中定义了标签库的名称、版本信息、描述信息和包含的各标签的名称、对应的标签处理器,标签的属性等。
Web.xml :是每个WEB应用程序的唯一的部署描述符文件(每个WEB容器有多个WEB应用程序,但每个WEB应用程序只有一个部署描述符文件)。它是使用XML(Extensible Markup Language)语言写的,描述WEB应用程序可用的资源和相关的信息,一般它在WEB服务器启动时被加载到内存中。WEB服务器依此来调度资源响应用户的请求。必须在Web.xml中注册定制标签库。
JspPage.jsp :是一个JSP页面,该页面使用在WEB应用程序描述符文件中注册的标签库中的标签,实现特定的表示功能。在JSP页面中使用某个标签库之间前,一定要导入标签库。
2、 定制标签处理器实现的接口

以上是定制标签的层次结构图,定制标签可以通过实现其中任何一个接口或者继承任何一个抽象类来实现特定的表示功能。通常使用什么接口或者抽象类处决于开发人员必须定义的方法所预期的生命周期。下面对图中的接口和抽象类分别进行介绍。
javax.servlet.jsp.tagext.Tag接口:
Tag接口定义了标签处理器和调用实例JSP页面之间基本的通讯协议,如果选择实现该接口,要求实现如下定义的所有方法,如:setPageContext(PageContext pc)、setParent(Tag tag)、getParent(Tag tag)、doStartTag()、doEndTag()、release(),这些方法都是容器回调方法。实现Tag接口的标签的生命周期如下图所示。

javax.servlet.jsp.tagext.IterationTag接口:
由上述标签处理器实现接口的层次结构图可知IterationTag接口扩展了Tag接口,而且增加了额外的方法doAfterTag()。该方法使实现该接口的标签处理器能够多次执行标签体正文。如果选择实现该接口,除了要实现Tag中的所有方法外,还要实现doAfterTag(),使标签处理器能够多次执行标签正文。实现IterationTag接口的标签的生命周期如下图所示。

javax.servlet.jsp.tagext.BodyTag接口:
BodyTag扩展了接口IterationTag接口,并且提供了多次执行和修改标签正文的能力。如增加了方法setBodyContent(BodyContent bc)、doInitBody()。IterationTag和BodyTag常用于处理集合对象中的数据实现。BodyTag接口的标签的生命周期如下图所示。

一般情况,用户可以根据实际情况选择地实现上述三个接口之一就能满足需要。但通过实现上述接口开发标签处理器要实现众多地方法是很不方便而且工作量很大,同时功能也受限。不过用户放心,JAVA天生的简洁之美和开放特性是不会让大家失望的,为了简化用户的开发和提供更多额外的功能,javax.servlet.jsp.tagext包还额外的提供了一些支持类,如:
javax.servlet.jsp.tagext.TagSupport
javax.servlet.jsp.tagext.BodyTagSupport
javax.servlet.jsp.tagext.TagExtraInfo
其中TagSupport和BodyTagSupport都实现了Tag接口。TagSupport用于实现那些不需要操纵标签体的的标签处理器;BodyTagSupport用于实现那些要求改变标签正文的标签处理器的标签。TagExtraInfo用于提供编译时标签的额外信息。

四、 基本的定制标签的步骤
定制标签通常有五个步骤:1、编写标签处理器类文件;2、编写标签库描述文件;3、部署标签库;4、向WEB应用程序注册标签库;5、导入和使用标签库。
下面分别加以简单介绍。
1、 标签处理器类文件的编写:
像其它的JAVA组件编程一样,编写标签处理器只需要实现特定的接口就可以了,在上述定制标签的原理中已经详细讨论了如何开发标签处理器,在此不再多说。
2、 编写标签库描述文件:
标签库是一些标签的集合,它们通常有一定的联系。由于标签处理器的方法有很多是容器回调方法,编写完标签后,要向WEB容器提供关于标签的信息,才能在客户引用时,WEB容器知道怎样调用相应的方法来处理客户的请求。通常标签的信息存储在一个名叫TLD的标签库描述文件中。TLD文件是用XML编写,很易理解。该文件一般包含标头信息、标签库定义信息、一个或多个标签定义信息。一个完整的TLD文件如下。
//标头信息
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
//标签库定义信息
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name> customTags </short-name>
<description>A set of my tag handlers.</description>
//标签定义信息
<tag>
<name>tagname</name>
<tag-class>TagHandlerclassName</tag-class>
<attribute>
<name>attributename</name>
<required>true/false</required>
<rtexprvalue>true/false</rtexprvalue>
</attribute>
------
</taglib>
3、 部署标签库:
由于标签库使用TLD文件来描述的,因而部署标签库实际上就是发布TLD文件,一般它放在WEAR包的WEB-INFO文件夹下,即直接将TLD文件拷贝到WEB-INFO文件夹中。
4、 向WEB应用程序注册标签库:
向WEB应用程序注册标签库实际上是向WEB应用程序指出标签库描述文件TLD文件的路径,也就是在WEB.XML文件中指出标签库描述文件的路径(在基于JAVA的WEB组件开发中WEB.XML文件用于向应用程序注册资源信息)。即在其中增加如下语句。
<taglib>
//标签库引用名称
<taglib-uri>/ customTags </taglib-uri>
//标签库描述文件TLD路径
<taglib-location>/WEB-INF/ customTags.tld</taglib-location>
</taglib>
5、 导入和使用标签库:
现在在JSP页面中就可以导入和使用标签了,语法如下:
//导入标签库
<%@ taglib uri="/ customTags " prefix="custTag" %>
//引用标签
< custTag: tagname />或< custTag: tagname>------< custTag: tagname/>

JSP页面定义的标签元素是如何在WEB容器中找到对应的标签处理器的呢?从定制标签的步骤,我们不难绘出定制标签映射图(如图六所示),可以清晰看出在WEB容器中定制标签元素是如何找到相应的标签处理器的。图六清晰地放映了定制标签的运行机制。

五、 如何在TOMCAT上发布
将编写好的标签处理器CLASS文件、标签库描述文件、WEB.xml文件和WEB应用程序打包成WEAR组件,就可以发布到TOMCAT等WEB容器上。经解压文件目录类似如图七结构,

其中customTags.tld为客户定制标签库描述文件,标签处理器类文件位于classes文件夹或包含标签处理器的JAR文件,WEB.XML将customTags.tld映射到WEB应用程序。JSP文件加中存放引用定制标签的JSP页面文件。
六、 典型定制标签的范例
在讲解了开发定制标签的基本原理、方法和步骤后,下面让我们通过一个完整的典型的例子来看在实际应用中如何使用定制标签来封装常见模块,以增强代码的可读性、可维护性、可复用性,提供编码效率。一般的WEB站点都有大量的新闻内容显示和民意调查内容等重用性很高的功能模块,如新浪、搜狐等。下面我们看如何用上面介绍的方法来开发新闻标签。
1、 编写标签处理器类文件
新闻列表标签(用于显示新闻条目)
public class NewsListTag extends TagSupport {
//属性
//对应的SETTER、GETTER方法
public int doStartTag() throws JspException {
//处理从数据库中检索获得的新闻条目集合和新闻显示格式
//输出标签体内容
try {
pageContext.getOut().print(sbOut.toString());
} catch (IOException e) {
throw new JspTagException("NewsListTag::IO Error: " + e.getMessage());
}
return SKIP_BODY ;
}
private ResultSet getRS() throws SQLException,IOException {
//从数据库中检索新闻条目,并返回结果集
return rs;
}
}
新闻内容标签(用于按指定的格式显示某条新闻的具体内容)
public class NewsContentTag extends TagSupport {
//新闻条目的ID号属性
//对应的SETTER、GETTER方法
public int doStartTag() throws JspException {
//从数据库中获得某条新闻的具体内容
//定制新闻显示的格式
//输出新闻内容。
try {
pageContext.getOut().print(sbOut.toString());
} catch (IOException e) {
throw new JspTagException("NewsListTag::IO Error: " + e.getMessage());
}

return SKIP_BODY ;
}
private ResultSet getRS() throws SQLException,IOException {
//按新闻ID号从数据库中获得新闻的具体内容,并返回结果集
return rs;
}
}
2、 编写标签库描述文件TLD(CustomTags.tld)
//标头信息
//标签库信息
<tag>
<name>newsList</name>
<tag-class>NewsListTag</tag-class>
//标签属性集
</tag>

<tag>
<name>newsContent</name>
<tag-class> NewsContentTag</tag-class>
//标签属性集
</tag>
3、 部署标签库
将CustomTags.tld文件放在WEAR包中的WEB-INFO目录下。部署结果类似如图七。
4、 向WEB应用程序注册标签库
在WEB.XML文件中增加如下语句:
<taglib>
<taglib-uri>/ customTags </taglib-uri>
<taglib-location>/WEB-INF/ customTags.tld</taglib-location>
</taglib>
5、 导入和使用标签
下面就可以在JSP文件中导入定制的标签库和定制的标签了,语法如下:
<%@ taglib uri="/ customTags " prefix=" customTags " %>//导入标签库
< customTags: newsList attribute----- />//引用新闻列表标签
< customTags: newsContent attribute----- />//引用新闻内容标签
6、 运行效果
启动TOMCAT,在浏览器中输入相应的URL地址就可以看到类似新浪站点上的新闻条目页面,可以查看按一定内格式输出新闻条目。当想查看某条新闻的具体内容时,点击该条新闻,就在新的页面按定义的格式显示该条新闻的具体内容。运行步骤如下:
1 启动TOMCAT,在地址栏中http://localhost:8080/tagexample/news/news.jsp, 以看到新闻条目界面,浏览新闻标题.,效果如图八.

2 点击新闻条目(新闻标题),可以浏览相应的新闻内容,效果如图九.

时间: 2025-01-01 06:25:09

J2EE平台WEB组件开发中如何使用定制标签的相关文章

J2EE平台架构上开发CRM的技术过程控制

第一章 概述 本文阐述了关于在J2EE平台上开发CRM应用系统的各方面内容,包括高辉本人对于CRM系统的理解,利用J2EE平台开发过程中要注意的一些技术深层的问题,开发分析中要注意的原则等等.这些都是作者在实际的工作中通过经验与教训所得来的.在工作中,我深刻的体会到系统分析员的重要性,尤其是对于以组件为主要开发对象的工程项目,系统分析员的技术与业务素质对于整个项目的成功与否起着非常关键性的作用. 需要说明的是,这并非作者工作文档,而仅仅是一篇分享经验与教训的交流文档,因此,其中关于一些涉及到具体

Yeoman提供各种Web应用开发中所需的实用功能

浏览器端所包含的 HTML.CSS 和 JavaScript 代码也变得更加复杂.对于日益复杂的前端代码,需要有更好的流程和工具来管理开发的各个方面,包括初始的代码结构.开发流程和自动化测试等.Yeoman 是一个新兴的工具.它结合了 Yo.Grunt 和 Bower 等工具,组成了一个完整的工具集合,提供各种 Web 应用开发中所需的实用功能. Yeoman 的最大优势在于它整合了各种流行的实用工具,提供了一站式的解决方案,使得 Web 应用开发中的很多方面变得简单.Yeoman 使得开发人员

面向设计的半封装web组件开发(概要版)

一.传统web组件的妄想 目前很多Team和团队都有自己的一套web组件体系,模块化开发,封装良好,上手简单.然后希望该web组件可以应用到接手的各个项目中,节约日后的开发成本.甚至考虑开源. 这其实是很棒的,但是呢,希望一套web组件各个项目通用?在我看来,除非对项目没有追求,否则不太现实. 但是呢,希望一套web组件各个项目通用?在我看来,除非对项目没有追求,否则就是妄想. 为什么说传统web组件想一统天下不现实呢?因为就像秦始皇一统天下一样,要牺牲很多很多东西. 牺牲代码量 web组件要想

Web前端开发中的MCRV模式

摘要 针对前端开发中基于ajax的复杂页面开发所面临的代码规模大,难以组织和维护,代码复用性.扩展性和适应性差等问题,本文尝试以MVC思想为基础,结合Web前端开发中"内容-结构-表现-行为"相分离的开发标准,提出一种将Web页面代码分为视图(View,页面静态部分,包括内容.结构.表现).模型(Model,负责数据缓存.数据校验与本地逻辑处理.发起ajax请求).控制器(Controller,负责用户和系统事件响应.模型和渲染器调度).渲染器(Renderer,对视图的渲染,控制器与

界面-web程序开发中文件的下载

问题描述 web程序开发中文件的下载 在登录得主界面增加下载的链接,可以下载发布到服务器上的文件.使用的框架是spring,Struts2,ibatis. 解决方案 如果你不愿暴露文件存储路径,就用io流的方式,若果无所谓,直接把路径放在超链接上即可. 解决方案二: BufferedInputStream br = new BufferedInputStream(new FileInputStream(f)); byte[] buf = new byte[1024]; int len = 0;

WEB 前端开发中防治重复提交的实现方法_javascript技巧

web前端数据请求或者表单提交往往通过对dom的点击事件来操作,但是往往因为认为点击过快(少年手速挺快的嘛),或者因为响应等待使得用户误人为没操作而重复很多次点击,造成表单数据的连续重复提交,造成用户体检的不好,甚至影响到整个系统的安全性.而前端的防治重复提交至少很有效的防治了人为正常操作下的很多不必要麻烦.下面就来讲讲如何有效避免前端的表单重复提交 表单提交有以下几种方式: <form name="form" method="post" action=&qu

《HTML5移动应用开发入门经典》—— 第2章 移动开发中新的HTML5标签和属性

第2章 移动开发中新的HTML5标签和属性 HTML5移动应用开发入门经典本章介绍如下内容: 如何使用HTML5中的新标签及属性:HTML5中的其他变化:HTML5的移动支持:使用HTML5开发移动Web应用的理由.HTML5中有许多在构建Web页面及应用中会用到的新标签和属性.在这一章中,读者将学习许多HTML5的新特性以及它们在移动设备上的运用.新款智能手机及平板电脑正在逐渐接纳HTML5,而本章将会告诉读者如何加入这一次革新的盛宴.

在Web项目开发中使用BasePage类的巧用(继承System.Web.UI.Page)

web|继承|项目 在web项目开发,我们基本每页都要与数据库连接,是不是每页都要实例化数据库对象呢?当然不用,只要我们写一个继承Page类的类就可以了.只要我们每个CodeBehind页面都继承这个类,就直接可以调用此类的属性了.以此类推,我们还可以加入一些项目中经常要用到的功能. 以C#为例,列出代码. using System; using System.Diagnostics; using System.Web; using DbLayer ; using System.Web.UI.W

Filter组件开发中的SDK基类分析

DirectShow SDK提供了一套开发Filter的基类源代码.基于这些基类开发Filter将大大简化开发过程. 1.CBaseObject 大部分SDK类都从CBaseObject类(参见combase.h)中继承而来的. [cpp] view plaincopy class CBaseObject   {      private:          // Disable the copy constructor and assignment by default so you will