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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! WQx;tX  
bed+Ur&  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 BE~[%6T7  
#pfosC[  
在这篇文章中,我们主要讨论: 4lCm(#T{,  
sXxO{aeev  
· 什么是自定义tag标签? AHGcWS\,X  
N3p3"4_]fy  
· 怎么使用tag标签? Ne 4*MwK  
1tdCzbEn+  
o 声明要使用的tag库 @{uc  
$ *A3p  
o 找到与之对应的tag处理类 +bW|Q>u  
=6&D4~R  
o tag标签的类型 cmI#R1\  
V-jL`(JF%  
· 自定义tag标签 Y=Qf!Cq]  
?M^t4nj  
o tag处理类 [<QWTMjR  
!$Z"\v'b  
o tag库描述 N&=2 /  
QEa=!O  
o tag标签示例 <>s\tJ  
hm>*eJNp]  
o 带属性的tag 4a!7|}W  
;!?K.,N:N  
o 带body的tag G`"Cqs<  
Hw&M2a  
o 定义了脚本变量的tag -QDgr`%5  
8[;oUVb5  
o 具有协作关系的tag "~C#DZwt{  
Xkom@F~]  
· 自定义tag标签 (}1f]$V  
{LHe 6#  
o 一个迭代tag的例子 X:&p9_O@  
%PbqASm  
o 一个模板tag库 bK9~C" k  
E2'e}RQ  
o tag处理类到底是怎样被调用的? 30+l0\1  
mX@* 2I  
"B3:m-'  
什么是自定义的tag? 9X9zIh]JV  
u 7Y< ~  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 4!vUksM  
k^c=y<I  
自定义tag标签有很多特色,诸如: NqE7[wH  
K/v-P <g  
· 可以在JSP页面中自定义tag标签的属性 A5<Z&Y[  
Ks2%F&\cE  
· 访问JSP页面中的所有对象 OG7v'vmY  
)+4}Ix/q  
· 可以动态地修改页面输出 %L>nXj  
Pl& `&N;  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 IC.<)I  
a<jE 25t  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 nvo1+W(%  
:*:fu n  
*jw$d8q2  
使用tag标签  Cmx2/N  
m_02"'  
m$mY<Q  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 a& aPBv1  
kJi&9  
要使用tag标签,JSP程序员必须做2件事: ?En| _E_C  
G4%M$LJ h  
· 声明此tag标签的tag库 _% 9+U [@  
\*!%YTZ~  
· 实现此tag标签 ^}/ E~Sg7\  
'h6} cw+K  
声明tag标签所在的tag库 *R\/#Y|  
3p 1EScH  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) Z F yX@#B9  
+<WRB\W  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> :Mu8W_  
JRjMt-7H_  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 b}&7~4zw  
 ]RX tC*  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 N!Wq}#&l  
kH8$nkeev  
以下taglib指示符直接引用一个TLD: Prb_/B Dd  
fZV8 o$V  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> i=X*  
xe gL!  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: N[x@j)w-`  
{I9 N6BQ&  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> RnA&-\|*  
t>6x)2,TC  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: M Hnf\|DX  
Pm#x?1rAj  
<taglib> Q_]!an(  
|IX`(  
<taglib-uri>/tutorial-template</taglib-uri> ELrZ8&5G  
: >wQwf  
<taglib-location> zJuRth)(,  
BsK|:MM]  
/WEB-INF/tutorial-template.tld p17|ld`  
b1+hr(kMRM  
</taglib-location> 6}i&6@Snq?  
I*:qGr+ WJ  
</taglib> TvWU[=4Yk  
o[6vxTH  
_<%\h?W$  
实现此tag标签 e>,9]{N+$  
+Y5(hjE  
dE5 5  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 ,a9D~i 9R  
QxL@'n#5   
T\2) $  
tag标签类型 @[5_C?2  
j(Fa=pi  
q?;*g@t  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): 2Ft8dfdm`  
% UW=:  
<tt:tag> C7b 5%a!  
- - i&"  
body o <D3Y95b  
nIV.9#~&  
</tt:tag> pYLY;qkG"  
#aitESbT  
om".j  
一个不带body的tag标签如下: ^ o $W  
$ DDSN  
<tt:tag /> MfXt+c`r  
qE#&)  
IOsXPf9@  
简单的tag标签 I;kf #nvao  
vx\nr8'k  
一个没有body和属性的tag标签如下: 00`bL  
I"8d5a}  
<tt:simple /> r~Y>+ln.  
< -Hs<T|tW  
hi;WFyJTu  
带属性的tag标签 _l#3]#  
'^Pq(b~  
gB/;clCdX)  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 pG,<_N@P  
ur/Oc24i1n  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: o5N]((9  
O%YjWb  
<loglic:present parameter = “Clear”> Y H<$ +U  
"C:rTIH  
而另一个标签logic:iterate是用表达式来给属性赋值: U9<_6Bsd  
SW,q}-  
<logci:iterate collection=”<%= bookDB.getBooks() %>” tv 4s12&  
?@Z7O.u  
id=”book” type=”database.BookDetails”> `j"4:  
Qy{NS.T  
* T JBPM,  
带body的tag标签 &q4ox71  
51&|t#8h  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 J Z %`%rA  
 4]"a;(  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: &e%{k@  
