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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! uK`gveY  
"'@D\e}  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 *3!r &iY  
w!v^6[!  
在这篇文章中,我们主要讨论: NZa 7[}H  
`(`-S md  
· 什么是自定义tag标签? JbJ!,86  
cruBJZr*  
· 怎么使用tag标签? =:zPT;K  
@YQ*a4`  
o 声明要使用的tag库 HFTeG4R  
/#SfgcDt  
o 找到与之对应的tag处理类 9_F&G('V{a  
LI25VDZ|iP  
o tag标签的类型 &BNlMF  
sD2,!/'  
· 自定义tag标签 7R m\#  
NZ&ZK@h}.  
o tag处理类 ao=e{R)  
mqHH1}  
o tag库描述 `LLmdm 6i  
/5z,G r  
o tag标签示例 " DLIx}  
5c(g7N  
o 带属性的tag m. p'LF  
Lwx J:Kz.  
o 带body的tag bvrXz-j  
- 0q263z  
o 定义了脚本变量的tag 2boyBz}=S  
/; /:>c  
o 具有协作关系的tag 9N{?J"ido  
hkm}oYW+  
· 自定义tag标签 ,c$tKj5ulQ  
ujkWVE'  
o 一个迭代tag的例子 _b>{:H&\  
g6aqsa  
o 一个模板tag库 @ S[As~9X  
YVv E>1z  
o tag处理类到底是怎样被调用的? Yy 0" G  
@ext6cFe3<  
r&B0 -7r  
什么是自定义的tag? 6}Tftw$0z  
S)wP];]`K  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 A+foc5B  
+boL?Ix+  
自定义tag标签有很多特色,诸如: nxBP@Td  
cYe2 a "  
· 可以在JSP页面中自定义tag标签的属性 u-s*k*VHoc  
#NGtba  
· 访问JSP页面中的所有对象 Z<^EZX3N  
[7~AWZU3  
· 可以动态地修改页面输出 J$5 G8<d>  
?Js4 \X!uJ  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 gq 3|vzNZ  
B8"c+<b  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 @#hvQ6u  
.w@B )f*  
+Ek1~i.  
使用tag标签 9W]OtSG  
1n}#54  
ti6X=@ P:  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 ,Eh]Zv1 AE  
9QB,%K_:4  
要使用tag标签,JSP程序员必须做2件事: "*j8G8  
hY%} x5ntU  
· 声明此tag标签的tag库 @mxaZ5Vv}  
(!N2,1|  
· 实现此tag标签 rC!"<  
iu*&Jz)D>  
声明tag标签所在的tag库 =[!(s/+>L  
vzbGLap#  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) #_aq@)Fd  
U{Oo@ztT  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> YEaT_zWG0  
60$;Q,]o  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 _h  \L6.  
[kqtkgK$j2  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 [q3zs_nz  
<;W-!R759  
以下taglib指示符直接引用一个TLD: DCZG'eb  
Y/I)ECm  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> );JWrkpz  
kSc~gJrne  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: x3`JC&hF,q  
WjK[% ;Z!  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> ok:L]8UN 3  
z,E`+a;  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: 3)#Nc|  
#}@8(>T  
<taglib> 8q{|nH  
L[ D+=  
<taglib-uri>/tutorial-template</taglib-uri> {~FPvmj&  
"+7E9m6I  
<taglib-location> GiM-8y~  
Dt(D5A  
/WEB-INF/tutorial-template.tld OaY89ko  
+swTMR  
</taglib-location> V>Z4gZp5sc  
U_izKvEh  
</taglib> :Z2997@Y  
@#N7M2/  
PWx%~U.8~j  
实现此tag标签 @MTv4eC}e  
sF[gjeIb  
X])iQyN  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 Nb !i_@m%s  
U?{oxy_[2  
v6=%KXSF  
tag标签类型 o8<~zeI  
KN657 |f  
'NCqI  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): Gds(.]_  
& C)1(  
<tt:tag> ,lvG5B\0  
:2==7u7v?  
body uQx/o ^  
B|"i`{>  
</tt:tag> i.Y2]1  
hF@%k ;I  
zng.(]U/?H  
一个不带body的tag标签如下: ovM;6o  
n YUFRV$  
<tt:tag /> (.@peHu)#  
=M*pym]QSY  
-2[4 @  
简单的tag标签 BgT ^  
S#8)N`  
一个没有body和属性的tag标签如下: D QxuV1  
- QY<o|  
<tt:simple /> W]7<PL*u  
i\/'w]  
1_f+! ns#  
带属性的tag标签 NNqvjM-  
k,=<G ,  
]N'% l]_$  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 m3pDFI  
W3>9GY90R  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: ]jVE  
xl,% Z~[  
<loglic:present parameter = “Clear”> |X A0F\  
&uO-h  
而另一个标签logic:iterate是用表达式来给属性赋值: 612,J  
F$ G)vskd  
<logci:iterate collection=”<%= bookDB.getBooks() %>” '5$@ I{z  
k]r4b`x`  
id=”book” type=”database.BookDetails”> C^4,L \E  
3fQ`}OcNr  
`4xQ#K.-  
带body的tag标签 YU[#4f~  
0wVM% Dng  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 ^L d5<  
#9[>  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: +3-5\t`  
/"k[T  
<logic:present parameter=”Clear”> \ZV>5N3hS  
$3p48`.\  
<% cart.clear(); %> 9^n0<(99b  
]*k ~jY,  
<font color=”#ff0000” size=”+2”><strong> 98 5h]KQ  
w8Z#]kRv  
你选择了清除购物车! "PRHQW  
8M,o)oH  
</strong></font> Q0jg(=9wP  
]nRf%Vi8g  
</logic:present> 71AYDO  
M_%KhK  
hLZf A rq}  
到底是用属性还是用body来传递信息? A_U=`M=-  
59j`Z^e  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。  {p/Yz#  
+kYp!00  
]k]bLyz\J  
定义脚本变量的tag标签 B1~`*~@  
K*DH_\SPK  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: \ Xh C  
)6p6<y  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> Nb ~J'"  
b,+KXx  
<% tx.begin(); %> U7n#TPet  
#>:S&R?2t  
... :nb|WgEc  
EFVZAY"+!;  
Et }%)M  
具有协作关系的tag标签 K{DmMi];I  
!=,zy  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 ]W Yub1  
>/4[OPB0R  
<tt:tag1 attr1=”obj1” value1=”value” /> t~K[`=G\ex  
5ta;CG  
<tt:tag2 attr1=”obj1” /> 0F- +)S?M[  
PZJn/A1  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 T}Wbt=\M  
9<3}zwJ  
<tt:outerTag> dg#Pb@7a  
C|Gk}  
<tt:innerTag /> VV$#<D<)  
j?o6>j  
</tt:outerTag> qvy*; <w  
RiR],Sj  
x!s=Nola  
Tag处理类 QbHX.:C  
iVeH\a  
P~!,"rY  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 MLTS<pW/  
gS[B;+d  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 ;g#nGs>  
7w9'x Y  
下表说明不同类型的tag所需要不同的处理过程: tx<^PV2  
hVB(*WA^D  
Tag处理类的方法 7@gH{p1  
QwG_-  
Tag标签类型 ZEDvY=@a   
所调用的方法 q+8de_"]  
AHuIA{AdUR  
基本标签 aiz ws[C  
doStartTag, doEndTag, release }[!=O+g O  
0%&}wUjV  
带属性的标签 A*+gWn,4Y_  
doStartTag, doEndTag, set/getAttribute1...N, release (c}!gjm  
yLCMu | +  
带内容的标签 X0j>g^b8  
doStartTag, doEndTag, release Z~94<*LEp  
fNx!'{o"  
带内容的标签,且内容重复循环 ~V?z!3r-)  
doStartTag, doAfterBody, doEndTag, release ]CcRI|g}  
_\k?uUo&,^  
带内容的标签,且内容与JSP交互 @?]>4+Oa0  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release 1@LUxU#Uu$  
J"E _i]  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 ^.@%n1I"5y  
MRo_An+  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 ~cO iv  
8,h!&9  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 v8C($<3%  
/=za m3kd  
K0vS  
Tag库描述(简称TLD) Ici4y*`M  
7;TMxO=bra  
~};q/-[r  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 WY@g=W>+  
{0,6- dd5  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 sx7zRw >X  
T3=h7a %=  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: [x, `)Fk  
H2[0@|<<  
<?xml version="1.0" encoding="ISO-8859-1" ?> fH9"sBiO  
Ex]Ku  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> xuqG)HthRS  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: 4/*@cW  
|%XcI3@*  
|[#Qk 4Ttf  
<taglib>的子元素 %o\+R0K  
[+A]E,pv]1  
Element WB'1_a  
Description {=d}04i)E"  
2auJp .  
tlib-version J1gnR  
Tag库的版本 ,2FI?}+R  
iE;F=Rb  
jsp-version e&!c8\F  
Tag库所需要的jsp的版本 8#,_%<?UVy  
/TB{|_HbW  
short-name ^A\(M%*F  
助记符,tag的一个别名(可选) ] FvGAG.*  
"B +F6  
uri /!>OWh*~  
用于确定一个唯一的tag库 4IY|<  
 6; )5v  
display-name AG%[?1IXW  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) $f+I#uJ  
+zDRed_]=_  
small-icon NB^Al/V@  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) Qof%j@  
L|(U%$  
large-icon S^D@8<6GJ  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) <?DI!~  
4=y&}3om(0  
description UB8n,+R  
对tag库的描述(可选) _~umE/tz  
An?#B4:  
listener S"^'ksL\  
参见下面listener元素 jd5kkX8=  
}#&[[}@th  
tag T]/>c  
参见下面tag 元素 #k &#d9}  
}z9v*C  
Listener元素 &ZFHWI(P  
@}PX:*c  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 eAP 8!  
{=&( { cS  
Tag元素 =\5f_g2M  
G[u6X_Q  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 yEh{9S%6p  
n dN*X'  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: @\oZ2sB  
hiV!/}'7  
Tag元素的子元素 "+&pd!\  
up8d3  
元素名称 n?D/bXp  
描述 ?5};ONjN  
7l*vmF6Z  
name Vep 41\g^  
独一无二的元素名 a\,V>}e  
3PLA*n+%  
tag-class ,|z zq@fk  
Tag标签对应的tag处理类 8a8D0}'  
Ie _{P&J  
tei-class rhaq!s38:  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) P&[&Dj  
#E\6:UnT  
body-content %8Y+Df;ax  
Tag标签body的类型 5{DwD{Q  
69:-c@ L0  
display-name X6w+L?A  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) Y1ca=ewFx  
d9jD?HgM(  
small-icon }?6;;d#  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) pz/W#VN  
;iJxJX\+  
large-icon !.pcldx  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) Vom,^`}  
l(F\5Ys  
description # &5.   
此tag标签的描述 \3K7)o^  
rp1+K4]P  
variable #bG6+"g{=L  
提供脚本变量的信息(同tei-class)(可选) {0/2Hw n  
8gt*`]I  
attribute ~5Mj:{B  
Tag标签的属性名 R/E6n &R  
'YbE%i}  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 #CyqiOM\*  
}F9#3W&`c  
lMg#zT!?  
简单的tag $txF|Fj]^A  
)~nieQEZQ  
{wz_ngQ  
tag处理类 DNqC*IvuzM  
DC BN89#  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 'q}f3u>  
[C;Neslo  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: XUUP#<,s  
BjTgZ98J  
cmCD}Skk  
public SimpleTag extends TagSupport SG0PQ  
y | I9"R  
{ /S~ =qodS  
=h ~n5wQG  
public int doStartTag() throws JspException bd27])n(  
~>0H k}Hv  
{ i tk/1  
tW-[.Y -M,  
try{ w"QZ7EyJ  
2cGiE{  
pageContext.getOut().print(“Hello.”); bNm]h.  
S^EAE]  
}catch(Exception e){ ` ` Yk  
eq&QWxiD*  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); @}{uibLD\  
W|n$H`;R  
} Z8Vof~  
n6Z!~W8  
return SKIP_BODY; Q^@7Yg@l  
N@!PhP  
} aiE\r/k8s  
<X& fs*x&  
public int doEndTag() vMJ(Ll7/  
oaILh  
{ NNE(jJ`/  
u.?jWvcv  
return EVAL_PAGE; U:c 0s  
`/!FZh<  
} 7d|1T'  
i`vy<Dvpz  
} utC^wA5U~  
7 &%#bMnw  
f:~$x  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 cF9oo%3  
(mI590`f  
<body-content>empty</body-content> \"Z\Af<  
tc\ZYCFr  
`cN8AcRHP  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 zx.SRs$  
MpJ<.|h  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, q 6>}  
UK,sMKbl1  
<logic:present parameter=”Clear”> XAtRA1.  
=9 ^}>u  
与此相应,此tag处理类应有如下方法和定义: w8J8III\~  
Zt=P 0  
+KNd%AJ  
protected String parameter = null; EdSUBoWF}  
qZ@d:u  
public String getParameter() mieyL9*n7  
hJir_=  
{ ssoE,6kS  
]\L+]+u~  
return this.parameter; ];b+f@  
8.I3%u  
} 3=} P l,  
}Ujgd2(U  
public void setParameter(String parameter) ('\sUZ+5  
`s Pk:cNz~  
{ b7T;6\[m  
du#f_|xG  
this.parameter = parameter; tXZMr   
oj)(.X<8N  
} N#$]W"U  
@v&s|X '  
:$PrlE  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 h.l.da1#  
y c 8 h}`  
Attribute元素 ,\aL v  
eQn[  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 ?cKTeGrS  
0) F\aJ4Y  
<attribute> Y"yrc0'&T  
&}pF6eIar  
<name>attr1</name> 0G33hIOS  
4*5e0:O  
<required>true|false|yes|no</required> WXDo`_{R  
"Ehh9 m1&  
<rtexprvalue>true|false|yes|no</rtexprvalue> KtH^k&z.f  
qK9A /Mc  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> d~h;|Bl[  
pLV %g#h  
</attribute> gG}H5uN  
E'(nJ  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 ZU+_nWnl  
/;1O9HJa  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 Hz==,NR-W  
SBDGms  
<tag> FH$q,BI!R  
U|\ .)h=  
<name>present</name> 6KXW]a `  
i ?uX'apk  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> X-,oL.:c  
@7.7+blS"H  
<body-content>JSP</body-content> !y'>sAf  
Ht\2 IP  
v&WK9F\  
9PV+Kr!c5I  
<attribute> k_zn>aR$F  
4gNN "  
<name>parameter</name> Iw h0PfWJ  
:M f8q!Q'  
<required>false</required> -o{ x ;:4  
n"D` =  
<rtexprvalue>true</rtexprvalue> =NI?Jk*iAq  
1,Mm+_)B  
</attribute> hiA\~}sl n  
UL>2gl4s/  
~/z%yg  
~w|h;*Bj  
</tag> =l${p*ABQ  
yG7H>LF?8  
^~7Mv^A  
属性元素的校验 :l1-s]  
fiD,HGx i  
B$x@I\(M  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 i'"#{4I  
Rt&5s)O'  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 *n7=m=%)  
(6:.u.b  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 Th*}U&  
0chpC)#Q3;  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: 748:* (O  
HpfZgkC+  
<attribute> H)"]I3  
vD?D]8.F~Q  
<name>attr1</name> W83PMiN"T-  
z/f._Z(  
<required>true</required> Ak kF6d+  
H^@Hco>|  
<rtexprvalue>true</rtexprvalue> H-v[ShE  
%Q &']  
</attribute> F'|e:h  
nLG)>L  
``$$yS~d};  
这个定义说明了attr1能在运行期间被赋值。 j2u'5kJ G  
H>;,r ,  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 G kG#+C0L  
<*dcl2xS  
6-TYOUm  
Public class TwaTEI extends TagExtraInfo q9j~|GE|  
Dykh|"  
{ f5b|,JJ  
3!fR'L/i  
public boolean isValid(Tagdata data) &0%Z b~ts  
F --b,,  
{ j%-Ems*H  
~ho,bwJM[T  
Object o = data.getAttribute(“attr1”); C/qKa[mg  
@fp@1n  
If(o != null && o != TagData.REQUEST_TIME_VALUE) 3\ Mt+!1{  
<HN+pi  
{ <#nU 06 fN  
]y=U"g  
if( ( (String)o).toLowerCase().equals(“true”) || ?Fn y_{&^H  
ort*Ux)  
((String)o).toLowerCase().equals(“false”) ) V:J|shRo  
'q |"+;  
return true; c$2kR:  
.ve_If-Hg  
else 7vFmB  
4dCXBTT  
return false; etiUt~W  
M:%g)FgW  
} :/szA?:W  
rg k1.0U0  
else 3'`&D/n  
Y$n+\K  
return true; r,0D I  
%aK[Yvo6  
} ol/@)k^s>  
nAl \9#M  
} L FJ@4]%V  
'h'pM#D  
hp(MKfhH  
带body的tag ,\P|%yv  
Y<VX.S2kf  
eaDZ^Z Er  
tag处理类 MZ-;'w&Z  
'l~7u({u  
Ot`%5<E^  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 fx(8 o+  
#<9'{i3  
Tag处理类不与body交互 % R25,  V  
d$bO.t5CLh  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 P![ZO6`:W'  
,e;,+w=~E  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 @S}j=k  
vnQFq  
Tag处理类与body交互 f~a 7E;y  
e.DN,rhqI  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 #I0FWZ>W  
3?"gfw W  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 NcF>}f,}\  
$3>Rw/,  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 %po;ih$jr*  
^ [HUtq  
doInitBody 方法 Y 'X!T8  
"i/GzD7`n  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 hDW_a y4  
$#s5y~z  
doAfterBody方法 2ns,q0I A  
BV>9U5  
此方法在body内容已被计算后进行调用。 /]Y#*r8jRi  
v@[3R7|4  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 i*mU<:t  
_[-MyUs  
release 方法 ),B/NZ/-  
^ [m-PS(  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 Ezew@*(  
>"<s7$g  
w/( T  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 (n?f016*%d  
_zM?"16I}  
db_?da;!`  
Public class QueryTag extends BodyTagSupport R0*P,~L;|  
U9b[t  
{ exiu;\+j  
cRr3!<EZ  
public int doAfterBody() throws JspTagException ;r"r1'a+@  
%gFIu.c  
{ l6w\E=K  
>\pF5a`  
BodyContent bc = getBodyContent(); P (7el  
Qfy_@w]  
//将body的内容以字符串的格式提取出来 z,m3U(  
_oBx:G6E  
String query = bc.getString(); ]] 0M  
eF{uWus  
//清除body v+Y^mV`|  
AU`z.Isf  
bc.clearBody(); yQj J-g(.  
af>i  
try{ L,#YP#O,j  
rqN+0CT  
Statement stmt = connection.createStatement(); c)^A|{,G  
AhOBbss]q  
Result result = stmt.executeQuery(query); v}t{*P  
4+ d(d  
}catch(SQLException e){ dZ(Z]`L,B  
)hO%W|  
throw new JspTagException(“queryTag: “ + e.getMessage() ); k}<H  
L{>rN`{  
return SKIP_BODY; zFO0l).  
MDIPoS3BRa  
} @Nh}^D >j  
CUpRtE8@[_  
} iH-,l  
DPW^OgL;  
Lc}hjK  
body-content元素 L7rr/D  
5TuwXz1v  
e#mf{1&  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: R||$Rfe  
M61Nl)|mx&  
<body-content>JSP|tagdependent</body-content> lc5(^ ~  
$X)|`$#pL#  
b1IAp>*2l  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 ?OnL,y|  
m)<+?Bv y  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 ~s'}_5;VY  
aDX&j2/  
cyWb*Wv  
用tags定义脚本变量 GR*sk#{  
Hc\@{17   
=2GKv7q$x,  
tag处理类 [Fag\/Y+  
 8(K:2  
tk'&-v'h  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 wV f 7<@/y  
mk~CE  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 MhE".ZRd  
7oIHp_Zq  
对象的生存周期(scope)如下表: "u~` ZV(  
H*<E5^#dw  
对象的生存周期表 ke W7pN?  
r>bgCQ#-n  
名字 #| g h  
可访问范围 _8 K|2$X  
生存周期 }eZ \~2  
Jg'#IM  
page 6 .?0 {2s  
当前页面 PuZzl%i P3  
一直有效,除非页面向客户提交响应或重定向到一个新页面 b+whZtNk7  
Z7y%  
request ,Q Ge=Exn  
当前页面或当前页面重定向到的页面 /[>_Ry,  
一直有效,除非页面向客户提交响应 NkGtZ.!pk  
N6_1iIM  
session SFuSM/Pf  
当前页面或在同一浏览器窗口中的页面 Ei]Sks V>*  
一直有效,除非关闭当前浏览器、超时、网络故障 (Lz|o!>  
Q-R?y+| x  
application Oz(=%oS  
整个web应用程序的所有请求 m!<FlEkN  
一直有效,除非发生网络故障、服务器故障 tuwlsBV  
'NjeF&#6  
提供关于脚本变量的信息 &DYC3*)Jih  
'*`n"cC:  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: .,S`VNU  
j&S.k  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> 16I[z+RG  
9&^5!R8  
<font color=”red” size=”+2” > yCkc3s|DA;  
-9+$z|K  
<%= messages.getString(“CartRemoved”) %> e&ZTRgYdi  
a[zVC)N0  
<strong><jsp:getProperty name=”book” property=”title” /></strong> 525^/d6v  
N|)e {|k  
</font> N&k\X]U  
n'pJl  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: jYAm}_?No  
ZWuNl!l>  
· 脚本变量名称 INk|NEX  
o%lxEd r  
· 脚本变量所属的类 h'G  
j<Pw0?~s6  
· 此脚本变量是否引用了一个新的或已存在的对象 [N[4\W!!  
0lq?l:/  
· 此脚本变量的有效性 Bo ywgL|  
;QG8@ms|  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 6_yatq5c  
GYJ j$'  
Variable元素 C{l-l`:  
NhYUSk ~u  
Variable元素有如下子元素: Z{#3-O<a+n  
[\Aws^fD_  
· name-given ?D?D 给出的名字,是一个常量 [Ax :gj  
n3U| d+  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 #] Do_Z  
;cL+= !  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: nHXPEbq-g  
}>,%El/  
· variable-class?D?D变量的类型,缺省为java.lang.String。 7bGt'gvv  
IJPyCi)  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 OOnj(%g  
t^6ams$  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: Xooh00  
# E8?2]  
脚本变量的有效范围 +W-b3R:1>  
jL 3 *m  
'_K`1&#U  
有效性 zh?B-"O=5  
方法 -g 9CW[  
$OGMw+$C ^  
NESTED w*@9:+  
在tag标签的开始和结束之间 I~"l9Jc!"  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 ?6N\AM '  
7uv"#mq  
AT_BEGIN Pq-@waH3  
从tag标签的开始一直到页面结束 p ~+sk1[.  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 l% %cU"  
7:$dl #  
AT_END 4RQ38%> >j  
从tag标签的结束一直到页面结束 3|3ad'  
在doEndTag中调用 }VH2G94Ll  
w+\RSqz/  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: R[vX+d!7  
T I ZkN6  
<tag> `-W4/7  
V0#E7u`4  
<variable> 'rfs rZ?  
BTA2['  
<name-from-attribute>id</name-from-attribute> <X1[j9Qtv0  
%.uN|o&n  
<variable-class>database.BookDetails</variable-class> Mj19;nc0I  
#:MoZw`rlw  
<declare>true</declare> !HXsxNe  
iz tF  
<scope>AT_BEGIN</scope> %2G3+T8*x  
%md9ou`  
</variable> % 1<@p%y/  
j6 _w2  
</tag> [a^<2V!vMn  
 1&=2"  
额外tag信息类 rX`fjS*C  
P=9sP:[f6  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: F*:H&,  
DAMw(  
· 变量名 hSh^A5 /  
`I|Y7GoUO  
· 变量所属类名 cIuCuh0I`  
pFo,@M  
· 此变量是否引用了一个新对象 $K|2k7  
`\BBdQ#bH  
· 此变量的有效范围 {+9t!'   
"JYWsE  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 :c[T@[  
')fIa2dO/  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: dsK ^-e6:5  
Z\)P|#L$  
yW"}%) d  
public class DefineTei extends TagExtraInfo MAc/ T.[  
~~ty9;KYL  
{ ^M1O)   
xkaed  
public VariableInfo[] getVariableInfo(TagData data) f+c{<fX  
L#_QrR6Sny  
{ <%`z:G3  
P[ Vf$ q<  
String type = data.getAttributeString(“type”); 7 :u+-U  
yN}<l%  
If( type == null) Z>'hNj)ju  
MB.LHIo  
type = “java.lang.Object”; MY&?*pV)  
V5I xZn%  
return new VariableInfo[] { iW? NxP  
JQ\o[t  
new VariableInfo(data.getAttributeString(“id”), 2 t]=-@  
rV I-Yb  
type, m{6 *ae  
/-3)^R2H  
true, W5 RZsS]  
-dUXd<=ue  
VariableInfo.AT_BEGIN) }-WuHh#  
wmX *n'l  
}; Pv8AWQQJ  
^DR`!.ttr  
} ~^eC?F(  
fhQ N;7  
} -]MZP:s  
O<0-`=W,a  
-n$hm+S  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: 6rAenK-%  
<tei-class> Y3luU&'  
org.apache.struts.taglib.bean.DefineTagTei w6k^|."  
</tei-class> mw=keY9]  
-.vNb!=  
IBv9xP]BZ  
具有协作关系的tag Sj4@pMh4  
[#2z=Xg  
\88 IFE  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 }e,*'mCC*  
9kU|?JE  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 js=w!q0)9  
*>Zq79TG  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 XZPq4(,9}  
(K> 4^E8  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 d!q)FRzi  
wQ9fPOm  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 mY]R~:  
9t0NO-a  
n11eJEtm  
public class QueryTag extends BodyTagSupport 9uY$@7qH  
> bSQ}kXe  
{ %XWb|-=  
EF'U`\gX  
private String connectionId; ]P(_ d'}  
Ob7F39):N  
public int doStartTag() throws JspException y8O<_VOO}"  
a 1pa#WC  
{ }Xy<F?Mh  
p4wXsOQ}  
String cid = getConnection(); fYZ)5xnj  
km!jxs  
if(cid != null) *ps")?tlC  
KZTT2KsYl  
{ SNf*2~uq)  
z4c{W~}`  
//存在一个connection id,使用它。 nrI-F,1  
vC!}%sxVw_  
connection = (Connection) pageContext.getAttribute(cid); t{ScK%S6  
]1n =O"vE  
} 5?4jD]Z  
\!:^=2VF  
else S4(lC%$|  
D7b] ;Nf\  
{ Ja#ti y  
:+\B|*T2.L  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, ukRbSJ5a5  
"EC,#$e%ev  
ConnectionTag.class); rQPV@J]:  
th(<S  
if(ancestorTag == null) WMd5Y`y  
>`c-Fqk  
{ Ucz`^}+  
PWThm ooP  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); iOzY8M+N(  
L+y90 T6?  
} C e1^S[  
yGtGhP8  
connection = ancestorTag.getConnection(); =;^#5dpt$  
Zo|# ,AdE>  
} 3]}wZY0  
Kr|9??`0E  
} Zb=H\#T  
pElAY3  
} OfGMeN6  
p+ bT{:  
=h9&`iwiu  
ns,qj} #  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: c)OQ_3xOs  
PF?tEw_WB  
7 xm>+(  
<tt:connection id=”con01” ...> ... </tt:connection> c:MP^PWc  
Fv"jKZPgzz  
<tt:query id=”balances” connection=”con01” > w qLY \  
'm,3znX!c  
SELECT account, balance FROM acct_table 9My |G)M6  
I&O}U|l06  
where customer_num = <%= request.getCustno() %> h"{Z%XPX#  
\vvV=iw  
</tt:query> L<**J\=7M  
P Yp<eo\  
R3SAt-IE  
*CtO Q  
EpCsJ08K  
<tt:connection ...> .A`Q!  
h}o7/p  
<x:query id=”balances”> yY$:zc"J  
yH0BNz8V  
SELECT account, balance FROM acct_table 3-5X^!C  
-_RMiGM?T  
where customer_num = <%= request.getCustno() %> b-rgiR$cg  
QK3j.Ss  
</x:query> q'%-8t  
<k0$3&D  
</tt:connection> fH/J8<  
>Hq)1o  
" E U[Lb  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: 8f37o/L  
|lOH PA  
<tag> q;p:)Q"  
VnB"0 "%w  
... b]X c5Dp{  
,dM}B-  
<attribute> ,Mp/Y>f  
&nk[gb o\  
<name>connection</name> @3hA\3ot^  
9fyJw1  
<required>false</required> "Y Z B@  
{>E`Zf:  
</attribute> &xG>"sJ  
wua`e <"  
</tag>
描述
快速回复

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