分享
 
 
 

标签库的深入研究

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

标签库Taglib

标签被定义和分布在一个称为标签库的结构中,一个标签库是由元信息和类组成的集合:

1.标签处理器:实现定制标签功能的Java类。

2.标签附加信息(TEI):向JSP容器提供边辑以确认标签属性和创建变量的类。

3.标签库描述器(TLD):描述单个标签和整个标签库属性的XML文档。

标签处理器和标签附加信息需要定位在JSP容器类载入器可以找到的地方。标签库描述器可在URL指定的符意位置。JSP1.1规范要求JSP容器接受一个打包成因定结构的JAR文件的标签库。TLD必须是/META-INF目录中名为taglib.tld的文件,JAR文件则复制到/WEB-INF/lib目录下。

一、标签实现

1.开发步骤

a.定义标签的名字、属性、声明的变量和标签体的内容。

b.编写标签库描述器TLD。

c.编写标签处理器。

d.在JSP页面中使用标签。

2.JSP页面在JSP容器中的转换步骤:

JSP页面存在三种形式:jsp文件、java文件和class文件。

a.指令元素<%@page%>、<%@include%>和<%@taglib%>向JSP容器提供转换时信息。

b.HTML行在_jspService()方法中依顺序转换到out.print()语名中。

c.脚本元素的声明被原封不动地复制到_jspService()方法外的源码中。

d.脚本元素的表达式在_jspService()方法中依顺序转换到out.print()语名中。

e.脚本元素的Scriptlet被原封不动地复制到_jspService()方法中。

f.行为元素被转换为执行其功能的运行时逻辑代码。

g.定制标签被扩展到调用其相应标签处理器中方法的Java语句中。

3.标签在JSP容器中的转换步骤:

a.JSP容器使用taglib指令元素定位标签库描述器,将页面中用到的定制标签和TLD相匹配。

b.读取标签库描述器的标签列表和每一标签相关的类名字。

c.在页面中遇到一个标签时,查找与具有指定名字的标签前缀相关的一个标签库。

d.容器使用在TLD中找到的标签结构信息生成一系列完成标签功能的Java语句。

二、标签库描述器(TLD)

标签库描述器是一个描述整个标签库标记信息和库中每个标签处理器及其属性的XML文档。

标签库描述器的DTD由一个简单的<taglib>元素组成,此元素包含下列一些子元素。

整个标签库标记信息

tlibversion标签库版本号。是一个点式十进制数,最多为4组小数点分隔的数字组成。

jspversion标签库所需的JSP规范最低版本。例如JSP1.1

shortname标签库的缩写名。JSP可以使用该名字作为库中标签的缺省前缀。

uri标签库唯一URI的元素。典型URL位置来自可下载taglib的位置。

info标签库描述信息。

每个标签处理器及其属性

tag在TLD中加入标签,描述组成库的每个标签。

name与标签库的名字前缀一起使用的标签的名字,是JSP容器唯一的标签标识。

tagclass实现标签的标签处理器类的全名。

teiclass标签附加信息(TEI)类的全名。TEI类给出关于标签处理器创建变量及对标签司性执行的任意有效性验证的信息。

bodycontent描述标签处理器如何使用标签体的内容。有三种取值:

empty:表示标签体必须为空;

JSP:表示脚本元素和模板及其它标签一样被评估。

tagdependent:体内容被原封不动写入BodyContent,其它脚本元素以源码形式出现,而不被JSP容器解释。

info标签的人工可读描述性信息。

attribute使用标签时被编码的属性信息。用于定义标签的属性。

<name>属性名</name>:属性的名字。

<request>true|false</request>:属性在标签用到的位置是否要被编码。

<rtxexpvalue>true|false</rtxexpvalue>:属性值能否用表达式指定。

三、标签处理器

标签处理器是通过实现JSP容器调用的一系列预定义方法执行定制标签行为的一个Java类。

标签处理器实现了标签的行为,标签处理器是Java类。

1.标签处理器的工作方式

a.导入javax.servlet.jsp和javax.servlet.jsp.tagext包。

b.实现javax.servlet.jsp.tagext包中的Tag接口或BodyTag接口。BodyTag是Tag的子接口。

c.继承TagSupport类或BodyTagSuppoert类。它们是上述接口的缺省实现。

d.重载publicintdoStartTag()throwsJspException方法。

2.标签处理器的接口与实现

javax.servlet.jsp.tagext.Tag是实现标签的最基本的接口。

javax.servlet.jsp.tagext.TagSupport是实现Tag接口的具体类。

