ITEEDU

JSP/Servlet: 简介 Tag Library

为了实现视图逻辑分离的模式,您可以使用JavaBean以及Expression Language,使用EL可以让您很简单的取得JSP中设定的一些属性,而使用JavaBean则可以让您将一些数据储存在JavaBean中,并作一 些适当的逻辑运算,然而为了完成一些网页格式的处理以及一些视图的限定存取,您还是不免在JSP网页中使用scriptlet。

您可以将一些网页格式处理或是视图限定存取之类的,使用JSP标签库(Tag Library)来处理,您将格式处理或视图限定存取的部份,撰写在一个标签处理类别(Tag Handler class)中,然而定义好标签库定义档案(.tld),接下来您就可以在JSP网页中使用自订的标签库来撰写网页,例如像< caterpillar:copyright/>这样的卷标来显示一段版权宣告。

先实地演练一篇如何撰写JSP标签库并应用,首先撰写一个标签处理类别:

CopyRightTag.java
package onlyfun.caterpillar;

import java.io.*; 
import javax.servlet.jsp.*; 
import javax.servlet.jsp.tagext.*; 

public class CopyRightTag extends TagSupport { 
public int doStartTag() { 
try { 
JspWriter out = pageContext.getOut(); 
out.println("<table border=1>");
out.println("\t<td bgcolor=yellow>"); 
out.println(
"\t\t<b>caterpillar.onlyfun.net(c)2004<b>"); 
out.println("\t</td>");
out.println("</table>"); 
} 
catch(Exception e) {} 

return SKIP_BODY; 
} 
} 

为了要能编译上面这个类别,您需要将jsp-api.jar加至CLASSPATH中,在Tomcat的话jsp-api.jar是放在common/lib目录下。

如上所示,为了实作一个标签处理类别,您可以继承TagSupport(javax.servlet.jsp.tagext 套件下)类别, TagSupport类别实作了一些接口,其中重要的是Tag与IterationTag,这都将是以后要说明的重点,这边您先要了解的就是,继承 TagSupport的类别并不对标签本体作处理,您所能决定的只是要不要显示本体,例如:

<caterpillar:copyright> 
额外的版权宣告文字。。。。。 
<caterpillar:copyright/> 

如果您继承了TagSupport类别,您所能决定的,就是要不要显示卷标<caterpillar: copyright>与<caterpillar:copyright/>之间的文字,而没有办法对这段文字作任何的处理,如果您要对 本体文字作处理,可以继承BodyTagSupport类别。

回到上面所撰写的标签处理类别,它从pageContext中取得了JspWriter对象,然而输出了一个表格与版权文字,最后我们传回了 Tag.SKIP_BODY常数变量,这是doStartTag()合法的传回值,表示不显示卷标之间的文字本体,另一个合法传回值是 Tag.EVAL_BODY_INCLUDE,这将会显示卷标之间的文字本体。

为了要编译这个类别,您必须在您的CLASSPATH中加入jsp-api.jar的路径,编译完成之后,要将之放置在WEB-INF/classes/ 之下,接下来可以撰写标签库定义.tld檔了,如下:

tagdemo.tld
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
web-jsptaglibrary_2_0.xsd" 
version="2.0">
<description>Tag Demo</description> 
<tlib-version>1.0</tlib-version> 
<jsp-version>2.0</jsp-version> 
<short-name>TagDemo</short-name> 
<uri>/TagDemo</uri>
<tag> 
<description>CopyRight Text</description> 
<name>copyright</name> 
<tag-class>
onlyfun.caterpillar.CopyRightTag
</tag-class> 
<body-content>empty</body-content> 
</tag>
</taglib> 

这是个XML文件,每个标签都已经表明了自身的意义,其中<name>所设定的,就是待会将在JSP网页中使用的标签名,<body- content>的内容设定为empty,表示这个卷标不处理本体文字,除了empty之外,<body- content>的内容还可以是JSP、scriptless、tagdependent, 设定为JSP的话,表示本体如果是JSP的元素,将会先执行完,再传给标签库作处理,Scriptless表示本体内容不可以是scriptlet,但可 以是EL或动作元素等其它JSP元素, tagdependent的话表示不作任何处理,直接将本体内容传给卷标库,有卷标库自行处理本体内容。

假设这个档案储存为tagdemo.tld,并放置在WEB-INF/tlds/下,为了方便管理,再于web.xml中添加一些uri与tld档的对应:

web.xml
...
<jsp-config>
<taglib> 
<taglib-uri>
http://caterpillar.onlyfun.net/
</taglib-uri> 
<taglib-location>
/WEB-INF/tlds/tagdemo.tld
</taglib-location> 
</taglib> 
</jsp-config> 
... 
上面这些步骤与定义EL自订函式的过程其实是类似的,接下来在JSP网页中使用自订JSP标签的方式也是类似,使用taglib指令元素来指定所使用的自订标签,如下:

tagTest.jsp
<%@taglib prefix="caterpillar" 
uri="http://www.caterpillar.onlyfun.net/"%> 
<html> 
<body> 
这个网页是有版权的OOOXXXX。。。。。。<p> 
<caterpillar:copyright/> 
</body> 
</html> 
然后就可以执行JSP网页了,您可以看到,只要一个标签,就可以完成一些网页格式的设定,结果如下:

<html> 
<body> 
这个网页是有版权的OOOXXXX。。。。。。<p> 
<table border=1>
<td bgcolor=yellow>
<b>caterpillar.onlyfun.net(c)2004<b>
</td>
</table> 
</body> 
</html>