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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! a7N!B'y  
|2{wG 4  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 ~ vqa7~}m  
ZXm/A0)S  
在这篇文章中,我们主要讨论: o=0]el^A  
M|:UwqV>  
· 什么是自定义tag标签? " Hd|7F'u=  
Qxj JN^Q  
· 怎么使用tag标签? 3}e%[AKh  
bV,}Pp+/"!  
o 声明要使用的tag库 8#vc(04(  
;G%R<Z  
o 找到与之对应的tag处理类 )"pF R4  
VkZ7#  
o tag标签的类型 @')[FEdW  
M![J2=  
· 自定义tag标签 5LOo8xN  
R?]02Q  
o tag处理类 K'GBMnjD  
wiiCd  
o tag库描述 R=jI?p  
AvW:<}a,  
o tag标签示例 qT+%;(  
.0es 3Rj  
o 带属性的tag NX}<*b/  
[sW3l:^  
o 带body的tag =zz ~kon9  
*6VF $/rP  
o 定义了脚本变量的tag D|{jR~J)xK  
w4gJoxY-`  
o 具有协作关系的tag /{&tY: ;m  
`E>1>'  
· 自定义tag标签 -PfX0y9n  
}"|K(hq  
o 一个迭代tag的例子 Q637N|01  
;XBI{CW  
o 一个模板tag库 yPal<c  
5rU[ T ir  
o tag处理类到底是怎样被调用的? va0{>Dc+  
H5Io{B%=  
rogT~G}q  
什么是自定义的tag? ye,>A.  
oaIi2=Tf  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 ++^l]8  
MB~=f[cUnd  
自定义tag标签有很多特色,诸如: 0E3[N:s  
fR(d  
· 可以在JSP页面中自定义tag标签的属性 md"!33 @  
*=V~YF:Qb  
· 访问JSP页面中的所有对象 =ACVE;L?  
f}9zgWU  
· 可以动态地修改页面输出 3`t%g[D1  
mj W8 Q\D  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 xe^Gs]fm  
J1C3&t}  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 8@MV%MVy$  
)-a'{W/t  
,F,X ,  
使用tag标签 +JjW_Rl?=V  
EK6:~  
z=q3Zo  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 qVH1}9_  
^ hZ0IM  
要使用tag标签,JSP程序员必须做2件事: E87Ww,z8  
n>BkTaI  
· 声明此tag标签的tag库 LG9+y  
--$ 4Q(#  
· 实现此tag标签 W3MJr&p  
x!5'`A!W%  
声明tag标签所在的tag库 r]:(Vk]|F  
DtXrWS/  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) |}=acc/  
I ?gSG*m  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> 5C o  
"_-Po^u=r  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 I|gB@|_~  
~*z% e*EL  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 bDL,S?@  
=P't(<  
以下taglib指示符直接引用一个TLD: ZX9TYN  
p<2L.\6"  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> E8$20Ue  
O}-jCW;K  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: +6HVhoxU#  
)dbB =OZ  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> l;R%= P?'F  
hYPl&^  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: ,(d) Qg  
 P5a4ze  