H,(F1+~d  
<logic:present parameter=”Clear”> i'M^ez)u  
jv*Dg (  
<% cart.clear(); %> 536^PcJlN  
SW3wMPy&s  
<font color=”#ff0000” size=”+2”><strong> *w=z~Jq^R"  
OfD@\;L  
你选择了清除购物车! (3AYy0J%  
C@ FxB[  
</strong></font> "(0oP9lZ  
6eD(dZ  
</logic:present> 0FG5_t"",\  
9Tqn zD  
!$D&6M|C8l  
到底是用属性还是用body来传递信息? M_tj7Q3 W  
|$M@09,F"  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 86/.8  
vkd *ER^  
t G]N*%@  
定义脚本变量的tag标签 3b<: :t  
T48BRVX-F  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: d?JAUbqy  
{V.Wk  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> D`V6&_. p  
/^d. &@*  
<% tx.begin(); %> '^hsH1  
*:?QB8YJ  
... dI!8S  
I9;xzES  
6@&fvf  
具有协作关系的tag标签 1d`cTaQ-  
37#cx)p^f  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 bi+9R-=&  
hl`u"?rg  
<tt:tag1 attr1=”obj1” value1=”value” /> !zU/Hq{wcK  
>Q&CgGpW$  
<tt:tag2 attr1=”obj1” /> aXC!t  
I[@ts!YD  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 5;}2[3}[  
Bu&So|@TL  
<tt:outerTag> @]*[c})/  
|0lLl^zp  
<tt:innerTag /> g- XKP  
I<sfN'FpT  
</tt:outerTag> *E.LP1xP  
!-7_ +v>  
NJk)z&M  
Tag处理类 nkTYWw  
lbd(j{h>4  
vlvvi()  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 N=q#y@L  
[8.-(-/;  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 Zgy7!AF!  
,'=hjIel  
下表说明不同类型的tag所需要不同的处理过程: UAdz-)$  
0Yp>+:#  
Tag处理类的方法 ><cU7 ja[^  
>[EBpYi  
Tag标签类型 "$r 1$mBi  
所调用的方法 w;~>k%}j  
r5[4h'f  
基本标签 ;uK";we  
doStartTag, doEndTag, release o OQ'*7_  
&Bm&i.r  
带属性的标签 Vu%n&uF  
doStartTag, doEndTag, set/getAttribute1...N, release !W~QT}  
0 k9<&  
带内容的标签 (#If1[L  
doStartTag, doEndTag, release MF^_Z3GS'  
=MxpH+spI  
带内容的标签,且内容重复循环 VNO'="U  
doStartTag, doAfterBody, doEndTag, release 1\y@E  
St+ "ih%  
带内容的标签,且内容与JSP交互 [3kl^TE  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release S@Iw;V  
#~S>K3(  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 "H$@b`)  
w:Ra7ExP  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 #jm@N7OZ  
O5M2`6|As  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 x}|+sS,g  
-x{&an=  
z+ ZG1\  
Tag库描述(简称TLD) lov%V*tL  
y6FKg)  
6} #"qqnx  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 lH6fvz  
kM;o0wi  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 j;+["mi  
e1UITjy  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: |mOMRP#'  
P$OUi!"  
<?xml version="1.0" encoding="ISO-8859-1" ?> Bzw19S6y  
<h@]Ri  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> GyK(Vb"h6  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: #Kl}= 1 4  
nmg{%P  
03_pwB)^  
<taglib>的子元素 , D"]y~~I5  
*VDVC0R  
Element "mA1H]r3  
Description )~dOmfw%|  
p/&HUQQk  
tlib-version 0X>T+A[E  
Tag库的版本 jkt 6/H  
TF2KZL#A|  
jsp-version F&az":  
Tag库所需要的jsp的版本 Y{+3}drJE  
*HeVACxo  
short-name V{ |[oIp  
助记符,tag的一个别名(可选) O|e}   
=$&&[&  
uri `tVy_/3(9  
用于确定一个唯一的tag库 )4m_A p\  
l9J*um-  
display-name 7&|6KN}c  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) Ao"C<.gUYP  
:tbd,Uo  
small-icon Dr+Ps  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) 6|#g+&[  
]0-<>  
large-icon q3+8]-9|5  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) b#='^W3  
YtYy zX5u7  
description JC2*$qu J  
对tag库的描述(可选) u"Y]P*[k  
pkk4h2Ah  
listener  =:~(m  
参见下面listener元素 o;J;k_[MX  
!_x*m@/  
tag vRr9%zx  
参见下面tag 元素 X<euD9?  
Z@M6!;y#  
Listener元素 9/3;{`+[a  
(Ilsk{aB;A  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 :<utq|#s  
kEP<[K  
Tag元素 E9$H nj+m  
T*+A.G@L"  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 5[R?iSGL1  
u"FjwF?  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: "8/dD]=f^a  
WeVi] n  
Tag元素的子元素 ^y Vl"/  
3U;1D2"AE  
元素名称 iN)af5)[^  
描述 2f..sNz  
6+PGwCS  
name Gru ALx7  
独一无二的元素名 F,pCR7o>  
- _t&+5]  
tag-class c<jB6|.=2  
Tag标签对应的tag处理类 ~gddcTp  
T4GW1NP  
tei-class xZ+]QDKC  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) r/PKrw sC  
l &Z(K,6  
body-content 8&.-]{Z  
Tag标签body的类型 o^GC=Aca`  
Z %EQt  
display-name o , LK[Q  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) jdlG#j-\  
X4Xf2aXI  
small-icon @]?R2bI  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) @a(oB.i  
3_zSp.E\l  
large-icon aYVDp{_  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) _6rKC*Pe1  
Euu ,mleM  
description M&[b.t*  
此tag标签的描述 :hP58 }Q$  
}cW#045es  
variable Tz` ,{k  
提供脚本变量的信息(同tei-class)(可选) 5-w:c>  
5;Ia$lm=y  
attribute A.U'Q|  
Tag标签的属性名 PEzia}m  
)U5u" ]9~  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 7$_ :sJ  
M/B/b<['  
VDiOO  
简单的tag s0!kwrBsp  
%wW'!p-<  
S@A<6   
tag处理类 +c?ie4   
rzT{-DZB[4  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 r*Z_+a8  
Ja [#[BJ?  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: ]!aUT&  
0jTMZ<&zZ  
qTy v.#{y  
public SimpleTag extends TagSupport PL@7 KD Q  
:8]6#c6`74  
{ Tf[dZ(+\  
Hirr=a3  
public int doStartTag() throws JspException 3:AU:  
K~@`o-Z[  
{ VIg\]%qse  
AT ymKJ  
try{ .vaJ Avg  
PWG;&ma  
pageContext.getOut().print(“Hello.”); C P&o%Uc*  
yHOqzq56  
}catch(Exception e){ 3'^S3W%  
w%2ziwgh  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); JV%nH! Fs  
;@4sd%L8V  
} {*fUJmao"  
e^WqJ7j  
return SKIP_BODY; O! (85rp/  
cNeiD@t3V&  
} nX 8B;*p6b  
SwJHgZ&  
public int doEndTag() )f[C[Rd  
D-D #`  
{ `u=oeM :  
N'a?wBBR  
return EVAL_PAGE; oX{@'B  
g-|Kyhr?=  
} z L8J`W  
B G5X_s0/  
} )w3 ,   
Rdj8 *f  
-)>(8f  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 J@gm@ jLc  
1 yJ75/  
<body-content>empty</body-content> T+(M8 qb  
R. O  
$r):d  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 {N "*olx  
;*nh=w  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, ]I8]mUiUH  
t@6w$5:}  
<logic:present parameter=”Clear”> x ~wNO/  
Q7L)f71i  
与此相应,此tag处理类应有如下方法和定义: *!i,?vn  
<o ~t$TH  
p%tE v  
protected String parameter = null; J}:&eS  
e~3]/BL  
public String getParameter() `|&\e_"DE  
y2GQN:X  
{ Bj; [  
p?}f|mQS)  
return this.parameter; /9P^{ OZ;y  
)sRN!~  
} AjG)1  
ijE<spG  
public void setParameter(String parameter) z/)$D  
)4@M`8  
{ JR] )xPI`  
PL9<*.U"=  
this.parameter = parameter; ES^NBI j5P  
(Z5q&#f  
} 93 [rL+l.Y  
JIVo=5c}  
=n)JJS94  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 _cR6ik zW(  
" 98/HzR  
Attribute元素 VIb;96$Or  
JvKO $^  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 6euR'd^Qi  
fDL3:%D  
<attribute> 4tbw*H5!5  
MgHOj   
<name>attr1</name> uPI v/&HA  
3gC\{y!8  
<required>true|false|yes|no</required> 0Wjd-rzc,  
{F<)z% ^  
<rtexprvalue>true|false|yes|no</rtexprvalue> ,m2A p\l  
tX@ 0:RX%  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> f$Gr`d  
C_6GOpl  
</attribute> r;c' NqP  
8FAT(f//.  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 i:C.8hmAE  
NKRaQ r  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 &\JK%X.Jlt  
yb[{aL^4%  
<tag> lq;  
,.~ W  
<name>present</name> $5ZR [\$  
uCY(:;[<  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> rdXCWK$E  
7h(HG?2Y  
<body-content>JSP</body-content> n/ui<&(  
i6-wf Gs;  
<E D8"~_  
,O$Z,J4VL  
<attribute> ^wvH,>Yo  
b{Z^)u2X  
<name>parameter</name> ev~dsk6k  
6"BtfQ")  
<required>false</required> I8 %d;G~  
C4&U:y<ju  
<rtexprvalue>true</rtexprvalue> qFV;n6&V  
}v_p gatC  
</attribute> \;nD)<)J  
O<}ep)mr  
qFvg}}^y  
K<$wz/\  
</tag> L!CX &  
8 m%>:}o  
 !7 ei1  
