当前位置:编程学习 > JSP >>

J2EE 探索者:用五个容易的步骤实现 JSP 自定义标记

答案:JSP 自定义标记为在动态 Web 页中将表示与业务逻辑分离提供了一种标准化的机制,使页面设计者可以将注意力放到表示上,而应用程序开发人员编写后端的代码。在 J2EE 探索者 的这篇文章中,具有企业观念的开发者 Kyle Gabhart 介绍了 JSP 自定义标记的基本知识,并引导您完成将它们加入到 JSP 页面的五步过程。
您可能听说现在有上百种不同的方式,但是在开发 Web 应用程序时将表示逻辑与业务逻辑分离是很重要的。近年来,Java 平台已经发展为在体系结构层次上加入了这种分离。例如,在 JSP 体系结构中加入 JavaBean 组件使开发人员使用 JSP 标记获得和设置经过特别编码的 Java 组件上的属性。这些组件或者 JavaBean 再代表表示层执行后端业务处理。

JSP 自定义标记是 JSP/JavaBean 体系结构的产物。像 JavaBean 技术一样,自定义标记有助于将表示逻辑与业务逻辑分离。并且自定义标记成了 Web 设计者的 HTML、XML 和 javascript 世界与软件工程师的 Java 代码、SQL 调用和算法世界之间的桥梁。

在本月的 J2EE 探索者 中,您将学到在 JSP 页中使用 JSP 自定义标记的一些基本知识。我们首先介绍 JSP 标记,然后直接进入创建标记、将它结合到 JSP 容器并在 JSP 页面中使用它的过程。在本文的最后,我们将简要讨论 Java 标准标记库(Java Standard Tag Library, JSTL),这是一组可以在您的 Java 开发项目中使用的、标准化的 JSP 自定义标记。

JSP 自定义标记
JSP 自定义标记 是用户定义的标记,它遵循 JSP JavaBean 标记(即 useBean、getProperty 和 setProperty)所使用的一种特殊的 XML 语法。当 servlet 容器处理自定义标记时,会调用一个或者多个 Java 类文件处理它,与用 Java 类文件处理 JSP 页面的 JavaBean 调用的方式基本一样。处理标记以后,容器将取其名字和属性、以及标记正文中可能有的任何内容,并将它传递给一个或者多个类文件进行处理。

Java 开发人员编写标记处理程序类以处理标记并处理所有需要的 Java 代码和数据操作。对于 Web 设计者来说,自定义标记与标准 HTML 标记除了都可以利用后端动态数据外,它们看上去与使用起来没什么区别。正确编写自定义标记可以让 Web 设计者创建、查询和操作数据而无需编写一行 Java 代码。正确使用自定义标记使 Java 开发人员不必再在编码过程中考虑表示层。这样应用程序开发小组的每一位成员都可以关注于他或者她最擅长的事物。

实现 JSP 自定义标记
JSP 体系结构需要以下组件以实现自定义标记:

在每一页中有一个 JSP 声明
Web 应用程序描述符(web.xml)中的一个项
一个包含特殊 XML 文件和为处理自定义标记而调用的 Java 类的 JAR 文件
在下面几节,您将一步一步地学习如何满足这些要求并将自定义标记加入到 JSP 页面中。要想成功实现 JSP 自定义标记,您需要采取下面五个步骤:

编写标记处理程序类。
创建标记库描述符(TLD)。
使 TLD 文件和处理程序类可访问。
引用标记库。
在 JSP 页面中使用标记。
这些内容是相当基本的,也不用花很长时间。就让我们开始吧。

第 1 步. 编写标记处理程序类
在下面的例子中,我们将使用一个非常简单的显示当前时间和日期的自定义标记例子。下面就是 DateTag:


<abc:displayDate />



我们要做的第一件事是编写标记处理程序类。在执行引用自定义标记的 JSP 页面时,JSP 容器判断每一个自定义标记。当容器遇到一个标记时,它调用与这个自定义标记相关联的标记处理程序,我们将在后面更多地讨论这个过程。然后,每一个标记处理程序实现 JSP API 中的一个特殊接口。标记有两种类型:可以处理标记内容(或者正文)的标记和不能处理标记内容的标记:

<abc:tagWithNoBody attribute="value"/>
<abc:tagWithBody attribute="value">
This is some body content that the tag handler can operate upon.
</abc:tagWithBody>


在 DateTag 例子中不需要加入正文内容,因为它只显示当前日期。因此,我们的处理程序类将实现 Tag 接口(一般是通过扩展 TagSupport 类)。如果我们要创建一个可以处理正文的标记,那么我们就需要实现 BodyTag 接口(一般是通过扩展 BodyTagSupport 类)。清单 1 显示了 DateTag 的处理程序类:

清单 1. 标记处理程序类

package myTags;

import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import javax.servlet.http.*;
import java.text.*;
import java.util.*;