<taglib> n}F&1Z  
>s>1[W@*  
<taglib-uri>/tutorial-template</taglib-uri> %b&". mN  
v1o#1;  
<taglib-location> x$5) ^ud?  
]m g)Q:d,  
/WEB-INF/tutorial-template.tld LClNxm2X  
Q sZx) bO  
</taglib-location> >`Y.+4 mE  
#hfXZVD  
</taglib> zi|+HM  
@$S+Ne[<  
[#-b8Cu  
实现此tag标签 {MtpkUN  
|'P]GK  
ciBP7>'::  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 ")O%86_Q:  
Zn&, t &z  
2`7==?  
tag标签类型 6t>.[Y"v  
E7t+E)=8  
hL/)|N~  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): cii_U=   
7S '% E  
<tt:tag> zL$@`Eh-KP  
/Y9>8XSc  
body B:5Rr}eY+  
Lm*e5JnV  
</tt:tag> <;vbsksZeH  
JJP08 oP  
"$#xK|t  
一个不带body的tag标签如下: 'n{Nvt.c  
}YB*]<]  
<tt:tag /> ![`Ay4AZ@a  
$@z5kwx:P  
(!ZM{Js%  
简单的tag标签 ozmrw\_}[  
pXrFljoYl[  
一个没有body和属性的tag标签如下: Li!Vx1p;u.  
U &C!}  
<tt:simple /> n!YKz"$  
cc,^6[OH@  
DK$X2B"cV  
带属性的tag标签 &M46&^Jho  
>"|B9Woc  
CnpV:>V=  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 `b Fff %_  
BzkooJ  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: E)TN,@%  
^Y=\#-Dd  
<loglic:present parameter = “Clear”> i*|\KM?P  
!Fca~31R'  
而另一个标签logic:iterate是用表达式来给属性赋值: s %qF/70'  
tz5e"+Tz  
<logci:iterate collection=”<%= bookDB.getBooks() %>” d6'{rje(  
CLRiJ*U  
id=”book” type=”database.BookDetails”> :yRo3c  
xDG2ws=@D  
5"CZh.J  
带body的tag标签 p~SClaR3H  
U}6B*Xx'  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 b<a4'M  
?%O(mC]u&  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: + ,%&e  
4,sJE2"[9  
<logic:present parameter=”Clear”> s"0Y3x3  
!j:9`XD|  
<% cart.clear(); %> 9{(.Il J>  
M^O2\G#B  
<font color=”#ff0000” size=”+2”><strong> G~Hzec{#tg  
!B\R''J5  
你选择了清除购物车! 1M}5>V{  
d@ i}-;  
</strong></font> ,24p%KJ*X  
Hw7;;HK 7  
</logic:present> 7({]x*o*%  
'_GrD>P)-  
: ]sUpO  
到底是用属性还是用body来传递信息? [Grxw[(_:  
:K-~fA%kt?  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 !D@ZYK;  
S#MZV@nGF  
X#*JWQO=  
定义脚本变量的tag标签 55tKTpV  
&^#VN%{  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: ]b\yg2  
qHuZcht  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> ;LG#.~f  
%K>,xiD)  
<% tx.begin(); %> UaWl6 Y&Vu  
b\3Oyp>  
... j7jCm:  
'^No)n\`  
jF0jkj1&/[  
具有协作关系的tag标签 <J`0mVOX  
\9cG36  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 jzDuE{  
?\t#1"d  
<tt:tag1 attr1=”obj1” value1=”value” /> v*r7Zz6l  
oXb;w@:  
<tt:tag2 attr1=”obj1” /> "t (p&;d  
r[BVvX/,F  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 XZ sz/#  
^lA=* jY(  
<tt:outerTag> D)j(,vt  
9f hsIe  
<tt:innerTag /> {@+Ty]e  
w2 a1mU/  
</tt:outerTag> 2 lj'"nm  
y9x w 9l'  
*v9 2  
Tag处理类 LcUh;=r}&  
do*EKo  
~$)2s7 O  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 M}yDXJx  
Z Uox Mm  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 6^eV"&+@  
t .7?  
下表说明不同类型的tag所需要不同的处理过程: NWMFtT  
n?- })  
Tag处理类的方法 x4E7X_  
y+"X~7EX  
Tag标签类型 | #47O  
所调用的方法 /J=v]<87a  
-Z 4e.ay5  
基本标签 W3MU1gl6k{  
doStartTag, doEndTag, release M luVx'  
_#r+ !e  
带属性的标签 R)QC)U  
doStartTag, doEndTag, set/getAttribute1...N, release U<DZ:ds ?T  
G LIi6  
带内容的标签 yXHUJgjl/  
doStartTag, doEndTag, release 0:9.;x9_  
G/7cK\^u  
带内容的标签,且内容重复循环 uTKD 4yig  
doStartTag, doAfterBody, doEndTag, release `< xn8h9p  
2E}*v5b,  
带内容的标签,且内容与JSP交互 Zc W:6po>  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release z^#;~I @M  
4nh>'v%pD  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 C -\S/yd  
;c4 gv,q@  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 Y8-86 *zC  
FaDjLo2'o  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 nV-mPyfL8  
de p=&  
" @v <Bk  
Tag库描述(简称TLD) @d mV  
0w&27wW  
YoBPLS`K  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 L?WFm n  
g*03{l#P  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 P)Rh=U  
Y]/% t{Y  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: __|+w<]  
2O.i\cH  
<?xml version="1.0" encoding="ISO-8859-1" ?> 1~Oe=`{&  
/v- 6WSN  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> JM x>][xD  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: @?yX!_YC  
G9xmmc  
eZIhEOF  
<taglib>的子元素 * +"9%&?  
WtG~('g>&  
Element =cm~vDl[  
Description ]:4*L  
|wiqGzAr{  
tlib-version 8FKXSqhVM  
Tag库的版本 e4HA7=z  
$~VRza 8Q  
jsp-version A OISs4  
Tag库所需要的jsp的版本 fI{&#~f4C  
y\Ic@-aWI  
short-name }<@b=_>S  
助记符,tag的一个别名(可选) oSy yd  
+av@$}  
uri ++6`sMJ  
用于确定一个唯一的tag库 \m(VdE  
Z>)Bp /-  
display-name QPx_-  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) YH vLGc%  
tzZ`2pSh  
small-icon :S<f?* }:  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) xe{ !wX  
k5:G-BQ:  
large-icon =e9>FWf>  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) }001K  
[@J/eWB  
description =G7m)!  
对tag库的描述(可选) r^FhTzA=1  
}+.}J  
listener ABQ('#78  
参见下面listener元素 `o=q%$f#k~  
7 n8"/0kc:  
tag iII=;:p  
参见下面tag 元素 Fq |Ni$  
SxOC1+Oy  
Listener元素 ZCmgs4W!  
s/$?^qtyC  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 ii T"5`KY  
?[@J8  
Tag元素 w,#>G07D  
n^Hm;BiE#  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 &e @2  
a1EOJ^}0  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: B2>H_dmQ  
\.MR""@y`{  
Tag元素的子元素 0 ?s|i :  
PVe xa|aaX  
元素名称 gG0!C))8  
描述 1oR7iD^  
8aK)#tNWN  
name ^q{9  
独一无二的元素名 Q# ~Q=T'<  
[xSF6  
tag-class Of*Pw[vD  
Tag标签对应的tag处理类 .nrMfl_  
] eotc2?u  
tei-class SIBtmm1W  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) J\+0[~~  
cqQ#p2<%  
body-content |XQIfW]A  
Tag标签body的类型 O#ai)e_uQk  
SheM|I~de  
display-name n&$j0k  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) a zCf  
CDsSrKhx  
small-icon Z InpMp  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) %KsEB*' "  
*Fy2BZH%Q  
large-icon % Qmn-uZ  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) [4YTDEv%  
#eoome2Q  
description Oxm>c[R  
此tag标签的描述 sd*p/Q|4  
(/=f6^}  
variable i+A3~w5c  
提供脚本变量的信息(同tei-class)(可选) nEJq_  
<^VJy5>  
attribute f86XkECZ;`  
Tag标签的属性名 D9<!mH  
B^1>PE  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 6V$Avg\6\  
+9M^7/}H  
?:vv50  
简单的tag *w|:~g  
/NLui@|R  
$mu^G t  
tag处理类 t>L;kRujVJ  
51#_Vg  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 m,VOx7%n  
Dt}JG6S  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: ( Z619w  
ZT'`hK_up  
@Pm>sY}d<I  
public SimpleTag extends TagSupport T/b6f;t-s  
ap.K=-H  
{ ),0g~'I~D  
tRs [ YK  
public int doStartTag() throws JspException 8NxM4$nQX  
@ju@WY45$^  
{ Hkk/xNP  
6^V=?~a&z  
try{ ^|/TC!v]M  
S'k_olx7  
pageContext.getOut().print(“Hello.”); 4QH3fTv   
QqDC4+ p"  
}catch(Exception e){ .7Dtm<K#  
69PE9zz  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); @D.}\(  
S ^"y4- 2  
} 2V"B:X\  
]GMe \n  
return SKIP_BODY; 4-? C>  
wVX[)E\J  
} <->{  
a+[RS]le  
public int doEndTag() DH[p\Wy'  
SbND Y{5RO  
{ %D UH@j  
\MsTB|Z  
return EVAL_PAGE; {'N Z.  
(iBNZ7sJ  
} BHIRH mM<Y  
bZ?v-fn\D,  
} TCN8a/@z  
j:^#rFD4?  
ZXu>,Jy  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 18)'c?^.  
tnV/xk#!  
<body-content>empty</body-content> e{h<g>7  
m.JBOq=  
 Hu^1[#  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 jG6]A"pr  
ucuSe!IcX  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, 4qN{n#{+]  
K#l:wH _  
<logic:present parameter=”Clear”> a:+{f&  
\(~y?l  
与此相应,此tag处理类应有如下方法和定义: f"B3,6m  
R]Vt Y7}i,  
^aIPN5CK  
protected String parameter = null; n+! AnKq  
7WZrSC  
public String getParameter() E0BMv/r8b  
JBD7h5|Lc  
{ ylUrLQ\  
!*/*8re  
return this.parameter; Xk:OL,c  
c4!^nk]  
} l+ 3[ KCE  
Q0$8j-1I  
public void setParameter(String parameter) :fKl]XO  
+~St !QV%  
{ F^l[GdUosK  
MtM%{=&_  
this.parameter = parameter; iy6On,UL  
sD<a+Lw}x  
} 3yANv?$a  
C#QpQg2  
|o,YCzy|5  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 M])ZK  
qsL) }sC^8  
Attribute元素 ?8HHA: GP  
y@]_+2Vo  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 K7$x<5+)  
m%rd0=}57  
<attribute> 5&xB6|k  
5NBV[EP  
<name>attr1</name> R|JC1f8P5  
L%">iQOG#  
<required>true|false|yes|no</required> d^/3('H6  
fz;iOjr>  
<rtexprvalue>true|false|yes|no</rtexprvalue> :#2Bw]z&z  
-\+s#kE:  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> U2$d%8G  
AUeu1(  
</attribute> r[1i*b$  
L9-h;] x!  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 2*rH?dz8E  
PEc,l>u9  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 3WN`y8l  
z25lZI" X`  
<tag> $ oTdfb  
jNu9KlN  
<name>present</name> #btLa\HJ  
EJ@?h(O  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> U0=]  
 rL/H2[d  
<body-content>JSP</body-content> `(T,+T4C5k  
Z.d 7U~_  
tc_286'x  
r`%+M7  
<attribute>  zG+R5:  
&lR 6sb\  
<name>parameter</name> U QE qX  
*Kyw^DI  
<required>false</required> Rfn9s(m  
?/TSi0R  
<rtexprvalue>true</rtexprvalue> 6cpw~  
u83J@nDQ  
</attribute> HfcL%b%G8  
MzPzqm<  
AGH|"EWG  
g wz7krUTe  
</tag> ]"+95*B  
?in|qevL  
&P.4(1sC  
属性元素的校验 v4?x.I  
{)DHH:n  
Wf>zDW^"R  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 > *@y8u*  
 XEC(P  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 BQBeo&n6  
9 Yx]=n  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 c<uN"/gi*  
RbCPmiZcH  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: df*5,NV'-*  
Z?pnj8h-&  
<attribute> qud\K+  
<F'X<Bau  
<name>attr1</name> .P.z B}0=  
#Pw2Q  
<required>true</required> !h(|\" }  
\|]Z8t7  
<rtexprvalue>true</rtexprvalue> ]V-W~r=  
HQ|MhM/"  
</attribute> xBUya4w  
Qd=^S^}(  
%ThyOl@O  
这个定义说明了attr1能在运行期间被赋值。 0ge$ p,  
BJgW,huLy  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 ZeUvyIG  
$B kubWM  
:[\v  
Public class TwaTEI extends TagExtraInfo O$D'.t  
@S|jC2^+h  
{ Rop'e8Q  
u\LiSGePN  
public boolean isValid(Tagdata data) Q?8R[i  
&=<x#h-  
{ nt;haeJ  
5nTY ?<x`k  
Object o = data.getAttribute(“attr1”); w^Lta  
rEHkw '  
If(o != null && o != TagData.REQUEST_TIME_VALUE) !FA# K8  
u$*56y   
{ @[#$J0q q  
BBH0OiV=  
if( ( (String)o).toLowerCase().equals(“true”) || AX?fuDLs  
T<JwD[ (  
((String)o).toLowerCase().equals(“false”) ) ( {1e%  
4J;-Dq  
return true; P&j (,7  
hX`hs- *qM  
else c1$ngH0  
~/8M 3k/  
return false; |+35y_i6  
+Vo}F  
} @HRC \OG  
Ma'_e=+A  
else XYS'.6k(  
Mva3+T  
return true; fLSXPvm  
j [rB"N`0  
} {%VV\qaC  
-zp0S*iP7  
} f6_];]yP  
^qg?6S4  
!/^-;o7  
带body的tag %V1Z~HC  
 ] GHt"  
:Xn7Ha[f  
tag处理类 GK9/D|h4  
Nru7(ag1~  
d~/q"r1"  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 3m>+-})d  
UK$ms~H  
Tag处理类不与body交互 %/c+`Wd/l$  
6*qL[m.F[o  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 kloR#?8A  
 U3izvM  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 rQOWLg!"  
\S*$UE]uG  
Tag处理类与body交互  |y h\  
4-kZJ\]  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 oT{@_U{*J  
~`GhS<D  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 /^$UhX9v  
BnCKSg7V  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 "F3]X)}  
c9\2YKo  
doInitBody 方法 OdQT2PA_  
J0 k  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 7R3fqU.Rq  
n4R2^gXAw  
doAfterBody方法 B d^"=+c4  
'S<%Xm  
此方法在body内容已被计算后进行调用。 7_wJpTz  
Tzt,/e  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 Wxk x,q?  
 Og2vGzD  
release 方法 iJv48#'ii  
c{>uqPTY  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 SR^_cpZoi  
7QVuc!V  
V $|<  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 ' JdkUhq1V  
j}F-Xs+  
ewuXpv%vwW  
Public class QueryTag extends BodyTagSupport R*zO dxY  
q8Nn%o=5V  
{ >tG+?Y'{  
FG%j {_Ez  
public int doAfterBody() throws JspTagException -ZW3  
li] 6Pj,  
{ dI*'!wK  
~gI{\iNF/  
BodyContent bc = getBodyContent(); Kzb`$CGK  
jJ3zF3Id  
//将body的内容以字符串的格式提取出来 6*nAo8gl  
Z,c,G2D  
String query = bc.getString(); <w>/^|]#  
1/ZR*f a  
//清除body {ub/3Uh  
Cs@ +r  
bc.clearBody(); sM\lO  
8ga_pNe  
try{ V8-h%|$p3W  
NQ|xM"MqD  
Statement stmt = connection.createStatement(); 6  P`)%zj  
VW@ x=m  
Result result = stmt.executeQuery(query); w %c  
"PH6e bm  
}catch(SQLException e){ ciMM^ZRIb  
8BXqZVm.  
throw new JspTagException(“queryTag: “ + e.getMessage() ); Qn:kz*:  
 T7$S_  
return SKIP_BODY; | A:@ &|  
y69J%/c ra  
} Y\+KoR' ;  
:XV} c(+d  
} Rt(J/%;  
O'NW Ebl/  
-Dzsa  
body-content元素 H]31l~@]  
n&-496H  
/.V0ag'G  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: zz_[S{v!#  
9.M{M06;  
<body-content>JSP|tagdependent</body-content> 8 Op.eYe  
h4fLl3%H  
WW "i  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 DFe;4BdC  
Omag)U)IPh  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 )%Y IGV;&  
y/_wx(2  
MZ#T^Y  
用tags定义脚本变量 V*65b(q)  
rUwE?Ekn/  
N dR ]  
tag处理类 Mth6-^g5  
L>Jd7; =  
=qoRS0Qa  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 ,#'7)M D8  
^[-> )  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 ua 8m;>R  
mog9jw  
对象的生存周期(scope)如下表: +nZRi3yu=  
xRDiRj  
对象的生存周期表 :kw0y  
$W!]fcZlB  
名字 -!*p*3|03|  
可访问范围 ;R[&pDx  
生存周期 9 Aivf+  
Ly (P=M>"y  
page %!.M~5mCd  
当前页面 :%_q[}e  
一直有效,除非页面向客户提交响应或重定向到一个新页面 ValS8V*N1  
bY#;E;'7  
request RfbdBsL  
当前页面或当前页面重定向到的页面 x3p9GAd#  
一直有效,除非页面向客户提交响应 TGWdyIk  
PM~*|(fA  
session hWGZd~L  
当前页面或在同一浏览器窗口中的页面 c%<2z  
一直有效,除非关闭当前浏览器、超时、网络故障 zS% m_,t  
G8NRj9k?  
application e)pTC97^L  
整个web应用程序的所有请求 LZ&uj{ <  
一直有效,除非发生网络故障、服务器故障 jmW^`%;7  
[V< 1_zqt  
提供关于脚本变量的信息 SWoEt1w  
]Ti$ztJ  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: &d 3HB=x  
\j:gr>4  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> Hptq,~_t  
/"0as_L<  
<font color=”red” size=”+2” > P06 . 1  
Ve:&'~F2 s  
<%= messages.getString(“CartRemoved”) %> >Pkdu}xP3  
E*4t8  
<strong><jsp:getProperty name=”book” property=”title” /></strong> 75(W(V(q  
lS{4dvr?w  
</font> }=pOiILvD  
BD1K H;  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: 3Wj,}  
M'|)dM|  
· 脚本变量名称 XIN5a~[z*  
FH -p!4+]  
· 脚本变量所属的类 8on[%Vk  
M7U:g}  
· 此脚本变量是否引用了一个新的或已存在的对象 )_pt*xo  
j&llrN  
· 此脚本变量的有效性 (1y='L2rj  
ho|  8U  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 Q2R-z^pd  
1HXlHic  
Variable元素 0Q*-g}wXfS  
Cji#?!Ra?  
Variable元素有如下子元素: 3#<'[TF00t  
<"NyC?b+G  
· name-given ?D?D 给出的名字,是一个常量 D3]@i&^B  
toN  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 p9w%kM?  
1bDJ}M~]z  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: %d-`71|lG^  
Ix4jof6(  
· variable-class?D?D变量的类型,缺省为java.lang.String。 2:/u2K  
#_,uE9  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 E.4n}s  
IPkA7VhFF  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: 8q{1E];:q  
[M<{P5q  
脚本变量的有效范围 H&u4v2  
S].Ft/+H  
1 O- E],  
有效性 AAdD\ %JZ  
方法 +Gp!cGaAm  
"?`JA7~g  
NESTED 0~:e SWz=  
在tag标签的开始和结束之间 y 2cL2c$BT  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 s|BX> 1  
]zy~@,\  
AT_BEGIN a5>)?m  
从tag标签的开始一直到页面结束 )fy <P;g  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 Y+OYoI  
w64.R4e  
AT_END T&mbXMN  
从tag标签的结束一直到页面结束 q!9^#c  
在doEndTag中调用 *EX$v4BX  
)Xq@v']%~9  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: e2q pJ4i  
91U^o8y  
<tag> Vx}Yl&*D  
D8q3TyCj%  
<variable> .Kg|f~InO  
y4 dp1<t%  
<name-from-attribute>id</name-from-attribute> -??!@R7V  
L,yA<yrC  
<variable-class>database.BookDetails</variable-class> HDa~7wE  
#: dR^zr<  
<declare>true</declare> .A )\F",X  
%_]=i@Y~  
<scope>AT_BEGIN</scope> QQ5lW  
e~tr^$/(  
</variable> v&k>0lV, ^  
FGV}5L  
</tag> E~rs11  
D)f5pEq'  
额外tag信息类 *4r s  
L`<T'3G  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: r'Hy}HWuF  
Q x9>,e6+  
· 变量名 ._8xY$l$  
=}B4I  
· 变量所属类名  5xG|35Pj  
Gr`MGQ,  
· 此变量是否引用了一个新对象 ({D}QEP  
MLkL.1eGSb  
· 此变量的有效范围 e6tH/`Uln  
stf,<W  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 ^4y(pcD  
V%X:1 8j  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: |V5$'/Y  
m1~qaD<DZ$  
owfp^hla  
public class DefineTei extends TagExtraInfo yYxeNE"  
Yio>ft&g]  
{ cq'}2pob  
VEFwqB1l  
public VariableInfo[] getVariableInfo(TagData data) o 2[vM$]  
o<C]+Nt,@  
{ 1qB!RIau  
$V`KrA~]  
String type = data.getAttributeString(“type”); -13P 2<i+  
VJ~X#Q  
If( type == null) _IQU<Za  
s=\LewF1<  
type = “java.lang.Object”; b0~H>cnA  
$UFge%`,q@  
return new VariableInfo[] { BR&Qw'O%  
= )JVT$]w  
new VariableInfo(data.getAttributeString(“id”), >|UrxJ7  
}[=xe(4]D  
type, FqT,4SIR  
. Ce&9l  
true, 4Vb}i[</  
cuV8#: i  
VariableInfo.AT_BEGIN) lRa 3v Ng  
XEvGhy#  
}; Ef,7zKG  
uFm(R/V  
} t?du+:  
.pB8=_e:  
} 8osS OOzM  
]<\;d B  
n,Yr!W:h  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: pr[B$X .V  
<tei-class> oPBg+Bh*  
org.apache.struts.taglib.bean.DefineTagTei lJGqR0:r+  
</tei-class> Th& Wq  
(^s&M  
9rpg10/T  
具有协作关系的tag y'0dl "Dy\  
#TW>'l F  
-A-hxK*^  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 8XS {6<  
%X0NHta ~@  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 H/p-YtY  
Z3abem<Q  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 =jV%O$Fx  
]Jq k C4|  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 7q2"b?|h  
#2lvfR|  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 ]9KQP-p'  
qUDz(bFk/  
8}pcanPg  
public class QueryTag extends BodyTagSupport qUoMg%Z%l  
LrM.wr zI/  
{ ~J. Fl[  
z|DA _dG  
private String connectionId; QNa}M{5>h  
/_VRO9R\V  
public int doStartTag() throws JspException HgSmAziv  
g~^{-6Vg  
{ eUKl Co  
m`yn9(1Y[  
String cid = getConnection(); M::IE|h  
QS=$#Gp  
if(cid != null) C tC`:!Q  
O"J.k&C<,  
{ !OZh fMVd  
49J+&G?)j  
//存在一个connection id,使用它。 ![P(B0Ct/  
OJ_2z|f<  
connection = (Connection) pageContext.getAttribute(cid); CI~;B  
$R$c1C'oX  
} "{ QHWZ  
uVuToMCp  
else lPFdQ8M  
A_(+r  
{ [P&,}o)+E0  
Er/5 ,  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, gh #w%g1g  
}DUDA%U  
ConnectionTag.class); pv m'pu78  
5KH'|z  
if(ancestorTag == null) 0h@%q;g  
18/@:u{  
{ Y"/UYxCm|&  
$m: a-.I  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); Kf?{GNE7  
6 pn@`UK  
} rIFC#Jd/  
^< /vbF  
connection = ancestorTag.getConnection(); $W_o$'crW  
9hs{uxwuEE  
} ZesD(  
2-E71-J  
} qVRO"/R  
-R$FJb Id  
} !Ub?eJp  
S7~F*CGBh  
rDx],O _  
TnU$L3k  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: tEX~72v  
zkMO3w>  
&?g!}Ky \  
<tt:connection id=”con01” ...> ... </tt:connection> ] xLb )Z  
i+x6aQ24  
<tt:query id=”balances” connection=”con01” > +@)$l+kk9  
n#4J]Z@  
SELECT account, balance FROM acct_table 7n 95>as  
6-X?uaY)os  
where customer_num = <%= request.getCustno() %> E)_!Hi0<s  
yoY)6cn@  
</tt:query> }NBJ T4R  
Jx9%8Ek  
Y 6Qb_X:  
3N%Ev o  
^%X\ }><  
<tt:connection ...> VaI P  
,M h/3DPgE  
<x:query id=”balances”> GK+\-U)v  
pH:|G  
SELECT account, balance FROM acct_table _>m*`:Wb  
,0~ {nQj]  
where customer_num = <%= request.getCustno() %> wG?kcfu  
}7 z+  
</x:query> kJeOlO[  
Xsn- +e  
</tt:connection> ;F(01  
x15tQb+  
wXZY5-h4  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: ?~Ed n-" Y  
Q0; gF?  
<tag> j6HbJ#]  
H.[&gm}p>  
... t RyGxqiG  
zPkPC}f(O  
<attribute> o4f9EJY   
x,c68Q)g  
<name>connection</name> ~S>ba']  
RTY4%6]O  
<required>false</required> W!B4< 'Fjc  
v 4b`19}  
</attribute> r8?Lr-;  
~JPzjE  
</tag>
描述
快速回复

您目前还是游客,请 登录注册
批量上传需要先选择文件,再选择上传
认证码:
验证问题:
10+5=?,请输入中文答案:十五