分享
 
 
 

开发JSP自定义行为

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

开发JSP自定义行为

1. 要开发一个自定义行为,需要使用一系列的类和接口,这些类和接口在JSP1.1规范中被称为标记扩展机制(tag extension mechanism)。实现标记处理程序所需要的所有接口和类都是在javax.servlet.jsp.tagext包中定义的。两个主要的接口分别是Tag和BodyTag。为了使开发标记处理程序更加容易,API定义了两个起支持作用的类:TagSupport和BodyTagSupport。这两个类分别为上面的两个接口提供了默认的实现。

2. 标记库是一个自定义行为的集合。在标记库中除了标记处理程序的类文件以外,标记库里还必须包括一个tld文件。这是一个XML文件,它把所有的自定义行为的名称映射到相应的标记处理程序类,而且对每一个自定义行为所支持的所有属性进行了描述。类文件和tld可以被打包到一个JAR文件中以方便安装。

3. 开发,配置和使用一个简单的自定义行为通常需要做这几部分工作。

(1) 实现一个标记处理程序类。对这个类进行编译,然后把生成的类文件放到应用程序的WEB-INF/classes目录下。

(2) 创建TLD文件。看下面这个简单的实例。

<?xml version=”1.0” encoding=”ISO-8859-1” ?>

<!DOCTYPE taglib

PUBLIC “-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN”

http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd>

<taglib>

<tlibversion>1.0</tlibversion>

<jspversion>1.1</jspversion>

<shortname>test</shortname>

<tag>

<name>hello</name>

<tagclass>com.mycompany.HelloTag</tagclass>

<bodycontent>empty</bodycontent>

<attribute>

<name>name</name>

</attribute>

</tag>

</taglib>

把这个文件取名为*.tld,并把它放在应用程序的WEB-INF/tlds目录下。

(3) 现在你可以这样在JSP页面中使用自定义行为。

<%@ taglib uri=”/WEB-INF/tlds/mylib.tld” prefix=”test” %>

<html>

<body bgcolor=”white”>

<test:hello name=”maojb”/>

</body>

</html>

当这个页面被请求时,JSP容器就使用这个TLD来发现与自定义行为相对应的类。然后它将调用所有相应的方法,将相应的文本加入到应答中去。以上就是在最简单的情况下我们要做的所有事情。

4. 先来看一下最重要的Tag接口的方法:

public void setPageContext(PageContext pageContext);

public int doStartTag() throws JspException;

public int doEndTag() throws JspException;

然后我们了解一下TagSupport类提供的对这些方法的实现。

Public class TagSupport implements Tag , Serializable {

Protected PageContext pageContext;

…….

Public void setPageContext(PageContext pageContext) {

This.pageContext = pageContext;

} //这个方法是在使用标记处理程序之前被JSP容器调用的。

Public int doStartTag() throws JspException {

Return SKIP_BODY;

} //当遇到开始标志时,JSP容器将调用doStartTag()方法。

Public int doEndTag() throws JspException {

Return EVAL_PAGE;

} //当遇到结束标志时,JSP容器将调用doEndTag()方法。

}

5. 开发一个不需要对行为元素体做任何事情的标记处理程序是非常简单的。然而,对于一个需要处理行为体的标记处理程序来说,还需要一些方法。这些方法是由BodyTag接口定义的,该接口扩展了Tag接口。

6. 一个有行为体的标记处理程序的执行过程。

(1) setAttr1(“value1”)

(2) setAttr2(“value2”)

(3) doStartTag()

(4) setBodyContent()

(5) doInitBody()

(6) doAfterBody()

(7) doEndTag()

7. BodyTagSupport类有许多实用的方法来处理行为体。

如:getBodyContent() , getPreviousOut()

8. 如何让多个行为互相协作。

内层行为是如何告诉外层行为自己定义参数信息之类的东西呢?这个问题的答案就在由TagSupport类实现的一些Tag接口方法和一个工具方法里。

这些Tag接口的方法是setParent()和getParent() 。一个嵌套的标记处理程序通常有一个对容纳它的父元素的引用。所以,一个在任意嵌套层次上的标记处理程序可以使用getParent()方法来得到它的父元素,然后可以得到父元素的父元素。可以一直这样下去,直到到达一个没有父元素的Tag(即getParent()返回了null)。这意味着已经到达了最外层。

通常说来,一个标记处理程序只对那个它要与之协同工作的父元素感兴趣。所以,一个好的想法是开发一个方法,该方法将沿着层次结构不断向上追溯,直到找到标记处理程序感兴趣的那个父元素。而这正是TagSupport类所实现的findAncestorWithClass()方法所做的工作。

Public static final Tag findAncestorWithClass(Tag from , Class klass) {

Boolean isInterface = false;

If(from == null || klass == null || (!Tag.class.isAssignableFrom(klass) &&

!(isInterface = klass.isInterface()))) {

return null;

}//假如from或者klass为null , 或者klass是一个类并且没有实现Tag接口,显然当前Tag找不到klass类的父元素。

for(;;) {

Tag tag = from.getParent();

If(tag == null) {

Return null;

} //表示没有父元素

if((isInterface && klass.isInstance(tag)) || klass.isAssignableFrom(tag.getClass()))

return tag; //假如klass是接口并且当前tag实现了该接口,那么找到了。

//或者当前tag是klass类型的,那么找到了。

else

from = tag;

}

}

