中国科学院文献情报中心机构知识库(NSL OpenIR): Log In

Download Report

Transcript 中国科学院文献情报中心机构知识库(NSL OpenIR): Log In

JSP自定义标签技术的分析与应用
----Custom Tag 的分析与应用
周强
2009-4-9
Custom Tag 的概念和特点



Custom Tag 由用户自己定义并可以被其它
JSP 使用。
在 JSP 中使用的 Custom Tag 会被转换成
Servlet 程序。
Custom Tag 的优点是取代了JSP中的Java程
序并且可以重复使用。
tag library



JSP 中通过使用 taglib directive 定义所使用的标记库。
一个标记库是一组 custom tag 的集合,它在 Web 程
序中由一个标记库描述文件(TLD)
定义。
<%@ taglib uri=“/WEB-INF/icsampes.tld” prefix=“ics”
%>,其中 uri 属性指定了一个在 /WEB-INF 目录下面的
tld 文件,这个前缀为 ics。在 JSP 中使用属于这个标
记库的 Custom Tag 都以这个前缀打头(ics:XXXX)。
Custom Tag 的格式

一个 Custom Tag 包括起始标记、终止标记和标记体。
其中起始标记可以设置属性,标记体是可选的。格式
如下:
<ics:tagname>
tagbody
</ics:tagname>
Custom Tag 的格式
分为 4 类:
1、简单标记:最简单的 Custom Tag 标记,起始标记
没有设置参数,没有标记体。
2、带属性标记:起始标记可以包括属性,这些属性可
以被 JSP 赋值并用来在使用 Custom Tag 时提供设置
信息。使用这种 Custom Tag,其属性的名称和类型
需要在 tld 文件中指明。

Custom Tag 的格式


3、带标记体标记:在 Custom Tag 的起始标记和终
止标记之间的为标记体(body)。Body 的内容可以是
JSP 中的标准标记、Html、脚本语言或其它Custom
Tag。
4、可被Script使用的标记:Custom Tag 可以采用特
定的格式定义对象(比如数据资源、EJB等),这些对
象可以在标记后面的scriptlet 中使用。要实现这个功
能,需要在一个Custom Tag 中使用 id 和 type 属性。
注:先讲 1 和 2。
Custom Tag 开发方法


1、采用特定的 API 编写实现标记处理的程序;
标记处理程序一般放在 /WEB-INF/classes目录下
面,或者作为 jar 文件放在 /WEB-INF/lib 目录下面。
2、建立一个 tag library descriptor(TLD) 文件用来描
述 Custom Tag。
TLD文件放在 /WEB-INF 下面某个指定目录内。
标记处理程序



标记处理程序,需要实现 tag handler 接口。
在 JSP 1.2 中定义了Tag、BodyTag、Iteration 接口。
Web 容器会通过调用这些接口的特定方法调用
Custom Tag 程序。
另外,JSP 提供了用来实现 tag handler 的方便类
TagSupport、BodyTagSupport 。
标记处理程序

一个 tag handler 可以通过
javax.servlet.jsp.PageContext 对象和 JSP 进行联系。
在 tag handler 中有 setPageContext 设定其
PageContext。在运行中,tag handler 通过
PageContext 可以获得 JSP 的隐含对象(如 request、
session、application等),并通过 setAttribute 和
getAttribute 方法读取和修改隐含对象的属性。
标记处理程序

如果 Custom Tag 套用另一个 Custom Tag,被套用
的Custom Tag 的 tag handler 程序可以使用
getParent() 方法得到包含它的 tag 对象。
简单 Custom Tag-- tag handler 程序
public class TimeTag implements Tag {
private PageContext pageContext;
private Tag parent;
private java.util.Calendar calendar;
public TimeTag() {
super();
}
public int doStartTag() throws JspException {
try {
calendar = Calendar.getInstance();
pageContext.getOut().print(
DateFormat.getDateInstance().format(calendar.getTime())+" "+
DateFormat.getTimeInstance().format(calendar.getTime()) );
} catch (IOException tage) {
throw new JspException("TimeTag Error: "+ tage.getMessage());
}
return SKIP_BODY;
}
简单 Custom Tag-- tag handler 程序
public int doEndTag() throws JspException {
return SKIP_PAGE;
}
public void release() {
}
public void setPageContext(PageContext
pageContext) {
this.pageContext = pageContext;
}
public void setParent(Tag parent) {
this.parent = parent;
}
public Tag getParent() {
return parent;
}
}
简单 Custom Tag-- tag handler 程序
程序使用了 Tag 接口,它主要实现了 doStartTag
方法和 doEndTag 方法。
 当 Web 容器运行这个标记时,它会在读到标记起
