jsp自定义标签
关键词:
jsp自定义标签
定义标签
要定义标签,需要:
· 为该标签开发一个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的实现,必须实现在处理标签的不同阶段调用的方法,在表16-1中汇总了这些方法。
表16-1标签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)是一个描述标签库的XML文档。TLD包含有关整个库以及库中包含的每一个标签的信息。Web容器用TLD验证标签,JSP页面开发工具也使用TLD。
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元素。表16-2中列出了taglib的子元素:
表16-2 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中指定标签。在表16-3中出了tag的子元素:
表16-3 标签子元素 |
元素 | 说明 |
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 元素。 |
下面几节描述开发在标签类型中介绍的每一种类型的标签所需要的方法和TLD。
简单标签
标签handler
简单标签的handler必须实现Tag接口的doStartTag和doEndTag方法。在遇到开始标签时调用doStartTag方法。因为简单标签没有正文,所以这个方法返回SKIP_BODY。在遇到结束标签时调用doEndTag方法。如果要对页面的其他部分进行判断,则doEndTag方法需要返回EVAL_PAGE,否则,它就返回SKIP_PAGE。
在第一节讨论的简单标签
<tt:simple />
由下列标签handler实现:
public SimpleTag extends TagSupport {
public int doStartTag() throws JspException {
try { pageContext.getOut().print("Hello.");
} catch (Exception ex) {
throw new JspTagException("SimpleTag: " +
ex.getMessage()); }
return SKIP_BODY; }
public int doEndTag() {
return EVAL_PAGE;
}
}
body-content元素
没有正文的标签必须用body-content元素声明它们的正文内容是空的:
<body-content>empty</body-content>