public DateTag extends TagSupport {

public int doStartTag() throws javax.servlet.jsp.JspException {
HttpServletRequest req;
Locale locale;
HttpJspPage g;
DateFormatdf;
Stringdate;
JSPWriterout;

req = ( HttpServletRequest )pageContext.getRequest();
locale = req.getLocale();
df = SimpleDateFormat.getDateInstance(
SimpleDateFormat.FULL,locale );
date = df.format( new java.util.Date() );

try {
out = pageContext.getOut();
out.print( date );
} catch( IOException ioe ) {
throw new JspException( "I/O Error : " + ioe.getMessage() );
}//end try/catch

return Tag.SKIP_BODY;

}//end doStartTag()
}//end DateTag



关于这段代码的说明
关于 DateTag 处理程序类有几件事值得一说。首先看一下方法声明。如果我们直接实现 Tag 接口,那么就需要完成几个方法声明。因为 TagSupport 类是简单的、具体类,它完全实现了在 Tag 接口中声明的方法,我们可以只实现那些在自定义标记中要使用的方法。在这个简单的例子中,我们只实现了 doStartTag() 方法,它是在遇到开始标记时调用的。

您还可能注意到 doStartTag() 方法返回 SKIP_BODY。当然其原因是我们的简单日期标记没有正文。您要注意的最后一件重要的事情是使用了 pageContext 对象访问输出缓存以直接向输出流发送内容。您可能还记得在本系列以前的文章说过,pageContext 对象是一个隐式对象,它提供对与当前页面有关的属性的访问。

编写了源代码文件后,我们像编译所有其他 Java 类一样编译这个类(确保在类路径中加入 Servlet/JSP JAR 文件),然后将编译的类文件放到 Web 应用程序的类目录(WEB-INF/classes)中。如果我们开发的是几个标记或者定义有标记变量的标记,那么我们就会有多个标记处理程序类。在这种情况下我们可能选择将处理程序类打包在一个 JAR 文件中而不是使它们成为类目录中的分散的文件。

第 2 步. 创建 TLD
下一步是定义包含自定义标记与处理它的 Java 类(或多个类)之间的映射的库。这个库是在一个名为标记库描述符(TLD)的 XML 文档中定义的。我们将从 DateTag 例子 DateTagLib.tld 中调用这个 TLD。注意“.tld”是这种文件的标准扩展名。

清单 2. DateTagLib.tld 文件

<?xml version="1.0" encoding="ISO-8859-1" ?>

<taglib>
<tlibversion>1.0</tlibversion>
<info>A 易做图 tag library</info>

<tag>
<name>displayDate</name>
<tagclass>myTags.DateTag</tagclass>
<bodycontent>empty</bodycontent>
<info>Display Date</info>
</tag>
</taglib>



DateTagLib.tld 是一个出色的、最小的标记库描述符文件。所有关键信息都包含在 Tag 标记中,在这里映射了标记名和处理程序类,我们声明了标记对于正文内容的敏感性。对于更复杂的情况,我们可以使用其他的 XML 标记以提供有关库和标记的更多信息。在一个库中定义多个标记也很常见。

第 3 步. 使 TLD 和处理程序类可访问
第 3 步是使这个类或者这些类和 TLD 可以被 Web 应用程序访问。有两种方法:可以将类和 TLD 打包到一个 JAR 文件中,再将这个 JAR 文件储存在 Web 应用程序的 lib 目录中,也可以将类文件分散地放到 classes 子目录中并将 TLD 文件放到 Web 应用程序的 WEB-INF 目录下面的某一位置。

在这个例子中,我们将使用第二种方法,将 TLD 文件和类分散地放到 Web 应用程序目录结构中。您可以回忆起在第 1 步中我们已经将标记处理程序类放到了 classes 目录中,所以我们实际上只需储存 TLD 文件。TLD 文件被储存在 WEB-INF 目录或者子目录中,如果是部署 Java 文件,则储存在 JAR 的 META-INF/ 目录或者子目录。在这里,我们没有使用 JAR 文件,所以我们只将 TLD 储存到 Web 应用程序的 WEB-INF/lib 目录中。

第 4 步. 引用这个库
这时,我们已经编译了标记处理程序类、创建了 TLD 文件以定义处理程序类和标记之间的映射、并保证类和标记在应用程序中都是可访问的。下一步是建立 JSP 页面与标记库之间的引用。有两种方法声明 JSP 页面与其库之间的引用。可以通过 Web 应用程序描述符(web.xml)声明一个静态引用,也可以直接在页面中声明一个动态引用。我们将试用这两种方法。

为了进行静态引用,首先必须将下面的项加入到 web.xml 文件中:


<?xml version="1.0" encoding="ISO-8859-1" ?>

<Web-app>

<!-- Define Servlets, Servlet Mappings, etc. -->

<taglib>
<taglib-uri>myTags</taglib-uri>
<taglib-location>/WEB-INF/lib/DateTagLib

上一个:J2EE clustering 2---有些老了
下一个:J2SE 5.0专题2.7注解

CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,