社区应用 最新帖子 精华区 社区服务 会员列表 统计排行 社区论坛任务 迷你宠物
  • 4223阅读
  • 1回复

一篇介绍JSP标签库很详细的文章,可以做为参考手册

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! 4svBzZdr  
j%Y#(Q>  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 =Z{O<xw'  
|T<_5Ik  
在这篇文章中,我们主要讨论: '50OgF'  
K='z G*$l  
· 什么是自定义tag标签? /74QMx?  
8^kGS-+^  
· 怎么使用tag标签? /}((l%UE.  
u0}vWkn\4  
o 声明要使用的tag库 ]P9l jwR  
B |5]Jm]  
o 找到与之对应的tag处理类 4(#'_jS  
1NbG>E#Ol  
o tag标签的类型 MS nG3]{z  
%2}-2}[>  
· 自定义tag标签 v3*_9e  
D.r<QO~6B  
o tag处理类 2+RUTOv/d  
yjO1 Ol  
o tag库描述 .H escg/S  
\Q {m9fE  
o tag标签示例 _jvxc'6  
A9[ F  
o 带属性的tag R#s )r  
NyaQI<5D  
o 带body的tag n"h `5p5'  
<]6SN  
o 定义了脚本变量的tag UBv,=v  
df*#!D7oz  
o 具有协作关系的tag 3RigzT3  
59 h]UX=  
· 自定义tag标签 kC:uG0sW  
nB_?ckj,  
o 一个迭代tag的例子 '<gI8W</  
raW>xOivR  
o 一个模板tag库 g!|=%(G=  
[NF'oRRD9s  
o tag处理类到底是怎样被调用的? ^dI424  
5A,K6f@:g  
bYcV$KJk  
什么是自定义的tag? R]JT&p|w.1  
,A9]CQ  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 %{7|1>8  
>d(~# Z`  
自定义tag标签有很多特色,诸如: EW}Bzh>b  
$1SPy|y  
· 可以在JSP页面中自定义tag标签的属性 zU,9T  
3Lfqdqj  
· 访问JSP页面中的所有对象 0^v`T%|fTX  
KsddA  
· 可以动态地修改页面输出 Lt2u,9  
kT|dUw9G  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 \9.bt:k@OT  
xn?a. 3b'  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 m1j*mtu  
<NHH^M\N  
R$EW4]j  
使用tag标签 XP`Nf)3{Yd  
_Mi5g_  
j9m_jv  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 q'+)t7!  
7( #:GD  
要使用tag标签,JSP程序员必须做2件事: ay4 %  
\Yy$MLs  
· 声明此tag标签的tag库 #./fY;:cj  
-Sq z5lo  
· 实现此tag标签 $&Gu)4'+  
?(xnSW@r  
声明tag标签所在的tag库 J; S (>c  
&PL8|w  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) dR K?~1  
bes<qy  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> J.3u^~zy  
<3L5"77G 6  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 bs+f,j-oBN  
I.I`6(Cb  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 SbcS]H5Sk  
.[YuRLGz  
以下taglib指示符直接引用一个TLD: !d'GE`w T  
D,FHZD t  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> 2Zm0qJ  
87=&^.~`  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: +|*IZ:w)  
<:_wbVn-  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> 9U7nKJ+iby  
,t3wp#E2#  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: k3~}7]O)  
bjyZk_\  
<taglib> OwuE~K7b{  
aasoW\UG  
<taglib-uri>/tutorial-template</taglib-uri> FOb0uj=(v  
c7?_46 J  
<taglib-location> O8^A5,2@3>  
,yC-+VL  
/WEB-INF/tutorial-template.tld 9q)Kfz  
N>Xo_-QCY  
</taglib-location> \TIT:1  
j 'FVz&  
</taglib> ?}qttj  
W,D4.w$@'  
{vs uPY  
实现此tag标签 lVd^ ^T*fh  
 JR'  
Ltv]pH}YN  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 =pr` '  
"7U4'Y:E  
}I2wjO  
tag标签类型 $Y;U[_l#  
Gw=B:kGk  
?yZ+D z\  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): N%kt3vmQ_  
\$R_YKGf1G  
<tt:tag> IO wj>t  
o\BOL3H  
body 1Vsz4P"O $  
7Sf bx~48  
</tt:tag> Uq[>_"}  
uyO/55;HO  
m&xW6!x  
一个不带body的tag标签如下: +ndaLhj'  
a Ve'ry  
<tt:tag /> N1Ng^aY0  
B`YTl~4  
9Q.rMs>qj  
简单的tag标签 s kv GU(G}  
\@Ts+7%  
一个没有body和属性的tag标签如下: i 6R~`0>Q  
*lYVY) L  
<tt:simple /> 5c9^-|-T  
^"2i   
7jxslI&F  
带属性的tag标签 bW$,?8(  
u6?Q3 bvI  
C7XxFh  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 oxC[F*mD  
tW.9yII  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: ng[Ar`  
8G9s<N}5&u  
<loglic:present parameter = “Clear”> S3F;(PDzy  
r~E=4oB7  
而另一个标签logic:iterate是用表达式来给属性赋值: XywE1}3  
Gp1?iX?ml  
<logci:iterate collection=”<%= bookDB.getBooks() %>” 1!ii;s^e  
VX].3=T8  
id=”book” type=”database.BookDetails”> cIUHa  
\}+_Fo/  
? 8)'oMD  
带body的tag标签 Jk&3%^P{m  
E8!e:l =Q  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 LVX[uWEM  
[\'%?BH(^  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: t;\kR4P  
A]<y:^2])C  
<logic:present parameter=”Clear”> b v G/|U  
t 4PK}>QW  
<% cart.clear(); %> 2- &k^Gl!:  
<x@}01 ~  
<font color=”#ff0000” size=”+2”><strong> hM@ HA  
*e<[SZzYZ  
你选择了清除购物车! G(Lzf(  
o#;b  
</strong></font> vmi+_]   
nv GF2(;l  
</logic:present> ccNd'2P  
* ;-*x6  
+?F[/?s5qz  
到底是用属性还是用body来传递信息? "&%I)e^  
;>#wU'  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 pN!}UqfI-  
'ZT^PV \  
qJ;jfh!  
定义脚本变量的tag标签 #G .ulX  
_|iSF2f,X  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: KmMzH`t}`  
wi;Br[d  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> 3Iua*#<m,  
:a^t3s  
<% tx.begin(); %> <_h~w}  
e 63uLWDT  
... 5"^en# ?9  
lAi6sPG)0  
j:<n+:H C  
具有协作关系的tag标签 dUsYZdQs  
p%#<D9S  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 FFV `P  
{`J)j6;  
<tt:tag1 attr1=”obj1” value1=”value” /> ;P;-}u  
=V-A@_^!c  
<tt:tag2 attr1=”obj1” /> o%v0h~tn  
uH/J]zKR  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 V:qSy#e  
vBRQp&YwX  
<tt:outerTag> YHkn2]^#A  
Qr1"Tk7s  
<tt:innerTag /> mIurA?&7!  
^]7}YF2|  
</tt:outerTag> AZ0;3<FfLp  
j\,EO+ZQCv  
<L`KzaA  
Tag处理类 `2'#! -  
`rgn<I"  
RzBF~2 >i  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 9}l33T4T  
&]8P1{  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 oT^{b\XN  
LISM ngQ.  
下表说明不同类型的tag所需要不同的处理过程: ./,/y"x  
lm!.W5-l  
Tag处理类的方法 mZk]l5Lc  
,ek_R)&[o  
Tag标签类型 4~y(`\0?4  
所调用的方法 tro7Di2Q  
?h.wK  
基本标签 M%Ji0v38  
doStartTag, doEndTag, release G]D+Sl4<7i  
2-7IJ\  
带属性的标签 yGWxpzmRS  
doStartTag, doEndTag, set/getAttribute1...N, release bW$J~ynM  
m4aB*6<lq  
带内容的标签 iEd\6EZ  
doStartTag, doEndTag, release >{N9kW Y  
Kh,V.+7k  
带内容的标签,且内容重复循环 J]v%q,"  
doStartTag, doAfterBody, doEndTag, release IzsphBI  
}x@2]juJ  
带内容的标签,且内容与JSP交互 txW{7+,  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release Q?e*4ba  
QOjqQfmM;  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 s@9vY\5[9  
{ D^{[I  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 W"zab  
Id'X*U7Q  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 PfreAEv,  
5i> $]*o  
!;0U,!WI  
Tag库描述(简称TLD) 9  TvV=  
-}=i 04^  
,u!*2cWN  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 G;&-\0>W  
DBPRGQ  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 y<HO:kZ8`  
>_e]C}QUr  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: >*]Hq.&8  
WP?TX b`5  
<?xml version="1.0" encoding="ISO-8859-1" ?> kgnmGuka  
?!9 )q.bW  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> yOphx07 (  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: 74H)|Dkx  
}lh I\q  
&S( .GdEf  
<taglib>的子元素 PK;*u,V  
[<-  
Element 7l'6gg  
Description |K6REkzr  
|<#{"'/=  
tlib-version AB F"~=aL  
Tag库的版本 ko Z  
c\iA89msp  
jsp-version =; ^%(%Y{m  
Tag库所需要的jsp的版本 l ;JA8o\x  
(^@ra$.  
short-name V=zi >o`   
助记符,tag的一个别名(可选) Qy.w=80kf  
"5-^l.CKH  
uri V^JV4 `o  
用于确定一个唯一的tag库 6I1,:nLL<  
)=5ng-  
display-name iMIlZ  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) ]vgB4~4#LP  
lLp^Gt^}w(  
small-icon `&KwtvkdI  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) vY%d   
>H'4{|  
large-icon {7$c8i  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) $UgA0]q n  
R#2t)y  
description 1abtgDL  
对tag库的描述(可选) fJ/e(t  
~MS\  
listener .#1~Rz1r  
参见下面listener元素 9A} # 6  
Yj)#k)x  
tag 6b+b/>G0  
参见下面tag 元素 dE:+k/  
^~G8?]w  
Listener元素 ^SxY IFL  
&GlwC%$S  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 U4gF(Q  
RT)d]u  
Tag元素 9:,V5n=  
RnhL< Ywu  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 ,_yh z0.  
kD*2~Z?;  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: Ys@}3\Mc  
Pm lx8@D  
Tag元素的子元素 _acE:H  
0Uz\H0T1  
元素名称 UG2nX3?  
描述 ROk5]b.  
O) WCW<p  
name XLAN Np%E  
独一无二的元素名 I3,= 0z  
@$LWWTr;  
tag-class 5D_fXfx_|  
Tag标签对应的tag处理类 Sg6"WV{<  
BB~OqZIP  
tei-class "Jt.lL ]5  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) r.#t63Rb  
f2^r[kPX"  
body-content :|Ad:fEs  
Tag标签body的类型 DTa N"{  
Ys,{8Y,7  
display-name T{Sb^-H#X  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) Z$0 uH*h  
gA:5M  
small-icon TQx.KM>y  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) O+?<h{"  
Au4yBm u  
large-icon UVw~8o9s  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) PNaay:a|  
BO~PT,QrF  
description m9"n4a|:  
此tag标签的描述 -TM 0]{  
|P -8HlOr  
variable #$c Rkw  
提供脚本变量的信息(同tei-class)(可选) blTo5NLX  
1E73i_L  
attribute ^go7_y  
Tag标签的属性名 4g : >[q  
GlbySD@  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 dHK`eS$sb  
$:  ]o]a  
?gJy3@D  
简单的tag 5dB'&8DX  
$% 1vW=d  
<Wp QbQM  
tag处理类 vgUb{D  
zipS ]YD  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 =dII- L=`  
~ECD`N<YF  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: r6&5 4f  
<^zHE=h"  
~$p2#AqX  
public SimpleTag extends TagSupport ]`&Yqg  
Dh5X/y  
{ H63,bNS s  
\/1<E?Q f  
public int doStartTag() throws JspException Td G!&:>  
Gm(b/qDDe  
{ Kj<^zo%w  
L ]w/P|  
try{ D3)zk@N  
);Z1a&K5k  
pageContext.getOut().print(“Hello.”); 6(G?MW.  
-5T=:2M  
}catch(Exception e){ iVd.f A  
(cN}Epi(D  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); *e-A6S h  
\'9PZ6q{  
} R,|d`)T  
G(~;]xNW+  
return SKIP_BODY; d1U\ft:gV  
-u? S=h}  
} ,(;lIP  
3:8{"md@2  
public int doEndTag() K91)qI;BD  
w9o^s5n  
{ e_/b2"{  
 w~ [b*$  
return EVAL_PAGE; >2]JXLq  
'A:x/iv}^  
} %K>.lh@  
h=(DX5:A  
} zOGU8Wg  
^_ kJKM,  
I =1+h  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 YhY:~  
/r-aPJX  
<body-content>empty</body-content> * 1Od-3  
uPRQU+  
7}vg.hmZ  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 +e-G,%>9  
S6fL>'uQ  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, bzvh%RsW  
E@P %v{)  
<logic:present parameter=”Clear”> %s&ChM?8F  
>-O/U5<!  
与此相应,此tag处理类应有如下方法和定义: y| Ir._bt  
1c;6xc,ub  
r" K':O6y  
protected String parameter = null; k<cgO[m   
3q`)*  
public String getParameter() E=cwq"  
;s~X  
{ MdXchO-Lyc  
&m[Qn!>i6  
return this.parameter; *b xzCI7b  
l983vKr  
} %/>Y/!;  
IXb}AxB f  
public void setParameter(String parameter) r YF #^  
}=|!:kiE  
{ OQ,NOiNkap  
<ERB.d!  
this.parameter = parameter; ua OKv.%  
H<QT3RF2  
} J7v|vj I  
9 Rx s  
8o/}}=m$  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 (%U@3._  
.S%0   
Attribute元素 JkGnKm9G  
;A'":vXmc  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 Fh*j#*oe  
CT\;xt,S  
<attribute> B}eA\O4}I  
UK{irU|\  
<name>attr1</name> -_<}$9lz  
Q//,4>JKf  
<required>true|false|yes|no</required> &<+ A((/i  
VOr1  
<rtexprvalue>true|false|yes|no</rtexprvalue> PC qZNBN  
?h0X,fl3  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> !=y]Sv~h  
^+ wD43  
</attribute> r)T:7zy  
R@wjccu  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 5BR2?hO4  
wP57Pf0  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 I"1;|`L~:  
c5Q<$86  
<tag> &|aqP \Q5  
(708H_  
<name>present</name> 1&/FG(*/  
5o/&T"]@  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> 1pCieTz!PN  
fl;s9:<  
<body-content>JSP</body-content> jA(>sz  
kvh&d|  
z`Hy'{1  
)~V4+*<  
<attribute> fRfn2jA)d  
} %'bullT  
<name>parameter</name> k"N(o(  
5qf BEPJ  
<required>false</required> zvvP81$W  
m{7^EF  
<rtexprvalue>true</rtexprvalue> yi^b)2G  
U;n*j3wT  
</attribute> r|*&GHo L  
jAh2N3)  
Q`#4W3-,  
!;Jmg  
</tag> j Y6MjZI  
n9;;x%6.I  
TM8 =U-A  
属性元素的校验 huudBc A[  
&vovA} F  
[DHoGy,P  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 {T'GQz+R"  
KI]wm  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 4 V1bLm  
,+;:3gRk9  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 @R m-CWa  
%Rh;=p`  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: -AYA~O(&  
^VT1vu %03  
<attribute> @h?shW=^  
"C?5f]T  
<name>attr1</name> F/1#l@qN  
?%O3Oi Xz  
<required>true</required> j$da8] !  
_al|'obomy  
<rtexprvalue>true</rtexprvalue> L'i-fM[#  
7DKz;o  
</attribute> )s9',4$eK<  
$DBGLmw  
B$KwkhMe  
这个定义说明了attr1能在运行期间被赋值。 ~dHM4lGY  
#tdf>?  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 _28<m JfG  
\tyg(srw0  
'O6]0l  
Public class TwaTEI extends TagExtraInfo 3K@@D B6  
!TAp+b  
{ as+GbstN  
XI Jlc~2  
public boolean isValid(Tagdata data) /Jf~25F  
I =Wc&1g  
{ %g]vxm5?  
-xg2q V\c  
Object o = data.getAttribute(“attr1”); uE=$p)  
>\<*4J$PZ  
If(o != null && o != TagData.REQUEST_TIME_VALUE) }]UB;id'  
: t$l.+B  
{ qP!P +'B  
S<nq8Ebmw  
if( ( (String)o).toLowerCase().equals(“true”) || _)$PKOzbb  
A\Txb_x  
((String)o).toLowerCase().equals(“false”) ) !}M,  
JIO$=+p  
return true; #(LfYw.P1V  
O;[9_[  
else "tS'b+SJ-S  
ZiFooA  
return false; Xl |1YX1&m  
ExHAY|UA  
} XH7xT@  
?R Fg$Z'^  
else K:y^OAZfV  
8 iC:xcN3  
return true; w(nHD*nm  
w'7R4  
} m+$ @'TbP  
MVCl.o  
} V+wH?H=  
E{Pgf8  
!.5),2  
带body的tag !SHj$Jwa'  
}iBC@`mg(  
_L.n,  
tag处理类 % 0:p)Z0  
o**yZ2  
%qsvtc`  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 Zszs1{t  
(y4#.vZh:  
Tag处理类不与body交互 o=fgin/E\  
;%q39U}  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 Bz2'=~J  
%1McD{  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 ts9pM~_~  
+UWU|:  
Tag处理类与body交互 J#3{S]* v_  
L$v^afP?  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 !{_yaVF  
x;BbTBc>  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 E^ h=!RW{  
qW^vz  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 cX2^wu  
Vs 0 SXj  
doInitBody 方法 ":?T%v>  
nw'-`*'rj  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 "u' )g&   
\Mx JH[  
doAfterBody方法 @fn6<3  
zz$q5[n  
此方法在body内容已被计算后进行调用。 U!q[e`B  
eQX`,9:5  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 ,35&G"JK5  
q(z7~:+qNr  
release 方法 eTE2J~\  
P]<= ! F  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 Sg*0[a3z  
0??Yr  
[!*xO?yCJ  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 EH9Hpo  
,qFA\cO*  
q@#BPu"\l  
Public class QueryTag extends BodyTagSupport L0h G  
1-;?0en&0  
{ jPu5nwvUV>  
uVU`tDzd:  
public int doAfterBody() throws JspTagException udqge?Tz  
aSnp/g  
{ CUmH,`hu  
+GNWF% zN  
BodyContent bc = getBodyContent(); $G?(OWI}l`  
%|Hp Bs#'  
//将body的内容以字符串的格式提取出来 ~\_T5/I%  
jD< pIHau  
String query = bc.getString(); H"YL k  
j64 4V|z  
//清除body <4?*$  
}~enEZ  
bc.clearBody(); %JoxYy-  
Xza4iV  
try{ w{7 ji}  
)@ PnTpL*  
Statement stmt = connection.createStatement(); m3 IP7h'  
!QC<n/  
Result result = stmt.executeQuery(query); eO4)|tW  
*=nO  
}catch(SQLException e){ j]> uZalr  
d?Y-;-|8Qh  
throw new JspTagException(“queryTag: “ + e.getMessage() ); B%b_/F]e  
fNhT;Bux  
return SKIP_BODY; c;V D}UD'  
/mbCP>bcG  
} 5j [#'3TSU  
Sb<\-O14"  
} _-a|VTM  
QPg2Y<2  
u(vw|nj`  
body-content元素 E[S':Q  
@W9H9 PWv&  
Gp1EJ2d8  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: m6so]xr  
)A83A<~  
<body-content>JSP|tagdependent</body-content> #MM &BC  
IRB& j%LA  
%-^}45](q  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 9/;{>RL=  
!kh{9I>M  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 $N\+,?  
M/w{&&  
BjD&> gO)  
用tags定义脚本变量 EzP#Mnz^  
bXl8v  
l P0k:  
tag处理类 -Cj_B\  
i:k-"  
>(tO QeN  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 o>u!CL<  
IA4+ad'\E  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 9v?V  
X% J%A-k]  
对象的生存周期(scope)如下表: 2v^lD('  
!GNXt4D  
对象的生存周期表 1o#vhk/ "+  
zz3 r<?#5  
名字 [:pl-_.C  
可访问范围 FW^.m?}|  
生存周期 n0FYfqH  
+ U5U.f%  
page +!$dO'0nt,  
当前页面 @zs1>\J7  
一直有效,除非页面向客户提交响应或重定向到一个新页面 `E;)`J8b  
2?1}ZXr  
request 22I Yrk  
当前页面或当前页面重定向到的页面 |uQ[W17^N  
一直有效,除非页面向客户提交响应 ^Jtl;Q  
sX~45u \  
session +E#PJ_H=F8  
当前页面或在同一浏览器窗口中的页面 z[biK|YL  
一直有效,除非关闭当前浏览器、超时、网络故障 nt`<y0ta  
|8;? *s`H  
application rIPl6,w~  
整个web应用程序的所有请求 `r.N  
一直有效,除非发生网络故障、服务器故障 ?d,M.o{0]  
5 ZUy:  
提供关于脚本变量的信息 >W~=]&7{s4  
J" wKRy  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: {e6 KJ@H6  
@YNGxg~*g  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> #fzw WP  
7<4xtK`+b  
<font color=”red” size=”+2” > [iXi\Ex  
/fC\K_<N  
<%= messages.getString(“CartRemoved”) %> MBv/  
LH.%\TMN$  
<strong><jsp:getProperty name=”book” property=”title” /></strong> i0i`k^bA  
w=$'Lt!  
</font> JP_kQ  
q-uLA&4  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: L`pY27 |  
UhA_1A'B  
· 脚本变量名称 ul$omKI$}  
.]zw*t*  
· 脚本变量所属的类 xx6S`R6:  
kpWzMd &RK  
· 此脚本变量是否引用了一个新的或已存在的对象 L B<UC?e  
wJ(8}eI  
· 此脚本变量的有效性 "_oLe;?$c  
.SBc5KX  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 jRwa0Px(  
` Rsl] GB  
Variable元素 'M lXnHxt  
r?]%d!   
Variable元素有如下子元素: #O><A&FrF`  
s%bUgO%&  
· name-given ?D?D 给出的名字,是一个常量 cyHhy_~R  
u:eW0Ows"  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 7>KQRLw  
[DL|Ht>  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: tUrNp~ve,  
?0m?7{  
· variable-class?D?D变量的类型,缺省为java.lang.String。 u<C $'V  
h/{8bC@bi  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 Bf+^O)Ns^  
<YSg~T  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: ,.q8Xf  
[Q=4P*G}X  
脚本变量的有效范围 m"q/,}DR  
}eI`Qg  
pbFYiu+  
有效性 e-jw^   
方法 " C&x ,Ic  
IF^[^^v+H  
NESTED dGa@<hg  
在tag标签的开始和结束之间 %/X2 l  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 }oV3EIH  
!b'IfDp[-!  
AT_BEGIN ^}tL nF  
从tag标签的开始一直到页面结束 wyNC|P;j$g  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 =}"R5  
"W3W:vl!  
AT_END 3 ^pYC K%  
从tag标签的结束一直到页面结束 :K: f^o]s  
在doEndTag中调用 jB`7T^bU  
.dt#2a_5q  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: d~3GV(M  
XS3{R   
<tag> V15q01bE#  
h^`{ .TlN  
<variable> s5nB(L*Pjp  
+fPNen4E  
<name-from-attribute>id</name-from-attribute> NuI T{3S  
 w}"!l G  
<variable-class>database.BookDetails</variable-class> |E? ,xWN  
x}_rnf_  
<declare>true</declare> .:T9pplq  
\?r$&K]4  
<scope>AT_BEGIN</scope> jm4)gmC  
sK#H4y+<  
</variable> hl*MUD,  
eS* *L 3  
</tag> ;r%<2(  
FF8WTuzB+  
额外tag信息类 "Jf4N  
 .fbYB,0w  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: l'W3=,G[?  
k:`a+LiZ  
· 变量名 ysL0hwir  
Ia=&.,xub  
· 变量所属类名 4 iik5  
gYRqqV  
· 此变量是否引用了一个新对象 MPqY?KF  
m9%yR"g9  
· 此变量的有效范围  {`tHJ|8  
vY4WQbz(  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 0 PR4g}"  
Q3(hK<Qh;  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: d$4WK)U  
bb*c+XN0  
}R4(B2vup  
public class DefineTei extends TagExtraInfo zwKg  
 ~WzMK  
{ (H'_KPK  
GOUY_&}tL  
public VariableInfo[] getVariableInfo(TagData data) =;kRk .qzy  
>3<&V{<K  
{ Dr4?Ow  
WW)_Wh  
String type = data.getAttributeString(“type”); 11PLH0  
[O.LUR;  
If( type == null) PY[S z=[  
/,=Wy"0TJ  
type = “java.lang.Object”; e!TG< (S  
=ltbSf7  
return new VariableInfo[] { TXA. 6e  
H't`Q&]a  
new VariableInfo(data.getAttributeString(“id”), ~3LhcU-  
c& 9+/JYMo  
type, [3Wsc`Q  
K!pxDW}  
true, ~vO'p  
ZJ;wRd@  
VariableInfo.AT_BEGIN) mvUVy1-c  
@hE7r-}]  
}; kxcgOjrmI  
E!:.G+SEl  
} #-l!`\@  
`HE>%=]b  
} jB}_Slh1j  
.%-6&%1  
Tb>IHoil  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: 8:;u v7p  
<tei-class> k#{lt-a/  
org.apache.struts.taglib.bean.DefineTagTei 9\\@I =;  
</tei-class> ~ nLkn#Z  
T2c_vY   
.Y=Z!Q  
具有协作关系的tag K8e4ax  
]L5Z=.z&  
AJJ%gxqGq  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 >FK)p   
yt]Oj*nn0K  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 Fm-q=3  
sDz)_;;%  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 r4]hS`X~%  
mtiO7w"M\7  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 ' lQ  
<z~2d  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 HYa$EE2  
RPa?Nv?e  
Z&?+&q r^  
public class QueryTag extends BodyTagSupport "<g?x`iz  
]%vGC^  
{ .j'@K+<45  
Z<$E.##  
private String connectionId; 8`R +y  
6KBzlj0T+  
public int doStartTag() throws JspException N,'[:{GOY  
r7]?g~zb  
{ mjkw&2  
3Vb=6-|  
String cid = getConnection(); Mp DdJ,  
< e7<t9  
if(cid != null) s$2l"|h>B  
LZZ:P  
{ y~4SKv $  
ebl)6C  
//存在一个connection id,使用它。 q.u[g0h;  
V PLCic,T  
connection = (Connection) pageContext.getAttribute(cid); b7>,-O  
[qjAq@@N#q  
} B6Wq/fl/  
 YiY&; )w  
else 2Be?5+  
JsWq._O{/  
{ W>t&N  
auyKLT3C  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, /: \VwH  
X*c_^g{  
ConnectionTag.class); #buV;!_!E?  
5;sQ@  
if(ancestorTag == null) Jm*M7g j  
{m*V/tX  
{ rhzv^t  
)$Dcrrj  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); N c&i) qh  
.5#tB*H  
} |R &3/bEr  
$jUS[.S_|I  
connection = ancestorTag.getConnection(); b0zxT9  
+UpMMh q  
} #sm_.?P  
Zh fD`@>&  
} ="'P=Xh!8  
fa*H cz  
} ,:dEEL+>c  
a2 klOX{  
qk+{S[2j  
HqnKpZ  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: F`ZIc7(.{  
#?b^B~ #  
zvK5Zxl  
<tt:connection id=”con01” ...> ... </tt:connection> 8KL_PwRX_f  
Wc`J`&#.#  
<tt:query id=”balances” connection=”con01” > 7gdU9c/q,  
KWn1%oGJ  
SELECT account, balance FROM acct_table H2FFw-xW  
DESViQM  
where customer_num = <%= request.getCustno() %> LGo@F;!n  
C^\*|=*\  
</tt:query> 5M\=+5wB  
A 4W  
!7"K>m<  
v ACsppa>#  
,GXfy9x7U  
<tt:connection ...> z kX-"}$8  
dbq{a  
<x:query id=”balances”> N|Cy!E=d  
#@\NdW\  
SELECT account, balance FROM acct_table U<,Kw6K  
,Q /nS$  
where customer_num = <%= request.getCustno() %> $b i_i|?  
D @4&@>  
</x:query> ~b6<uRnM.  
<@AsCiQF  
</tt:connection> ,w b|?>Y  
cf[u%{ 6Y  
QSs$   
与此同时,在TLD中必须指定connection属性为可选的,定义如下: a+>W  
+^&v5[$R  
<tag> T m@1q!G  
3}#XA+Z  
... b#I*~  
vo( j@+dz  
<attribute> ?lwQne8/  
moJT8tb  
<name>connection</name> y'2kV6TtqD  
64 \5v?C  
<required>false</required> :@@A  
1-NX>E5  
</attribute> D>7_P7]y  
l;Wy,?p  
</tag>
描述
快速回复

您目前还是游客,请 登录注册
如果您提交过一次失败了,可以用”恢复数据”来恢复帖子内容
认证码:
验证问题:
3+5=?,请输入中文答案:八 正确答案:八