属性元素的校验 Y}AmX  
)2iM<-uB  
^+(A&PyP?  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 \[Sm2/9v  
l=oN X"l=  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 y #hga5  
i_j9/k  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 kvMk:.  
J!21`M-Ue  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: u Y?/B~  
o0,UXBx  
<attribute> 'Qm` A=  
W&fW5af9  
<name>attr1</name> vjexx_fq  
D6&mf2'u  
<required>true</required> tc+GR?-7W  
" #mXsp-ut  
<rtexprvalue>true</rtexprvalue> 3::3r}g  
P<j4\zJ  
</attribute> W0+gfg  
Hs:4I  
?z\q Mu  
这个定义说明了attr1能在运行期间被赋值。 %8}WX@SB  
\_*?R,$3Y,  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 %JP&ox|^&  
dWzDSlP&  
v`[Tl  
Public class TwaTEI extends TagExtraInfo N<#S3B?.  
^4xlZouCb  
{ p56KS5duI.  
5 {T9*  
public boolean isValid(Tagdata data) fZka%[B  
SQO>}#qm  
{ b xk'a,!S  
d-6sC@PB  
Object o = data.getAttribute(“attr1”); <GL}1W"Ay  
6=Y3(#Ddt  
If(o != null && o != TagData.REQUEST_TIME_VALUE) 8]cv&d1f  
rd&*j^?  
{ 1S*8v 7  
F]K$u <U  
if( ( (String)o).toLowerCase().equals(“true”) || W%Y.SP$Y  
.c=$ bQ>^  
((String)o).toLowerCase().equals(“false”) ) _Ewy^;S%L  
Pi&fwGL  
return true; @1pW!AdN  
Dg9--wI}I9  
else ^D ]7pe  
)V[w:=*  
return false; 2- Npw%;  
fd!pM4"0  
} x*,q Rew  
n&2=6$*,k  
else 9}%~w(P  
*@bg/S K%  
return true; _g^K$+F'}  
E>l#0Zw  
} #K<=xP  
G<">/_jn  
} E i\J9zt  
Y5h)l<P>B  
K^]?@oHO  
带body的tag FT3,k&i  
.v #0cQX+.  
dN$D6*  
tag处理类 4t +/  
=#POMK".6  
k2_6<v Z  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 0M/\bE G(_  
+s+PnZ%0V  
Tag处理类不与body交互 gNEzlx8A  
H649J)v+m  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 evndw>  
t(z(-G|&  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 T0*TTB&b  
@ 2%.>0s.  
Tag处理类与body交互 6S! lD=  
m5'__<  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 , IMT '*  
EvH(Po h  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 7b7%(  
'$kS]U  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 tvj'{W  
TeGLAt  
doInitBody 方法 6bRQL}[  
k<j)?_=`  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 T|BY00Sz`  
N) V7yo?  
doAfterBody方法 Y bn=Gy  
VxPTh\O*[  
此方法在body内容已被计算后进行调用。 Y00i{/a 8  
<@x+N%C  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 RBv=  
mk[d7Yt{O  
release 方法 iaa (ce  
\fM!^  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 L!+[]tB  
)K\k6HC.  
6&OonYsP  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 uc"[qT(X  
0()9vTY+  
Ro3I/NI>  
Public class QueryTag extends BodyTagSupport HhQPgjZ/  
x w?9W4<  
{ Op$J"R  
*]>OCGsr  
public int doAfterBody() throws JspTagException [hv3o0".  
n_xQSVI0F  
{ -%/,j)VKD  
<-oRhi4  
BodyContent bc = getBodyContent(); (W}i287  
!+*?pq  
//将body的内容以字符串的格式提取出来 +poIgjq0  
*{;A\sL  
String query = bc.getString(); @h7GTA \  
!3X%5=#L4  
//清除body _>?8eC]4a  
("P mB?20  
bc.clearBody(); u UVV>An  
v\?\(Y55Y  
try{ c;t(j'k`  
(?&_6B.*  
Statement stmt = connection.createStatement(); ! 4^L $  
%BYlbEx  
Result result = stmt.executeQuery(query); yS.fe[  
lA^Kh  
}catch(SQLException e){ Kj<<&_B.H  
{'wU&!  
throw new JspTagException(“queryTag: “ + e.getMessage() ); 1^H<+0  
7N~qg 7&  
return SKIP_BODY; #35S7G^@`  
BI]ut |Qw  
} ~cg+BAfu  
W*/s4 N  
} n`I jG  
nO.+&kA  
;~1/eF  
body-content元素 @Ozf}}#  
C5lD Hw[CX  
^J5V!i$  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: ~3-YxCn%  
oj4)7{  
<body-content>JSP|tagdependent</body-content> }HQT@&=  
Q]?J%P.  
U-]PWt?C{  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 %},S#5L3  
zH\;pmWiN9  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 j n&9<"W  
A@Yi{&D_Q]  
pvwnza1  
用tags定义脚本变量 @okm@6J*X  
4z 3$  
I\4`90uBN  
tag处理类 Mp @(/  
,E8>:-boL  
Y"\T*lKa  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 3<' Q`H>  
3L!&~'.Ro  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 N n-6/]d#  
mBgx17K/-_  
对象的生存周期(scope)如下表: Y  X{  
[Oy2&C  
对象的生存周期表 AFhG{G'W  
` Ehgn?6'  
名字 }Yl8Q>t  
可访问范围 "s6_lhu=E7  
生存周期 bg3jo1J  
7R`ZTfD  
page 9kg>)ty@  
当前页面 +5}T!r  
一直有效,除非页面向客户提交响应或重定向到一个新页面 md +`#-D\O  
czsoD) N  
request SFPIr0 u  
当前页面或当前页面重定向到的页面 ;@-5lCvC(+  
一直有效,除非页面向客户提交响应  !+VN   
!J?=nSu  
session OsSiBb,W79  
当前页面或在同一浏览器窗口中的页面 >`V|`Zi ?  
一直有效,除非关闭当前浏览器、超时、网络故障 A kQFb2|ir  
?}Ptb&Vk(  
application F1[ [fH  
整个web应用程序的所有请求 3\l9Sf=M|  
一直有效,除非发生网络故障、服务器故障 ]~ 8N  
<.B > LU  
提供关于脚本变量的信息 mt]YY<l  
xcRrI|?eC  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: Jz8#88cY  
j\L$dPZ  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> #w?%&,Kp  
(']z\4o  
<font color=”red” size=”+2” > exN#!& ;  
oW1olmpp=  
<%= messages.getString(“CartRemoved”) %> D~?*Xv]s ~  
n[S*gX0  
<strong><jsp:getProperty name=”book” property=”title” /></strong> 7XC}C+  
pQ`L=#WM  
</font> ^p%+rB.j[  
jP6G.aiO  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: tfIBsw.  
&MLhCekY  
· 脚本变量名称 =<uz'\Ytv%  
q'-l; V|  
· 脚本变量所属的类 jN{xpd  
Jj!tRZT  
· 此脚本变量是否引用了一个新的或已存在的对象 5:3$VWLa <  
soK_l|z:J  
· 此脚本变量的有效性 tJfN6  
bD[W~ku  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 \ bmboNe  
JM9Q]#'t  
Variable元素 -@?>nLQb  
bN %MT#X  
Variable元素有如下子元素: ) G&3V  
e7AI&5Eg{  
· name-given ?D?D 给出的名字,是一个常量 JV{!Ukuyp+  
t7%Bv+Uo  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 c)~|#v  
X \ZUt >  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: _^$b$4)  
%ycT}Lu  
· variable-class?D?D变量的类型,缺省为java.lang.String。 ptL}F~  
'QS~<^-j"  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 APm[)vw#f  
0#GwhB  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: U.} =j'Us+  
yAkN2  
脚本变量的有效范围 ?^GsR[-x  
-+Ji~;b  
5. UgJ/  
有效性 #`wfl9tj  
方法 R.$Y1=U6  
^Iq.0E9_  
NESTED Nxk'!:  
在tag标签的开始和结束之间 .y/?~+N^  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 j-\u_#kx%  
*3oQS"8  
AT_BEGIN oQB1fs  
从tag标签的开始一直到页面结束 'B:De"_(N  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 Q%d[ U4@  
*#9kFz-  
AT_END Ykq }9  
从tag标签的结束一直到页面结束 $)a5;--W  
在doEndTag中调用 ,fL e%RP  
}i~j"m  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: 9jBr868  
m5g: Q  
<tag> oK[,xqyA  
e+aQ$1^t  
<variable> FJ. :*K[  
jH/%Z5iu  
<name-from-attribute>id</name-from-attribute> gvt4'kp  
0kEq|k9  
<variable-class>database.BookDetails</variable-class> skArocs  
RtEkd_2  
<declare>true</declare> l'R`XGT  
IMEoov-x  
<scope>AT_BEGIN</scope> +T;qvx6  
;:1mv  
</variable> OPh@H.)^  
Um&@ 0C+L  
</tag> 2l%iXK[  
(acRYv(  
额外tag信息类 _~<TAFBr  
uf3 gVS_h=  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: D]_\i[x  
Ps-d#~4U;  
· 变量名 _CT|5wQF<  
wpmtv325  
· 变量所属类名 |Q+v6r(<zZ  
yU`IyaazZ  
· 此变量是否引用了一个新对象 (#BA{9T,^  
6?~pjMV  
· 此变量的有效范围 N|d@B{a(  
%%u4( '=  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 LRgk9*@,  
4K% YS  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: "fwuvT 1  
pc>R|~J{2  
;^]F~x}  
public class DefineTei extends TagExtraInfo 1Qkuxw  
3g?T,| 2K  
{ 8ttw!x69)_  
Ric$Xmu  
public VariableInfo[] getVariableInfo(TagData data) #SOe &W5  
}])f^  
{ OMNdvrE*=O  
2/WXdo  
String type = data.getAttributeString(“type”); ? 'nMZ  
A O]e^Q  
If( type == null) Y6Q6--P  
_E7eJSM.  
type = “java.lang.Object”; @n3PCH6:Ao  
}%|OnEk"  
return new VariableInfo[] { U[u6UG  
(~4AG \  
new VariableInfo(data.getAttributeString(“id”), ~*Wb MA  
q3t@)+l>*  
type, X*&r/=  
`^x^= og'  
true, M,P_xkLp  
&v88x s  
VariableInfo.AT_BEGIN) b1"wQM9  
AmFHn  
}; +ZO*~.zZ  
8iB}a\]B  
} uNDkK o<M  
Z )I4U  
} #B[>\D"*  
a1&^P1.  
hCrgN?M z  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: *G38N]|u6  
<tei-class> JJr<cZ4]  
org.apache.struts.taglib.bean.DefineTagTei O5w\oDhMb  
</tei-class> k5/}S@F8  
t!$/r]XM h  
:yeTzIz]  
具有协作关系的tag ?T&D@Ohsx  
sh RvwE[  
oc3/ IWII  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 ]0O$2j_7  
ZBWe,Xvq  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 hB4.tMgZ  
bBf+z7iyc  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 |m% &Qb  
g}7B0 yo  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。  qn .  
SE1 tlP  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 c4|.!AQ>  
rXMv&]Ag  
m[XN,IE#u  
public class QueryTag extends BodyTagSupport Phczf  
f.{0P-Np  
{ ( KrIMZ  
ueOvBFgZ  
private String connectionId; = zSrre  
Ra5cfkH;  
public int doStartTag() throws JspException WF]:?WE%  
\`^jl  
{ +y2*[  
@QofsWC  
String cid = getConnection(); Q] HRg4r  
?bEYvHAzg  
if(cid != null) L r,$98Dy  
w@4+&v>O  
{ @9L9c  
k dqH36&<  
//存在一个connection id,使用它。 @ NF8?>!  
KRQ/wuv  
connection = (Connection) pageContext.getAttribute(cid); |cacMgly  
D'X'h}+2  
} y\:2Re/*Jt  
{XAKf_Cg  
else H0S7k`.  
VQCPgs  
{ x+&&[>-P  
Jg:'gF]jt  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, q&.!*rPD  
6m]L{ buP  
ConnectionTag.class); J';tpr  
>Y:ouN~<  
if(ancestorTag == null) 8CL05:&  
Ce:kMkJ  
{ 7D,+1>5^Ne  
wsARH>Vz  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); T"z!S0I  
tPUQ"S  
} Ldu!uihx  
N\u-8nE5  
connection = ancestorTag.getConnection(); _VJb i,V  
cb+!H>+  
} R#t~i&v/  
psMagzr&)e  
} 4xlsdq8`t  
P_;oSN|>  
} LZeR .8XM>  
;rFa I^  
srC jq  
1yo@CaW[\  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: 1Dbe0u  
t :_7 O7  
'K`)q6m  
<tt:connection id=”con01” ...> ... </tt:connection> #X)s=Y&5!T  
V3-LVgM%  
<tt:query id=”balances” connection=”con01” > Djzb#M'm  
1osI~oNZ  
SELECT account, balance FROM acct_table @ZmpcoDI  
3|A"CU/z@  
where customer_num = <%= request.getCustno() %> 6 3HxQH  
0YS*=J"7z  
</tt:query> q*T+8 O  
cc>h=%s`  
-{O2Nv-]]  
6Hz=VhQrN  
-*WD.|k  
<tt:connection ...> m'S-h'a  
BH}u\K  
<x:query id=”balances”> N\p3*#M  
Z d%*,\`S  
SELECT account, balance FROM acct_table NzEuiI}  
}b-?Dm_H  
where customer_num = <%= request.getCustno() %> :{sX8U%  
Mfgd;FsX#  
</x:query> 7S Qu  
/A>/]2(  
</tt:connection> Z/0M9 Q%  
>Nov9<p  
R(:q^?  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: )a.U|[:y[+  
.8,lhcpY  
<tag> !,\]> c  
N=wB1gJ  
... }SYvGp{J,  
=IUTU4!]  
<attribute> V'9 k;SF  
6PTD%Rf\  
<name>connection</name> ,0~'#x>  
|OC6yN *P)  
<required>false</required> wk3yz6V2  
)qKfTt N`  
</attribute> n>@(gDq  
L 0|u^J  
</tag>
描述
快速回复

您目前还是游客,请 登录注册
欢迎提供真实交流,考虑发帖者的感受
认证码:
验证问题:
3+5=?,请输入中文答案:八 正确答案:八