通常情况下继承tagSupport类而不直接实现Tag接口通常是有益的。除了对所有必需方法提供了缺省实现外、还保存了pageContext对象及对嵌套标签的支持。

Tag接口包含4个常量,表示doStartTag()和doEndTag()方法可能的返回码。

EVAL_BODY_INCLUDE当doStartTag()返回时,指明servlet应对标签体进行评估。

SKIP_BODY当doStartTag()返回时,指明servlet应忽视标签体。

EVAL_PAGE当doEndTag()返回时,指明页面其余部分应被评估。

SKIP_PAGE当doEndTag()返回时,指明页面其余部分就被跳过。

Tag接口的方法

publicvoidsetPageContext(PageContextctx)生成的servlet在请求处理器执行其它任务前首先调用此方法,实现类应保存上下文对象以便它可以在标签生命期中使用。从页面上下文中标签处理器可以访问所有JSP隐含对象。

publicvoidsetParent(Tagp)使用一个标答可以找到操作栈中它上面的标签。在setPageContext后立即调用。

publicTaggetParent()返回父标签。

publicintdoStartTag()throwsJsp在设置了页面上下文、父标签和开始标记中编码的属性后调用。返回码表明JSP实现servlet是否就评估标签体。

publicintdoEndTag()throwsJspException当遇到结否标记时调用。返回码表明JSP是否就继纽页面的其余部份。

publicvoidrelease()确保在页面退出前被调用。释放资源并重置标签处理器状态。

TagSupport类的方法

publicstaticTagfinAncestorWithClass(TagthisTag,Classcls)为所需的父标签处理器查找运行时标签栈。一个标签处理器可以提供其范围内子标签调用的方法。

publicvoidsetId(Stringid)保存和检索在id属性中指定的名字。

publicvoidsetValue(Stringname,Objecto)在本地哈希表中设置指定名字的值。

publicObjectgetValue(Stringname)从本地哈希表中获取指定名称的值。

publicvoidremoveValue(Stringname)从本地哈希表中删除指定名称的值。

publicEnumerationgetValues()返回哈希表中关键字的一个枚举。

3.标签处理器的生命期

a.生成servlet需要创建标签处理器类的一个实例。实现方式通常是调用JSP容器的工厂类的一个方法,工厂类包含一个标签处理器实例池以使其可重用不再处于激活状态的对象。

b.初始化标签处理器,使servlet获知其存在性。servlet通过调用标签处理器的两个方法实现此过程:setPageContext(PageContextctx)和setParent(Tagparent)。

c.如果标签具有属性,属性的取值通过处理器提供setter方法传入到对象。属性setter方法是一个标签支持属性所需的唯一方法。

d.页面的上下文和父标签已被调置,并已具备属性。此时调用标签处理器的doStartTag()方法,该方法可以读取这些变量并执行实现标答功能所需的计算和操作。doStartTag()方法必须返回一个整型数。返回EVAL_BODY_INCLUDE则正常处理标签体,返回SKIP_BODY则从初始JSP页面中直到此标签结束标记处的内容均被忽略。

e.标签体被评估或忽视后调用标签处理器的doEndTag()方法,返回EVAL_PAGE则页面的其余部分被评估,返回SKIP_PAGE则servlet代码立即从_jspService()中返回。

4.体标签处理器的接口与实现

javax.servlet.jsp.tagext.BodyTag是Tag的子接口。

javax.servlet.jsp.tagext.BodyTagSupport是实现BodyTag类。

BodyContent是javax.servlet.jsp.JspWriter的子类,但与其父类有所区别。

BodyContent对象的内容不自动写了入servlet的输出流,而是积累在一字符串缓存中。当标签体完成后其对象仍可在doEndTag()方法中可以应用,由getString()或getReader()方法操作。并在必要时修改及写入恢复的JspWriter输出流。

BodyContent类的方法

publicvoidflush()throwsIOException复写JspWrite.flush()方法以便它总是产生溢出。刷新写入已失效,因为它没有连接到将被写入的实际输出流中。

publicvoidclearBody()重置BodyContent缓存为空。

publicReadergetReader()返回Reader读取体内容。

publicStringgetString()返回包含体内容的一个字符串。

publicvoidwriteOut(Writew)将体内容写入指定输出。

publicJspWritegetEnclosingWrite()返回栈中下一个更高的写入者对象(可能是另一个BodyContent对象)。

BodyTag接口定义了一个新的整型常量

EVAL_BODY_TAG当doStartTag()返回时,使得新的BodyContent对象被创建并与此标签处理器相关联。当doAfterBody()返回时,使得JSPservlet在修改完此标签控制的任意变量后再次评估体。

BodyTag接口的方法

