JSP自定义标记

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

  • 在每一页中有一个 JSP 声明
  • Web 应用程序描述符(web.xml)中的一个项
  • 一个包含特殊 XML 文件和为处理自定义标记而调用的 Java 类的 JAR 文件

在下面几节,您将一步一步地学习如何满足这些要求并将自定义标记加入到 JSP 页面中。要想成功实现 JSP 自定义标记,您需要采取下面五个步骤:

  1. 编写标记处理程序类。
  2. 创建标记库描述符(TLD)。
  3. 使 TLD 文件和处理程序类可访问。
  4. 引用标记库。
  5. 在 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 simple 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.tld</taglib-location>   </taglib>               </Web-app>

 

然后,将 JSP 声明加入到所有需要使用自定义标记库的页面中:

<%@ taglib uri="myTags" prefix="abc" %>

 

注意指定的 uri 属性与在 web.xml 文件中指定的 taglib-uri 值相匹配。

为了进行动态引用,只需在所有需要使用这个库的页面中加入一个 JSP 声明即可:

<%@ taglib uri="/WEB-INF/lib/DateTagLib.tld" prefix="abc" %>

 

静态引用与动态引用的比较

在进行标记库的静态引用时,JSP 声明必须查询 web.xml 文件以执行库查询。这意味着如果移动或者重命名了库,或者希望在 web.xml 文件中加入更多的库,就必须停止服务器、更新 web.xml 文件、然后重新启动服务器。动态方法让 JSP 页直接指向 TLD 位置,因而是在解释 JSP 页面时进行处理。

静态方法提供了页面与库的实际名和位置之间一定程度的非直接性,这可以为您提供一些改变这些属性而不修改页面的灵活性。另一方面,动态方法提供了更大的灵活性,让您可以在运行时增加和移动标记声明。如果您对动态方法感兴趣,但是又担心做了一些改变后、有可能要更新多个页面的维护负担,那么您可以始终将 JSP 声明放到一个单独的 JSP 文件中,并在每一个要访问 Web 应用程序的自定义库的页面中加入这一页。这使您具有在运行时只需要更新信息一次就可以增加库的灵活性。

 



 

 

第 5 步. 在 JSP 页面中使用标记

完成了所有这些准备工作后,我们就可以在 JSP 页面中使用这些自定义标记了。清单 3 显示了包含 DateTag 的 JSP 页面的浏览器输出:


清单 3. 带有自定义标记的 JSP 页

<%@ taglib uri="/WEB-INF/lib/DateTagLib.tld"  prefix="abc" %><HTML><HEAD><TITLE>Date tag example</TITLE></HEAD><BODY><H1>Date tag Example</H1><p>Hi today is <b><abc:displayDate /></b> </p></BODY></HTML>

 

重新启动 Web 服务器并测试自己的 JSP 页面 !转载:http://www.cnblogs.com/jqyp/archive/2010/08/17/1801113.html

原文地址:https://www.cnblogs.com/summer520/p/2964280.html