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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! NDw+bR-  
HT]v S}s  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 M*DFtp<  
xwjim7# _:  
在这篇文章中,我们主要讨论: k,EI+lCX  
}pE8G#O&  
· 什么是自定义tag标签? - nWs@\  
)V!9/d  
· 怎么使用tag标签? CaX0Jlk*  
%5N;SRtv  
o 声明要使用的tag库 Rw]4/  
Cd4a7<-  
o 找到与之对应的tag处理类 z*Y4t?+  
.g CC$  
o tag标签的类型 nI1DLVt  
CYr2~0<g  
· 自定义tag标签 =)56]ki}  
~~U2Sr  
o tag处理类 s\c*ibxM,  
U Ox$Xwp5&  
o tag库描述 -1tdyCez  
ya81z4?  
o tag标签示例 9Fe(],AzF  
=1dU~B:Lm  
o 带属性的tag "W_C%elg  
5lp L$  
o 带body的tag e=11EmN9  
/Q7cQ2[EU  
o 定义了脚本变量的tag O|#N$a&_N  
pRsYA7Ti  
o 具有协作关系的tag #!Iez vWf  
n@LR?  
· 自定义tag标签  `O-LM e  
tK<GU.+  
o 一个迭代tag的例子 t 6.hg3Y  
\]y4e^FZZ  
o 一个模板tag库 Evz;eobW/  
4<S*gu*W  
o tag处理类到底是怎样被调用的? '4PAH2&n  
'qTMY*  
fvajNP  
什么是自定义的tag? Oeo:V"  
)"  H$1  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 A>"v1Wk  
U D9&k^  
自定义tag标签有很多特色,诸如: 0phO1h]2S)  
P# o/S4  
· 可以在JSP页面中自定义tag标签的属性 )7mX]@  
o C]tEXJ  
· 访问JSP页面中的所有对象 {~*aXu 3  
[\o+I:,}wi  
· 可以动态地修改页面输出 1'5I]D ec  
{}?;|&_  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 o0-7#2  
&a?&G'?  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 {;(X#vK}9  
tuA,t  
{~g(WxE  
使用tag标签 d*26;5~\  
Az.k6)~  
G Q&9b_  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 0NLoqq  
bl|k6{A  
要使用tag标签,JSP程序员必须做2件事: dhe?7r ]u  
QN[-XQ>Xt  
· 声明此tag标签的tag库 _m!TUT8o  
W~GbB:-  
· 实现此tag标签 :$&%Pxm  
||y5XXs  
声明tag标签所在的tag库 t&UPU&tY  
*uR&d;vg.8  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) OE(H:^ZR  
E3gR%t  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> !1f8~"Z  
iw6qNV:\Z  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 }$W4aG*[  
xq:.|{HUk  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 DpIv <m]  
>;',U<Wd  
以下taglib指示符直接引用一个TLD: =z'w-ARy  
r}OK3J  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> v}hmI']yf  
37 )Dx  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: #n^P[Zw  
.s 31D%N  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> SCk2D!u  
>=hO jV;  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: q/xMM `{  
@Md%gEh;&  
<taglib> >:M3!6H_~{  
-;_`>OU{  
<taglib-uri>/tutorial-template</taglib-uri> G#/}_P  
#Ag-?k  
<taglib-location> &?^S`V8R*  
jw$3cwddH  
/WEB-INF/tutorial-template.tld EWPP&(u3  
kVs'>H@FY  
</taglib-location> >{i/LC^S  
b:.aZ7+4  
</taglib> A87JPX#R?  
n(.y_NEgV!  
I0 a,mO;m  
实现此tag标签 bs!N~,6h  
0es[!  
u2 a U0k:  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 *6~ODiB  
FjIS:9^)t5  
5Qhu5~,K  
tag标签类型 c 6sGjZdR  
#|fa/kb~  
|R:gu\gG  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): 0!F"s>(H  
|ofegO}W7  
<tt:tag> v4!zB9d  
hK9Trrwau  
body e{8z1t20:  
0 Vv 6B2<  
</tt:tag> J& }/Xw)  
kH1hsDe|&y  
mD-qJ6AM  
一个不带body的tag标签如下: 6V\YYrUz  
R0y={\*B5k  
<tt:tag /> `m?%{ \  
IbC(/i#%`  
Ed,`1+  
简单的tag标签 :G9+-z{Y&  
SCE5|3j  
一个没有body和属性的tag标签如下: H];|<G  
!s#25}9zX5  
<tt:simple /> tWQ_.,ld  
8RWfv}:X  
6H67$?jMyJ  
带属性的tag标签 LY2oBX@fC  
%o9@[o .]  
j?%^N\9  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 0ZPwEP  
C J S  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: /%|JP{   
Ql a'vcT  
<loglic:present parameter = “Clear”> QlJ cj+_h  
E%OY7zf`%  
而另一个标签logic:iterate是用表达式来给属性赋值: 0F-X.Dq  
qLBXyQ;U  
<logci:iterate collection=”<%= bookDB.getBooks() %>” NR-d|`P;  
y0cHs|8  
id=”book” type=”database.BookDetails”> *JE%bQ2Q  
@#K19\dQ  
24PEt%2  
带body的tag标签 3^ ~M7=k  
km2('t7?  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 D].!u{##  
v.:aICB5  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: ;]zV ?9  
Nq1la8oQ3  
<logic:present parameter=”Clear”> G%w.Z< qy  
tAFKq>\  
<% cart.clear(); %> Gm;)Om_  
'_,/N!-V  
<font color=”#ff0000” size=”+2”><strong> T%~w~stW  
Y-\hV6v6  
你选择了清除购物车! C( 8i0(1  
~>&7~N8  
</strong></font> O6Bs!0,  
~Q"3#4l  
</logic:present> E8gXa-hv  
nmZz`P9g  
yQE|FbiA  
到底是用属性还是用body来传递信息? j78WPG  
8uq^Q4SU  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 AE`X4q  
2^w3xL"   
b"n8~Vd  
定义脚本变量的tag标签 K}"xZy Tm1  
,T@+QXh  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: &5puGnTZ  
%jz]s4u$5j  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> 0+MNu8t  
k#Qav1_  
<% tx.begin(); %> >QO^h<.>  
$U%M]_  
... }U3+xl6g  
C(zgBk  
3/c3e{,!  
具有协作关系的tag标签 C'&)""3d  
)!.ef6|  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 lM1~ K  
mM&Sq;JJ;  
<tt:tag1 attr1=”obj1” value1=”value” /> m;-FP 2~  
gY\X?  
<tt:tag2 attr1=”obj1” /> Z`x|\jI  
j8n_:;i*  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 0WT]fY?IS  
j6v|D>I  
<tt:outerTag> 8* 7t1$  
R<. <wQ4I  
<tt:innerTag /> VP0q?lh  
`roos<F1D  
</tt:outerTag> 0VsQ$4'V^  
o V"d%ks  
p3>(ZWPNV  
Tag处理类 *69{#qN  
AsFn%8_I  
kQ~2mU  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 ?;84 M@  
1o"/5T:S[  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 ql"&E{u?  
Zoe>Ow8mE`  
下表说明不同类型的tag所需要不同的处理过程: c%1k'Q  
N(i%Oxp1  
Tag处理类的方法 p3tu_If  
sF9{(Us  
Tag标签类型 W0e+yIaR  
所调用的方法 %smQ`u|  
(Z:(f~;  
基本标签 :5)Dn87  
doStartTag, doEndTag, release k=;>*:D%  
>,c$e' h  
带属性的标签 dRw O t  
doStartTag, doEndTag, set/getAttribute1...N, release ZEY="pf  
-& Qm"-?:  
带内容的标签 7$3R}=Z`\q  
doStartTag, doEndTag, release i%BrnjX  
,TeJx+z^  
带内容的标签,且内容重复循环 $t*>A+J  
doStartTag, doAfterBody, doEndTag, release 6,C2PR_+  
m]H[$ Q  
带内容的标签,且内容与JSP交互 L8OW@)|  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release (Hk4~v6pqC  
bVfFhfh*  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 V11(EZJ/j  
nW)-bAV<  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 &UzeNL"]  
hxG=g6:G  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 /|7@rH([{  
BR&T,x/d  
^RL#(O  
Tag库描述(简称TLD) ~K'e}<-G  
w+A:]SU  
pypW  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 k+-IuO  
2MT_5j5[N  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 FHztF$Z  
t "y[  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: ~nit~ ;  
Yz<,`w5/6~  
<?xml version="1.0" encoding="ISO-8859-1" ?> 3[q&%Z.  
Q?"o.T';  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> )"( ojh  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: |gXtP-  
E`E$ }iLs  
s |40v@ M  
<taglib>的子元素 kg,t[Jl  
P9d%80(b4  
Element m/{HZKh  
Description 6d4e~F  
|E{tS,{OhJ  
tlib-version 1 zo0/<dk  
Tag库的版本 ^O>G?a  
kXj rc  
jsp-version 4Cd#S9<ed  
Tag库所需要的jsp的版本 euxkw]`h6  
$? 'JePC  
short-name %62W[Oh5  
助记符,tag的一个别名(可选) Oup5LH!sW  
"h@|XI  
uri .`I;qF  
用于确定一个唯一的tag库 fj 14'T  
A/bxxB7w  
display-name 3o).8b_3g  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) ioIOyj  
M<Gr~RKmAn  
small-icon b*;zdGX.A9  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) 8}B*a;d  
0LX"<~3j  
large-icon f+ }Rj0A  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) !@6P>HzY$  
/ 7i>0J]  
description $ 12mS  
对tag库的描述(可选) Z.Otci>J  
<5 Ye')+  
listener j|6@>T1  
参见下面listener元素 m=s aUhI*9  
q5Bj0r[/o  
tag MU  }<-1  
参见下面tag 元素 {|R@\G.1(  
~RdD6V  
Listener元素 SH oov  
N}$$<i2o  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 tEU}?k+:j)  
\hlQu{q.  
Tag元素 Gky e  
3CKd[=-Z  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 Ffv v8x  
*\-R&8  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: ( M > C  
dkHye>  
Tag元素的子元素 2#srecIz-!  
.o27uB.  
元素名称 :Dh\  
描述 #!A'6SgbkM  
f *Xum[  
name  0 |/:m  
独一无二的元素名 z%4E~u10  
]JQ+*ZYUE  
tag-class )td?t.4  
Tag标签对应的tag处理类 N5ph70#y3  
)aV\=a |A  
tei-class F!>92H~3G  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) .C 6wsmQ  
I.4o9Z[?  
body-content iY|zv|;]=  
Tag标签body的类型 LTn@OhC  
G{ |0}  
display-name CMcS4X9/}  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) ?g ~w6|U(r  
?Aq \Gr  
small-icon P"Scs$NOU?  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) &Zzd6[G+  
&J]|pf3m  
large-icon a/ 4!zT   
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) vU4Gw4  
\zdY$3z  
description 35;UE2d)<  
此tag标签的描述 ~BUzyc%  
@Sik~Mm_h  
variable D2,2Yy5 y  
提供脚本变量的信息(同tei-class)(可选) JU6PBY~C'  
)=k8W9i8b  
attribute kVqRl%/3Tb  
Tag标签的属性名 -T,/S^  
I^u$H&  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 ~ z< &vQ=  
*X_-8 ^~  
4s:S_Dw  
简单的tag h/LlH9S:!  
9<" .1  
&7fwYV  
tag处理类 z PW[GkD  
<n+]\a97*  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 #NvL@bH  
F2N)|C<  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: #1-2)ZO.  
T?DX|?2X  
Yn~N;VUA  
public SimpleTag extends TagSupport CnXl 7"  
zXEu3h  
{ ~xp(k  
eG @0:  
public int doStartTag() throws JspException rUz-\H(-  
(V06cb*42[  
{ hoLQuh%2%  
#A:+|{H"  
try{ !5wuBJ0  
|riP*b  
pageContext.getOut().print(“Hello.”); cn3F3@_"\  
0afDqvrC6  
}catch(Exception e){ as k76  e  
<*Ex6/j  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); ./KXElvQ%  
DHnO ,"  
} b3vPGR  
2_i9 q>I  
return SKIP_BODY; 6Hh\ys  
9>OPaL n  
} O'WB O"  
H}p5qW.tH:  
public int doEndTag() &Q>tV+*  
3= q,k<=L  
{ 5;alq]m7  
fPA5]a9  
return EVAL_PAGE; C&1()U  
^z^zsNx  
} -".q=$f  
h,!#YG@>  
} k%gO  
8NUVHcB6  
z2 m(<zb  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 J}{a&3@Hm  
2C &G' @>  
<body-content>empty</body-content> Nr(t5TP^  
CD"D^\z  
w y\0o  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 *%#Sa~iPo  
ox&PFI0Gn  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, ?r}'0dW  
ER'zjI>t@  
<logic:present parameter=”Clear”> F3Y/Miw  
dU"ca|u  
与此相应,此tag处理类应有如下方法和定义: <8,,pOb  
$.0l% $7  
S!r,p};  
protected String parameter = null; 4]P5k6 nV  
VHbQLJ0  
public String getParameter() 'Y;M%  
|Vj@;+/j  
{ >69-[#P!  
V0 O6\)/.  
return this.parameter; %%c1@2G<  
%0MvCm  
} I%Yeq"5RB  
m,X8Cy|vQ  
public void setParameter(String parameter) IBn+4 2V  
AW')*{/(Ii  
{ Mcfqo0T-  
=uil3:,[S  
this.parameter = parameter; 4b/>ZHFOF;  
vWh]1G#'p[  
} "+{>"_KV  
,ej89  
a^5.gfzA  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 t8:QK9|1  
{n'+P3\T:  
Attribute元素 9[@K4&  
sWKe5@-o0  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 HVLj(_ A  
AS-%I+ A  
<attribute> <u Kd)l  
O>tz;RU  
<name>attr1</name> S@^o=B]]  
D9 \!97  
<required>true|false|yes|no</required> CEXD0+\q  
N, SbJ Z  
<rtexprvalue>true|false|yes|no</rtexprvalue> 7mT iO?/y<  
vLT$oiN[c  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> (aUdPo8H^  
6!T9VL\=H  
</attribute> H)rE-7(f!  
A}l+BIt  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 |1/UC"f  
SF. Is=b  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 ZT d)4f  
3I.0jA#T&/  
<tag> G}V5PEF]`  
L}hc|(:  
<name>present</name> >X58 zlxk  
NfsF'v  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> @ i*It Hk  
?qJt4Om  
<body-content>JSP</body-content> , #nYHD  
jnzOTS   
J-U5_>S  
!l|fzS8g  
<attribute> {W11+L{8  
A8T75?lL(  
<name>parameter</name> #O,;3S  
 SCq:jI  
<required>false</required> /3KPK4!m  
S(ky:  
<rtexprvalue>true</rtexprvalue> Gv\:Agi  
Yj{-|2YzL  
</attribute> HE{JiAf  
{7Qj+e^  
H/''lI{k)  
- U Elu4n&  
</tag> Hpj7EaMZ_  
6^VPRp  
k%Wj+\93 f  
属性元素的校验 C;\R 62'  
_)XZ;Q  
8k_cC$*Ng  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 DcRvZH  
EGw;IFj)  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 S3N+ 9*i K  
e.Gjp {  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 YwU[kr-i  
TMw6 EM  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: 4d63+iM+}  
W!o|0u!D  
<attribute> 1%$Z%?  
PR3&LI;B*  
<name>attr1</name> t b>At*tO  
4o3TW#  
<required>true</required> mkuK$Mj  
yN{TcX  
<rtexprvalue>true</rtexprvalue> 7fXta|eP0  
=Q~@dP  
</attribute> 36MNaQt'e  
,(;]8G-Yj  
.r~M7 I  
这个定义说明了attr1能在运行期间被赋值。 Px?zih!6  
$nqVE{ksV  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 ni?5h5-  
sH51 .JG  
c|s7 cG$+-  
Public class TwaTEI extends TagExtraInfo Y6RbRcJw  
[79iC$8B|  
{ ,B1~6y\b  
&cZl2ynPi  
public boolean isValid(Tagdata data) HlOn=>)<  
nduUuCIY.  
{ @iBaJ"*,  
>Vph_98|  
Object o = data.getAttribute(“attr1”); XsGc!  o  
\rM5@ Vf  
If(o != null && o != TagData.REQUEST_TIME_VALUE) $ww0$  
61Wh %8-  
{ w Y=k$  
s<{) X$  
if( ( (String)o).toLowerCase().equals(“true”) || 9>r@wK'Pn  
~cul;bb#  
((String)o).toLowerCase().equals(“false”) ) g4^3H3Pd  
Jd28/X5&  
return true; Zg$RiQ^-{J  
0]xp"xOwW  
else Xbu P_U'  
Ejj+%)n.  
return false; Z '~Ie~  
G=PX'dS  
} 9`tSg!YOh  
heScIe N^`  
else [Om,Q<  
e=`=7H4P  
return true; 7O,!67+^~  
6z2%/P-'  
} yJW/yt.l  
d' l|oeS  
} $]gflAe2  
|4rqj 1*U  
,</Kn~b  
带body的tag HcM/  
RT<HiVr`  
0i(c XB  
tag处理类 yof8LWXx  
2  ZyO  
*uoO#4g~  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 nd }Z[)  
M9~6ry-_  
Tag处理类不与body交互 ]]P@*4!  
3F32 /_`  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 :,V&P_  
6w~Cyu4Ov  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 Muyi2F)j  
KNjU!Z/4  
Tag处理类与body交互 W5>emx'>  
> D%  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 3_"tds <L  
m qwJya  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 Vwb_$Yi+]  
CU:HTz=  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 <R?S  
#gVWLm<  
doInitBody 方法 7^C&2k 5G  
Dt\rrN:v  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 gv){&=9/  
{E0\mZ2  
doAfterBody方法 }Fsr"RER@{  
5\}E4y  
此方法在body内容已被计算后进行调用。 Tj+U:#!!~  
*T~b ox  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 &ET$ca`j#  
7^syu;DT9Y  
release 方法 H5*#=It  
k *D8IB  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 )iid9K<HB  
Bj GfUQ  
5fRrd;  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 A4(k<<xjE  
l,Fn_zO  
\BX9Wn*)a  
Public class QueryTag extends BodyTagSupport 7A h   
)Y6\"-M[  
{ hkdF  
8tVSai8[  
public int doAfterBody() throws JspTagException ~n! & ~  
Qq'e#nI@  
{ 1OV] W f  
6s'n r7'0  
BodyContent bc = getBodyContent(); q[ 9N4nj$<  
a_-@rceU  
//将body的内容以字符串的格式提取出来 nw_s :  
.PV(MV  
String query = bc.getString(); qOIVuzi*  
7!wc'~;  
//清除body 8nWPt!U:  
Fv$A%6;W  
bc.clearBody(); qoZ)"M  
I;n <) >  
try{ LzD RyL  
/8!n7a7  
Statement stmt = connection.createStatement(); jo3(\Bq  
OMM5ALc(F  
Result result = stmt.executeQuery(query); w=3 j'y{f  
yz,0 S'U  
}catch(SQLException e){ \hn$-'=4  
1;'-$K`}  
throw new JspTagException(“queryTag: “ + e.getMessage() ); eoXbZ  
V.6pfL  
return SKIP_BODY; *?$M=tH  
HA7%8R*.2i  
} hn\d{HP  
.Z#/%y3S  
} qHtIjtt[q  
R$66F>Jz^  
z 2jC48~  
body-content元素 "R=~-, ~  
Ji:<eRx)  
_!!Fg%a5"R  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: &W c$VDC  
KV8<'g+2?  
<body-content>JSP|tagdependent</body-content> \WbQS#Z9  
*A4eYHn@  
8Lgm50bs  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 w^("Pg`  
T\(k=0R M  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 |i #06jIq  
]T)<@bmL  
sH_, P  
用tags定义脚本变量 ml Cg&fnDB  
``I[1cC  
# 5U1F[  
tag处理类 bM5o-U#^ C  
VIN0kRQ#  
>fth iA  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 +GL$[ 5G  
 I8`$a  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 "^!y>]j#A  
p Pag@L  
对象的生存周期(scope)如下表: k`A39ln7wu  
(x?Tjyzw  
对象的生存周期表 'TuaP `]<  
Pqw<nyC.  
名字 kU=U u>  
可访问范围 )J0h\ky  
生存周期 awvP;F?q|  
h_+  
page Kd5 8'$  
当前页面 zH6@v +gb  
一直有效,除非页面向客户提交响应或重定向到一个新页面 al-rgh  
Ej 5_d  
request -zn_d]NV  
当前页面或当前页面重定向到的页面 Mp>(cs  
一直有效,除非页面向客户提交响应 kd\Hj~*  
CaO-aL  
session q<! -Anc  
当前页面或在同一浏览器窗口中的页面 QIlZZ  
一直有效,除非关闭当前浏览器、超时、网络故障 *8m['$oyV  
'P" i9j  
application  o kA<  
整个web应用程序的所有请求 A_9J ~3  
一直有效,除非发生网络故障、服务器故障 % @+j@i`&  
"y&`,s5}  
提供关于脚本变量的信息 :$,MAQ'9  
f,Dic%$q  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: jl&Nphp  
rQ_@q_B.  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> qIQRl1Tw;V  
7pciB}$2  
<font color=”red” size=”+2” > 3X11Gl  
EY<"B2_%  
<%= messages.getString(“CartRemoved”) %> Bf;_~1+vLG  
&KAe+~aPm  
<strong><jsp:getProperty name=”book” property=”title” /></strong> qy)~OBY  
S#v3%)R  
</font> dpsc gW{M  
-f mJkI  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: eh `%E0b}  
h]k $K  
· 脚本变量名称 3Cc#{X-+  
:S_]!'H  
· 脚本变量所属的类 %dg[ho  
25-h5$s  
· 此脚本变量是否引用了一个新的或已存在的对象 )X[2~E  
_/noWwVu  
· 此脚本变量的有效性 -X~|jF  
|g)>6+?]W  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 $*iovam>^]  
vno/V#e$WX  
Variable元素 ?z&%VU"  
S7Ty}?E@  
Variable元素有如下子元素: ~"#HHaBO#  
;%^=V#  
· name-given ?D?D 给出的名字,是一个常量 LlO8]b!P-^  
PC<_1!M]  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 nWY^?e'S  
BR@m*JGajz  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: qx[c0X!  
]4en |Aq  
· variable-class?D?D变量的类型,缺省为java.lang.String。 aE 9Y |6  
&k%>u[Bo  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 bNVeL$'  
!=,Y=5M,  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: ">z3i`#C'  
N\ !  
脚本变量的有效范围 ChG7>4:\  
p\ ;|Z+0=  
yvoz 3_!  
有效性 o5?Y   
方法 II}M|qHaK  
s) shq3O  
NESTED >VkBQM-%  
在tag标签的开始和结束之间 X]D,kKasG  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 R8Vf6]s_  
G#7(6:=;,`  
AT_BEGIN }}QR'  
从tag标签的开始一直到页面结束 3EICdC  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 R~k`KuY@!  
, i5_4  
AT_END A+0-pF2D  
从tag标签的结束一直到页面结束 wqF?o  
在doEndTag中调用 @ gWd  
U*$xR<8v  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: u6ULk<<\  
f(Of+>   
<tag> `{G&i\"n  
fyb;*hgu  
<variable> Pp tuXq%U  
JN|6+.GG  
<name-from-attribute>id</name-from-attribute> Z%qtAPd  
mnsl$H_4S  
<variable-class>database.BookDetails</variable-class> nJ2x;';lA  
bTaKB-  
<declare>true</declare> $0E+8xE  
L!If~6oD(  
<scope>AT_BEGIN</scope> sE6>JaH  
F^NK"<tW  
</variable> "a8E0b  
K%? g6j  
</tag> _y^r==  
r@{TN6U  
额外tag信息类 LnI  
, ,{UGe 3  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: Ww2@!ng  
w>&*-}XX  
· 变量名 WQ.0}n}d  
rTIu'  
· 变量所属类名 :lcq3iFn  
nTEN&8Y>R  
· 此变量是否引用了一个新对象 xf]K  
4 V')FGB$  
· 此变量的有效范围 0 Uropam  
`x`[hJ?i  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。  mLxgvp  
KkA)p/  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: &3[oM)-V  
3N2d V6u  
V*uE83x 1  
public class DefineTei extends TagExtraInfo J, 9NVw$  
No'?8+i  
{ 6:7[>|okQ  
Cku"vVw,  
public VariableInfo[] getVariableInfo(TagData data) N>!:bF  
_qxI9Q}<"  
{ L=4+rshl!_  
cQU;PH]  
String type = data.getAttributeString(“type”); ZD]1C ~)  
"]+g5G  
If( type == null) O,Q.-  
x;n3 Zr;(  
type = “java.lang.Object”; g"!(@]L!@  
7MKX`S  
return new VariableInfo[] { f~`=I NrU  
lM6pYYEq=  
new VariableInfo(data.getAttributeString(“id”), kOYUxr.b  
&0F' Ca  
type, 08`|C)Z!  
P=QxfX0B  
true, 2*|T)OA`m,  
hH8&g%{2  
VariableInfo.AT_BEGIN) E7:xPNU  
d~LoHp  
}; FlBhCZ|^  
[0 F~e  
} =&WIa#!=  
}e?H(nZS7h  
} FZr/trP~  
6_Fr\H  
nI\6a G?`  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: -K64J5|b7  
<tei-class> ,&P 4%N"  
org.apache.struts.taglib.bean.DefineTagTei m\L`$=eO8  
</tei-class> O *sU|jeO  
$C4~v  
$TI^8 3  
具有协作关系的tag k?+ 7%A]  
R6+)&:Ab{R  
m8q4t ,<J  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 u\]EG{w(  
\Z[1m[{  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 vrnvv?HPrR  
/eF@a!  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 QNj]wm=mp  
B/twak\  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 ?d7,0Ex P  
KGz Nj%  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 u_(~zs.N]  
=&}@GsXdo  
DX s an  
public class QueryTag extends BodyTagSupport $|N6I  
]juPm8eF  
{ 2c `m=  
//R"ZE@d\  
private String connectionId; QL?_FwZL  
VW-qQe  
public int doStartTag() throws JspException H+v&4}f  
NJUKH1lIhR  
{ 9LDv?kYr  
d54iZ`  
String cid = getConnection(); Ep7MU&O0iK  
!GcBNQ1p+7  
if(cid != null) }Q\%tZC#T  
Nu5|tf9%A  
{ .ZTvOm'mB^  
E9:@H;Gc  
//存在一个connection id,使用它。 -$Oh.B`i  
^/f~\ #R  
connection = (Connection) pageContext.getAttribute(cid); d>QFmsh-  
:gVUk\)  
} |cvU2JI@  
n6/Ous  
else E }L Hp  
sPH 2KwEv  
{ b9b Ivjm_  
P`Np +E#I  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, YvR bM  
ARH~dN*C  
ConnectionTag.class); 3BFOZV+  
-`O{iHfM|P  
if(ancestorTag == null) "#Rh\DQ  
i'IT,jz !  
{ {{G)Ry*pb  
~k"+5bHa*  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); broLC5hbQU  
8q2a8I9g  
} }w0pi  
&7L7|{18  
connection = ancestorTag.getConnection(); CIudtY(:  
"+HJ/8Dd1  
} -l^<[%  
Q6h+.  
} gq=t7b  
1"h"(dA  
} cgnNO&  
\DB-2*a"  
w"hd_8cO  
]Q^)9uE\D  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: +QChD*  
R\j~X@vI  
,f }$FZ  
<tt:connection id=”con01” ...> ... </tt:connection> 6=iHw 24  
7J'%;sH  
<tt:query id=”balances” connection=”con01” > 0vY_  
kAftW '  
SELECT account, balance FROM acct_table I^NDJdxd  
,AP&N'  
where customer_num = <%= request.getCustno() %> 2t= = <x  
c=m'I>A  
</tt:query> i]8O?Ab>?  
.#[ 9q-  
;mQj2Bwr  
xS*UY.>  
H$![]Ujq  
<tt:connection ...> X8C7d6ca  
Xw H>F7HPe  
<x:query id=”balances”> Kz HYh  
HDe\Oty_  
SELECT account, balance FROM acct_table #M-!/E  
gx&es\  
where customer_num = <%= request.getCustno() %> /jv/qk3i  
C}huU  
</x:query> 4cjfn'x  
-TUJ"ep]QJ  
</tt:connection>  N' hT  
}b_Ob  
I8xdE(o8+  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: ug3\K83aj/  
YWZ;@,W  
<tag> z^bS+0S5x!  
\&"C  
... '| 8 dt "C  
?f?5Kye  
<attribute> ^<I(  
k^5Lv#Z  
<name>connection</name> qO6M5g:   
+nYFLe  
<required>false</required> `TBXJ(Y  
yw1 &I^7  
</attribute> 8Qvs\TY  
3?Pg ;  
</tag>
描述
快速回复

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