通过在使用任何自定义标签之前,将taglib指令加入页面中声明JSP页面将使用在标签库中定义的标签:
<%@ taglib uri="/WEB-INF/tutorial-template.tld" prefix="tt" %>
uri属性:表示唯一标识标签库描述符(TLD)的URI,在标签库描述符中描述了uri。这个URI可以是直接或者非直接的。
prefix属性:定义了区分指定标签库所定义的标签与其他标签库提供的标签的前缀。
标签库描述符文件名必须有扩展名.tld。TLD文件储存在WAR的WEB-INF目录中,或者在WEB-INF的子目录中。可以直接或者间接引用TLD。
下面taglib指令直接引用一个TLD文件名:
<%@ taglib uri="/WEB-INF/tutorial-template.tld" prefix="tt" %>
这个taglib指令使用一个短的逻辑名间接引用TLD:
<%@ taglib uri="/tutorial-template" prefix="tt" %>
在Web应用程序部署描述符中将逻辑名映射到一个绝对位置。要将逻辑名/tutorial-template映射为绝对位置/WEB-INF/tutorial-template.tld,在web.xml中添加元素taglib:
<taglib>
<taglib-uri>/tutorial-template</taglib-uri>
<taglib-location>
/WEB-INF/tutorial-template.tld
</taglib-location>
</taglib>
标签库描述符文件名必须有扩展名.tld。TLD文件储存在WAR的WEB-INF目录中,或者在WEB-INF的子目录中。可以直接或者间接引用TLD。
下面taglib指令直接引用一个TLD文件名:
<%@ taglib uri="/WEB-INF/tutorial-template.tld" prefix="tt" %>
这个taglib指令使用一个短的逻辑名间接引用TLD:
<%@ taglib uri="/tutorial-template" prefix="tt" %>
在Web应用程序部署描述符中将逻辑名映射到一个绝对位置。要将逻辑名/tutorial-template映射为绝对位置/WEB-INF/tutorial-template.tld,在web.xml中添加元素taglib:
<taglib>
<taglib-uri>/tutorial-template</taglib-uri>
<taglib-location>
/WEB-INF/tutorial-template.tld
</taglib-location>
</taglib>
让标签库实现可用
可以以两种方式让标签库实现对Web应用程序可用。实现了标签handler的类可以以非打包的形式储存在Web应用程序的WEB-INF/classes子目录中。另一种方法是,如果以JAR的形式发布库,就将它储存在Web应用程序的WEB-INF/lib目录中。在多个应用程序中共享的标签库储存在Java WSDP的<JWSDP_HOME>/common/lib目录中。
定义标签
· 为该标签开发一个tag handler和helper类
· 在标签库描述符中声明这个标签
本节描述标签handler和TLD的属性,并解释如何为在前面几节中介绍的标签开发tag handler和库描述符元素。
标签handler
标签handler是由Web容器调用的一个对象,用于执行带有自定义标签的JSP页面时对这个标签进行判断。标签handler必须实现Tag或者BodyTag接口。接口可以用于接受现有Java对象并使它成为标签handler。对于新创建的处理器,可以用TagSupport和BodyTagSupport类作为基类。这些类和接口包含在javax.servlet.jsp.tagext包中。
JSP页面的servlet在对标签处理的不同阶段调用由Tag和BodyTag接口定义的标签handler。遇到自定义标签的开始标签时,JSP页面的servlet调用方法以初始化相应的handler,然后调用handler的doStartTag方法。遇到自定义标签的结束标签时,调用处理器的doEndTag方法。在标签handler需要与标签的正文交互时调用其他方法,见带正文的标签。为了提供标签handler的实现,必须实现在处理标签的不同阶段调用的方法。
标签handler类型 方法
简单 doStartTag, doEndTag, release
属性 doStartTag, doEndTag, set/getAttribute1...N, release
正文、判断且无交互 doStartTag, doEndTag, release
正文、迭代判断 doStartTag, doAfterBody, doEndTag, release
正文、交互 doStartTag, doEndTag, release, doInitBody, doAfterBody, release
标签handler可以使用一个能让它得以与JSP页面通信的API。到API的入口点是页面上下文对象(javax.servlet.jsp. PageContext),通过它标签handler可以获取JSP页面能够访问的所有其他隐式对象(请求、会话和应用程序)。
隐式对象可以有与其相关联的命名属性。可以用[set|get]Attribute方法访问这种属性。
如果标签是嵌入的,标签handler还可以访问与外围标签关联的handler称为parent)。
一组相关的标签handler类(标签库)一般是打包的且作为JAR文档部署。
标签库描述符
TLD文件名必须有扩展名.tld。TLD文件也储存在WAR文件的WEB-INF目录中或者在WEB-INF的子目录中。
TLD必须以指定XML的版本和文档类型定义(DTD)的XML文档序言(prolog)开始。
<?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">
Tomcat支持版本 1.1和1.2的DTD。不过,本章所讨论的是1.2版本,因为在开发的所有标签库中都应该使用最新的版本。模板库TLDtutorial-template.tld符合版本1.2。Struts库TLD符合版本1.1的DTD,它的元素要少,且其中一些元素使用了稍微不同的名字。
TLD的根是taglib元素。
taglib子子元素
元素 说明
tlib-version 标签库的版本
jsp-version 这个标签库要求的JSP规范版本
short-name JSP页面编写工具可以用来创建助记名的可选名字
uri 唯一标识该标签库的的URI
display-name 将由工具显示的可选名
small-icon 将由工具使用的可选小图标
large-icon 可被工具使用的可选大图标
description 可选的标签特定信息
listener 见listener元素
tag 见tag元素
listener元素
标签库可以指定一些事件监听器类(见处理Servlet生命周期事件)。这些监听器在TLD中作为listener元素列出,Web容器将初始化监听器类并以类似在WAR级定义的监听器的方式注册它们。与WAR级监听器不同,这里没有指定标签库监听器注册的顺序。listener元素的唯一子元素是listener-class元素,它必须包含监听类的完全限定名。
tag元素
库中的每一个标签都由给出其名字和其标签handler的类、在由标签创建的脚本变量上的信息以及标签属性上的信息描述。脚本变量信息可以在TLD中直接给出,也可以通过tag extra info类给出(见定义脚本变量的标签)。每一个属性声明包含指明属性是否是必需的、其值是否可以由请求时表达式确定以及属性类型的内容(见属性元素)。
在tag元素中的TLD中指定标签。
标签子元素
元素 说明
name 唯一标签名
tag-class 标签handler类的完全限定名
tei-class javax.servlet.jsp.tagext.TagExtraInfo的可选子类。见提供有关脚本变量的信息。
body-content 正文内容类型。见body-conten元素和 body-content元素。
display-name 由工具显示的可选名
small-icon 可以由工具使用的小图标
large-icon 可以由工具使用的大图标
description 可选的标签特定的信息
variable 可选的脚本变量信息。见提供有关脚本变量的信息。
attribute 标签属性信息。见Attribute 元素。
返回值列表
EVAL_BODY_INCLUDE:把Body读入存在的输出流中,doStartTag()函数可用
EVAL_PAGE:继续处理页面,doEndTag()函数可用
SKIP_BODY:忽略对Body的处理,doStartTag()和doAfterBody()函数可用
SKIP_PAGE:忽略对余下页面的处理,doEndTag()函数可用
EVAL_BODY_TAG:已经废止,由EVAL_BODY_BUFFERED取代
EVAL_BODY_BUFFERED:申请缓冲区,由setBodyContent()函数得到的BodyContent对象来处理tag的body,如果类实现了BodyTag,那么doStartTag()可用,否则非法
EVAL_BODY_AGAIN:请求继续处理body,返回自doAfterBody(),这个返回值在你制作循环tag的时候是很有用的。
EVAL_BODY_INCLUDE:把Body读入存在的输出流中,doStartTag()函数可用
EVAL_PAGE:继续处理页面,doEndTag()函数可用
SKIP_BODY:忽略对Body的处理,doStartTag()和doAfterBody()函数可用
SKIP_PAGE:忽略对余下页面的处理,doEndTag()函数可用
EVAL_BODY_TAG:已经废止,由EVAL_BODY_BUFFERED取代
EVAL_BODY_BUFFERED:申请缓冲区,由setBodyContent()函数得到的BodyContent对象来处理tag的body,如果类实现了BodyTag,那么doStartTag()可用,否则非法
EVAL_BODY_AGAIN:请求继续处理body,返回自doAfterBody(),这个返回值在你制作循环tag的时候是很有用的。