始位置时调用 doStartTag方法。 doStartTag方法返
回一个SKIP_BODY值表明不用处理标记体。
 当 Web 容器遇到标记的结尾时,调用其
doEndTag方法。doEndTag方法返回EVAL_PAGE
或 SKIP_PAGE,前者表示接着处理标记后面的
JSP内容,后者表示忽略标记后面的 JSP 内容。

简单 Custom Tag--TLD

<tag>
<name>time</name>
<tag- class>jwadbook.taglib.TimeTag</tagclass>
<body-content>empty</body-content>
</tag>
<ics:time/> 示例 timetag.jsp
<%@ taglib uri="http://www.icconcept.com/taglibs/sampleTag" prefix="ics" %>
<HTML>
<HEAD>
<TITLE>TimeTagJSP</TITLE>
</HEAD>
<BODY BGCOLOR=white>
<CENTER>
<FONT COLOR='#009999' SIZE='4' face='Arial'>
<STRONG>Using Custom JSP Tag to List Current Time </STRONG>
</FONT>
</CENTER>
<HR/>
<CENTER><H3> Current Time is: <ics:time/> </H3></CENTER>
</BODY>
</HTML>
使用简单Custom Tag 的timetag.jsp运行效果
带属性 Custom Tag



对于带属性的标记,在 tag handler 程序中需要对标
记的每个属性进行定义。
标记 <ics:wordcount inputname=“input”
warnEmpty=“true” /> 有两个属性。在
WorldCountTag.java 中有 setInputname方法和
setWarnEmpty 方法。Web 容器会在处理标记时,对
这些属性进行赋值。
TagSupport 类已经定义了名为 id 的属性,如果标记
的 tag handler 程序继承 TagSupport 类就不需要声明
setId 方法。
带属性 Custom Tag—tag handler 程序
public class WordCount extends TagSupport
{
String inputname;
boolean warnEmpty;
String inputword;
public void setInputname(String _inputname) {
this.inputname = _inputname;
}
public void setWarnEmpty(boolean _warnempty) {
this.warnEmpty = _warnempty;
}
带属性 Custom Tag—tag handler 程序
public int doEndTag() throws JspException {
JspWriter out = pageContext.getOut();
inputword = pageContext.getRequest().getParameter(inputname);
try {
If ((inputword==null)&&(warnEmpty==true)) {
out.println("<FONT color = 'red'> None Input Found! Input Again
</FONT>");
} else if (inputword==null) {
out.println("0");
} else {
StringTokenizer st = new StringTokenizer(inputword);
int wordnumber = st.countTokens();
out.println(wordnumber);
}
} catch (IOException ioe) {
System.out.println ("Error: " + ioe.getMessage());
}
return EVAL_PAGE;
}
}
带属性 Custom Tag—tag handler 程序



<ics:wordcount> 标记可以计算表单中输入的单词数
目。
“inputname” 属性定义了一个输入表单请求变量名称,
“warnEmpty” 规定了当用户没有输入文字时,是否给
出警告。
这个 tag handler 程序在 doEndTag 方法中使用
request.getParameter 得到特定的请求参数,然后将
这个字符串内的单词数目计算并显示出来。
带属性 Custom Tag—TLD
在<tag> 中有 <attribute> 元素, <attribute> 中的<name> 指出了属性的名称,
<required> 表明属性是否必须被设定(默认为否),<rtextprvalue> 设定是否 Web 容器
要计算属性表达式的值(默认为否),<type>代表了属性的类型(默认为String)。
<tag>
<name>wordcount</name>
<tag-class>jwadbook.taglib.WordCount</tag-class>
<body-content>empty</body-content>
<attribute>
<name>inputname</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>warnEmpty</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
</attribute>
</tag>

带属性 Custom Tag—wordcounttag.jsp
<%@ taglib uri="http://www.icconcept.com/taglibs/sampleTag"
prefix="ics" %>
…
<form action="wordcounttag.jsp" method="post">
<TEXTAREA rows="10" cols="58" name="input">Enter A Brief Description
Here</TEXTAREA>
<BR></BR>
Your have entered
<ics:wordcount inputname="input" warnEmpty="true" />
words in the above text area.
<BR></BR>
<INPUT type="submit" name="Submit" value="Count Words"></FORM>
</form>
…
wordcounttag.jsp 输入界面
wordcounttag.jsp 输出统计结果
谢谢!