publicvoidsetBodyContern(BodyContentout)在当前JspWriter已被写入,一个新的BodyContent在被创建后由Jspservlet调用,它发生在doStartTag()之后。

publicvoiddoInitBody()throwsJspExceptionsetBodyContent()之后,体被评估前调用的生命期方法。如果多次评估体,此方法只调用一次。

publicinitdoAfterBody()throwsJspException体被评估后,BodyContent写入者仍处于激活状态时调用的生命期方法。此方法必须返回EVAL_BODY_TAG或SKIP_BODY,若返回EVAL_BODY_TAG时体再次被评估。

BodyTagSupport类的方法

publicintdoStartTag()throwsJspException复写TagSupport中的doStartTag()方法。

publicintdoEndTag()throwsJspException调用TagSupport中的doEndTag()方法,返回结果。

publicvoidsetBodyContent(BodyContentout)在一保护成员变量bodyContent中保存新的体内容对象,子类可直接访问此对象。

publicvoiddoInitBody()throwsJspException缺省什么都不做。被需要执行初始化的子类所复写。

publicintdoAfterBody()throwsJspException每次体被评估后由JSPservlet调用,体同容对象仍处于激活状态。返回SKEP_BODY或EVAL_BODY_TAG则体再次被评估

publicvoidrelease()设置bodyContent对象为null,然后调用super.release()。

publicBodyContentgetBodyContent()返回bodyContent变量。子类已经可以访问保护变量,但此方法允许无关的标签处理类对此体内容发送输出。

publicJspWritergetPreviousOut()在bodyContent变量上调用getEnclosingWriter()并返回结果的简便方法。

5.体标签处理器的生命期

a.生成servlet需要创建标签处理器类的一个实例。实现方式通常是调用JSP容器的工厂类的一个方法,工厂类包含一个标签处理器实例池以使其可重用不再处于激活状态的对象。

b.初始化标签处理器,使servlet获知其存在性。servlet通过调用标签处理器的两个方法实现此过程:setPageContext(PageContextctx)和setParent(Tagparent)。

c.如果标签具有属性,属性的取值通过处理器提供setter方法传入到对象。属性setter方法是一个标签支持属性所需的唯一方法。

d.页面的上下文和父标签已被调置,并已具备属性。调用标签处理器的doStartTag()方法,该方法可以读取这些变量并执行实现标答功能所需的计算和操作。

doStartTag()方法必须返回一个整型数。

返回EVAL_BODY_TAG则正常处理标签体(跳到e);

返回SKIP_BODY则从初始JSP页面中直到此标签结束标记处的内容均被忽略。(跳到f)

e.如果返回EVAL_BODY_TAG时,则正常处理标签体。

e1.在栈中保存当前的JspWriter对象,创建新的BodyContent对象,并将其置为JSP页面的out对象保存在上下文范围内名为name的属性中。并调用它的setBodyContent()方法。

e2.调用doInitBody()方法进行初始化。

e3.处理标签体。将输出写入BodyContent对象中,此过程依赖于TLD的标签元素<bodycontent>,有三种可能取值。

e4.调用doAfterBody()方法,将体内体内容写入JspWriter,可如下实现:

JspWriterout=bodyContent.getEnclosingWriter();

out.println(bodyContent.getString());//bodyContent.writeOut(out);

bodyContent.clear();

e5.doAfterBody()方法返回两种可能:

返回EVAL_BODY_TAG时,再对标签体进行评估,这是数组和枚举被循环处理的典型情况。

返回SKIP_PAGE时,继续页面的其余部份。

e6.体内容完成,因此创建它的过程被反向:

调用pageContent.popBody()方法检索前面的JspWriter对象。

将写入者设置回out隐含对象。

f.标签体被评估或忽视后调用doEndTag()方法,允许标签处理器像输出流发回内容。

返回EVAL_PAGE则页面的其余部分被评估;

返回SKIP_PAGE则servlet代码立即从_jspService()中返回。

g.此时体的内容在受保护的bodyContent对象中仍然可用。

可以将它写入servlet输出流中:

JspWriterout=pageContext.getOut();

out.println(bodyContent.getString());

或者

bodyContent.WriteOut(pageContext.getOut());

6.标签附加信息类

四、标签指令

taglib指令元素的目的是指定TLD的位置,设置在页面上与标签区分开来的一个短别名。

语法:<%@taglibprefix=”tagprefix”uri=”taglibURI”%>

属性:prefix:用于标识标签库的唯一标识。uri:标签库本身的URI。

uri不必指向一个实际文件,它是JSP容器可以在web.xml中查找实际文件位置的唯一标识符。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有