9. 通过行为创建新的变量

当自定义行为创建一个变量时,它必须与JSP容器合作。

对于一个标记处理程序来说,创建一个新的对象并使得其他行为和JSP脚本代码可以访问这个对象,需要两件事情:

(1) JSP容器必须知道对象的名称和Java类型,这样它才能为变量声明生成代码。

(2) 变量必须被放置在某个JSP作用域内,这样才能通过findAttribute()方法找到它,并能赋值给这个变量。

第一件事由一个名为TagExtraInfo的类来完成。当你为一个引入对象的行为开发标记处理程序时,你必须创建TagExtraInfo类的一个子类。JSP容器在生成代码的时候就需要这样一个类的实例。

10. 开发迭代行为

开发迭代行为时,通常也需要一个TagExtraInfo子类,这样才能在loop的过程中访问loopID变量。

11. 如何创建TLD

当JSP容器将自定义行为元素转化成创建并调用正确的标记处理程序的代码时,JSP容器还需要关于哪个标记处理程序实现哪个自定义行为元素的信息。而这些信息都是从TLD那里获得的。另外,JSP容器还使用TLD信息来验证行为元素的属性列表是否正确。

TLD是一个XML文件,它包含了一个库中所有自定义行为的信息。使用自定义行为的JSP页面必须能识别相应的TLD,还能够利用taglib指令元素在页面中识别出用于行为的名称空间前缀。如:

<%@ taglib uri=”/WEB-INF/tlds/orataglib_1_0.tld” prefix=”ora” %>

….

<ora:redirect page=”main.jsp”/>

JSP页面里遇到前缀匹配的行为时,JSP页面就会用TLD来查找它需要的信息。

TLD文件中的内容:

(1) 最顶部:标准的XML声明和一个DOCTYPE声明。(这两个声明指定了文件的文档类型定义Document Type Definition , DTD)。

(2) <taglib>元素: TLD的主元素,它包含了描述库的所有特定元素。

(3) <tlibversion>元素:指定标记库的版本。必须

(4) <jspversion>元素:指定了库所依赖的JSP规范的版本。默认值为1.1。可选

(5) <shortname>元素:必须元素。这个元素的值中不能包含空格或其他特殊字符,也不能以数字或下划线开头。

(6) <uri>元素:可选,字符规则同上。

(7) <info>元素:可选,

(8) TLD中至少还必须包括一个<tag>元素。<tag>元素中包含了描述自定义行为的各个方面的其他元素:<name> <tagclass> <teiclass> <bodycontent> <info> <attribute>

l <name>元素是必须的。它包含了自定义行为元素对应的名称,这个名称是唯一的。

l <tagclass>元素也是必须的。

l 如果行为引入了变量,或者需要进行语法验证,那么就要使用<teiclass>元素。这个元素是可选的,用来制定TagExtraInfo子类的全名。

l <bodycontent>元素是一个可选元素,它的三个可能值为:empty , JSP或tagdependent。

l <info>元素是可选的,用来描述行为的目的。

l tag元素还必须为行为的每个属性设置<attribute>元素。当然每个元素中也包含了描述属性的另外一些元素:<name>,<required>和<rtexprvalue>

12. 语法验证

(1) 最简单的语法验证是:

当JSP容器将一个JSP页面转化成Servlet时,它会将自定义行为元素和TLD中行为元素的规范进行比较。这样就可以验证语法上的错误。

(2) 某些语法验证就要复杂许多了。如:一些属性依赖于其他属性是否出现。有些属性是排他的,如果使用了这个就不能使用那个。某个可选的属性必须和其它的可选属性一起使用。为了验证这些依赖性,JSP容器必须向标记处理程序的TagExtraInfo子类寻求支持。

在JSP容器检查完一切它自己能检查的以后,它会为行为查找TagExtraInfo子类(由<teiclass>元素定义)。如果定义了TagExtraInfo子类,它就将所有属性信息放到TagData类的一个实例中,并调用TagExtraInfo的isValid()方法,参数是装有信息的TagData类。

13. 如何重用标记处理程序

建议在release()方法中完成重置所有属性的工作。

14. 如何打包和安装标记库

在完成开发后,你可能希望将所有的标记处理程序类,TagExtraInfo类,标记处理程序类中使用的bean和TLD打包到一个JAR文件里。这样可以使得在应用程序中安装库更加容易。TLD在JAR文件中必须被存为/META-INF/taglib.tld。

(1) 为了创建JAR文件,按照下面的结构来安排目录下的文件。

META-INF下:taglib.tld

将所有类放在com目录上

文件结构设置好就使用jar命令创建一个JAR文件:

jar cvf maojb.jar META-INF com

(2) 将JAR文件拷贝到应用程序的WEB-INF/lib目录下。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有