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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! .wtYost v  
bF +d_t  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 .ffr2\'*  
z34+1d  
在这篇文章中,我们主要讨论: li} >xDSQ4  
*r6v9  
· 什么是自定义tag标签? ZalL}?E ?  
J%E0Wd  
· 怎么使用tag标签? clIn}wQ  
X{h[    
o 声明要使用的tag库 I7<UC{Ny  
;N _ %O  
o 找到与之对应的tag处理类 9HlM0qE5b  
M IUB]  
o tag标签的类型 ;;EFiaA  
owO &[D/  
· 自定义tag标签 p\]rxtm  
1}CJ&  
o tag处理类 SNHAL F  
P>|sCF  
o tag库描述 ~k ]$J|}za  
8,B#W#*{  
o tag标签示例 G/KTF2wl7  
~BXy)IB6  
o 带属性的tag 2nSz0 .  
@,pn/[  
o 带body的tag H\|H]:CE  
Jb8%A@Z+  
o 定义了脚本变量的tag Q:Y`^jP   
"m}N hoD4  
o 具有协作关系的tag m`@~ZIa?>B  
',6d0>4 *  
· 自定义tag标签 Ye[Fu/0  
SQJ4}w>i  
o 一个迭代tag的例子 #*}cc  
rFto1m  
o 一个模板tag库 miY=xwK&  
!Jaj2mS.N  
o tag处理类到底是怎样被调用的? (~:ip)v  
.5#+)] l  
GGGz7_s ?  
什么是自定义的tag? }&EdA;/o_  
*o=( w5   
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 2j[; M-3  
2(Nf$?U @0  
自定义tag标签有很多特色,诸如: ;^8X(R  
,B,0o*qc{K  
· 可以在JSP页面中自定义tag标签的属性 BR~+CBH  
asYUb&Hz88  
· 访问JSP页面中的所有对象 _^F%$K6  
tLGNYW!K  
· 可以动态地修改页面输出 wUzMB ]w  
bX+"G}CRP  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 %D+NrL(  
XC,by&nY<y  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 %lGg}9k'  
TnPx.mwK\  
4'L.I%#tZ  
使用tag标签 <!~NG3KW[>  
&3YXDNm  
rmhL|! Y  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 ZV~9{E8  
d-#yN:}0  
要使用tag标签,JSP程序员必须做2件事: &t74T"(d  
N<aMUVm  
· 声明此tag标签的tag库 (w/lZt  
zUJPINDb  
· 实现此tag标签 l'"Ici#7Ls  
xx[l#+:c  
声明tag标签所在的tag库 bm(.(0MI  
K1-y[pS]E  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) bHmn0fZ9  
`q?@ Ob&  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> sq}uq![?M  
]hY4 MS  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 WNiM&iU  
W%K=N-kE_  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 ?qczMck_  
j$khGR!  
以下taglib指示符直接引用一个TLD: f,8PPJ:,  
c.;<+dYsm*  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> ob7hNo#  
/SJI ~f+$  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: ;)!);q+  
4,7W*mr3(  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> `FIS2sl/  
<f@ A\  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: -K iI&Q  
O[HBw~  
<taglib> 7u[$  
7^Y`'~Y^  
<taglib-uri>/tutorial-template</taglib-uri> }j|YX&`p  
DMd&9EsRG  
<taglib-location> pt9fOih[  
8|IlJiJ~v  
/WEB-INF/tutorial-template.tld (l:LG"sy\  
\Oa11c`6  
</taglib-location> .\|}5J9W  
{tF)%>\#  
</taglib> e&F=w`F\  
vA0f4W 8+  
Rc`zt7hbJ  
实现此tag标签 z6bIv }  
#|acRZ9 }  
-o`|A767  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 d{RMX<;G  
1IZTo!xi  
BPC>  
tag标签类型 n,%/cUl  
jg=}l1M"  
UJrN+RtL  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): `:EU~4s\  
IFF3gh42.  
<tt:tag> RJA#cv~f  
WlnS.P\+E  
body )W3kBDD  
"l 1z@  
</tt:tag> C 4hvk'=  
e2M jV8Bs  
QhmOO-Z?  
一个不带body的tag标签如下: Eilo;-El  
qJEtB;J'  
<tt:tag /> ~DUOL ~E  
`Bv, :i  
')~[J$qz  
简单的tag标签 ^TCfj^FP  
-n`2>L1  
一个没有body和属性的tag标签如下: .7MLgC;  
NLO&.Q]#  
<tt:simple /> MGSD;Lgn  
0`"DYJ}d  
RV, cQ K  
带属性的tag标签 OJPi*i5*  
c:_dW;MJ0  
;F\sMf{  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 >&uR=Yd  
>I;J!{  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: vK8!V7o~h%  
z]R)Bh  
<loglic:present parameter = “Clear”> uZ(,7>0  
-Oc  
而另一个标签logic:iterate是用表达式来给属性赋值: NUGiDJ+[  
&3bhK5P  
<logci:iterate collection=”<%= bookDB.getBooks() %>” }n$I #G}\/  
84M*)cKR~  
id=”book” type=”database.BookDetails”> WOuk> /  
F48W8'un  
PZO8< d  
带body的tag标签 a #Pr)H  
o.KE=zp&z  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 m[6c{$A/w  
o9AwW  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: ?/^x)Nm  
C+Pw  
<logic:present parameter=”Clear”> lsRW.h,  
S]}W+BF3  
<% cart.clear(); %> 2U`g[1  
`NARJ9M   
<font color=”#ff0000” size=”+2”><strong> =1Tn~)^O  
;>h:VnV(>(  
你选择了清除购物车! J2Z? }5>  
2M3C 5Fu  
</strong></font> C?lZu\L  
uy oEMT#u  
</logic:present> DjQgF=;  
RS /*Dp^  
=!P$[pN2  
到底是用属性还是用body来传递信息? @1iH4RE*  
\6K1Z!*;  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 L|K^w *\C  
,3FG' q2  
5r(Y,m"?  
定义脚本变量的tag标签 &L4>w.b"N  
H4JwgQ  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: yDXW#q  
IltU6=]"l  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> W,sPg\G 3  
UWg+7RL  
<% tx.begin(); %> l. 0|>gj`0  
x]<0Kq9K  
... L<H6AzR+  
EGJrnz8  
s.9_/cFWB  
具有协作关系的tag标签 ^9A,j} >o-  
V"R,omh  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 cHk ?$  
c$52b4=a  
<tt:tag1 attr1=”obj1” value1=”value” /> cy!;;bB  
FG6mh,C!  
<tt:tag2 attr1=”obj1” /> ipn 0WQG  
#x[3@zP.  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 '?dT<w=Y&  
u[?M{E/HU  
<tt:outerTag> mZ}C)&,m2  
[V_\SQV0  
<tt:innerTag /> +DA ,|~k_  
sRDxa5<MD  
</tt:outerTag> 4&+lc*  
`/L D:R  
TwLQ;Q  
Tag处理类 Vf] ;hm  
d+158qQOh]  
2r>I,TNHl  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 )w'GnUqWz  
M5<c HE  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 .[8g6:>  
%r >Y)@$Vt  
下表说明不同类型的tag所需要不同的处理过程: Y[Kpd[)[v  
8$C?j\J|*  
Tag处理类的方法 mv\S1[<T  
9  7Mi{Zz  
Tag标签类型 1JWo~E'  
所调用的方法 ^P}c0}^  
NG?-dkD  
基本标签 bbxo!K m"  
doStartTag, doEndTag, release J\c\Ar :  
gzeTBlXg  
带属性的标签 Lm"zW>v  
doStartTag, doEndTag, set/getAttribute1...N, release (YKkJ  
 '  
带内容的标签  WDq~mi  
doStartTag, doEndTag, release QTT2P(Pz  
{axMS yp;  
带内容的标签,且内容重复循环 G+zIh}9  
doStartTag, doAfterBody, doEndTag, release l~c# X3E  
3KN>t)A#  
带内容的标签,且内容与JSP交互 g]Fm%iy  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release QDpzIjJj  
%% A==_b  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 *e}1KcJ  
P2>Y0"bY  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 \YrvH  
3~6,fTMz{  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 N,~"8YSo  
%"g; K  
3?:?dy(3z  
Tag库描述(简称TLD) <`WtP+`  
v!77dj 6I  
85 <%L:EC  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 S1G3xY$0  
yOr5kWqX  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 >a$b4 pvh  
,J ZM%f  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: 2X!!RS>qg  
I^itlQ  
<?xml version="1.0" encoding="ISO-8859-1" ?> BOf)27)  
IM$I=5y e  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> T,SCK^  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: PuoN<9 #  
ZKco  
_ pKWDMB$z  
<taglib>的子元素 m. DC  
JDj^7\`  
Element $3D#U^7i  
Description Bn?MlG;aA  
AB")aX2% E  
tlib-version (3fU2{sm  
Tag库的版本 9G"-~C"e3  
z1`z k0  
jsp-version )*I%rN8b   
Tag库所需要的jsp的版本 19# A7  
XbMAcgS  
short-name 8@J5tFJ&%  
助记符,tag的一个别名(可选) 5_~QS  
rtY4 B~_  
uri ]/y69ou  
用于确定一个唯一的tag库 :MbD=sX  
k:k!4   
display-name tF=Y3W+L  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) ?=a,  
+KKx\m*  
small-icon SF?s^  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) oq3{q  
Ad]oM]  
large-icon k}r)I.Lp  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) 9HJA:k*k|  
8w]>SEGFs  
description g{%2*{;i  
对tag库的描述(可选) _rjLCvv-  
r]'Q5l4j6"  
listener I!uGI  
参见下面listener元素 1?5UVv_F  
n^7m^1to  
tag W99Hq1W;r  
参见下面tag 元素 <;.->73E  
Isna KcLM  
Listener元素 %zA$+eT  
Pu7cL  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 jXALN  
LJII7<k  
Tag元素 8 y+Nl&"V  
;V"(! 'd  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 LwL\CE_6+  
b/g"ws_  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: Jb4A!g5C  
#m<<]L(o8W  
Tag元素的子元素 ^&-H"jF  
eg vgi?y  
元素名称 7TN94@kCF  
描述 sBfPhBT|  
L_4Zx sIv  
name J)xc mK  
独一无二的元素名 ~0~f  
d3|oKP6  
tag-class 2AZ)|dM'`  
Tag标签对应的tag处理类 u/8urxp y  
=P.m5e<  
tei-class YN@ 4.&RP  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) g~AO KHUP  
z nc'  
body-content h&4f9HhS=  
Tag标签body的类型 5V{zdS=  
0u'qu2mV  
display-name 7>`VZ?  
被可视化工具(诸如Jbuilder)用来显示的名称(可选)  MXj7Z3  
u< ,c  
small-icon +s'qcC  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) Q< q&a8~  
uM^eoh_  
large-icon Evn=3Tw  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) CK+GD "Z$  
! awfxH0  
description 6SIk,Isy8  
此tag标签的描述 8C{mV^cn~  
=+qtk(p  
variable V~uH)IMkh7  
提供脚本变量的信息(同tei-class)(可选) ]$>O--  
i: ZL0nH-  
attribute jB17]OCN  
Tag标签的属性名 H -sJt:  
1.Ximom  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 8SGFzb! h  
WYb\vm =r  
v{}i`|~J  
简单的tag ZO2$Aan  
+hIStA  
x)SW1U3TVx  
tag处理类 b$f@.L  
Qw{LD+r(  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 bnz2\C9^  
]S6`",+)<f  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: dT%$"sj5  
DUk&`BSJ  
&_^t$To  
public SimpleTag extends TagSupport W(oJ{R&m{  
?Sq?f?  
{ <J`",h  
3+_ .I{  
public int doStartTag() throws JspException cGhnI&  
,{HxX0  
{ @,<@y>m7  
_JZw d9K  
try{ W -Yv0n3  
g{zvks~it  
pageContext.getOut().print(“Hello.”); Vs-])Q?7J  
] {r*Z6bs  
}catch(Exception e){ |=^p`CT  
xm }9(EJ  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); b3G4cO;t;  
iINd*eXb^  
} Ny@CP}  
I6x  
return SKIP_BODY; HWJ(O/N  
lw4#xH-?  
}  fWx %?J  
CfguL@tR.  
public int doEndTag() :esHtkyML  
d;3/Vr$t=  
{ 6q[|U_3I@  
(cX;a/BR  
return EVAL_PAGE; k !S0-/ h  
2nW:|*:/p6  
} O\h*?, )  
/Q4TQ\:  
} [*<F   
d%:B,bck  
2NHkK_B1P  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 M^c`j#NQ  
U{vt9t  
<body-content>empty</body-content> g]IRv(gDh  
la7VeFT  
}Fd4; ]  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 yrp5\k*{y  
'Vwsbm tY  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, Zj@k3y  
KMO(f!?  
<logic:present parameter=”Clear”> n[~kcF  
zn| S3c  
与此相应,此tag处理类应有如下方法和定义: gnjh=anVX1  
q\2q3}n  
dW K; h  
protected String parameter = null; J#h2~Hz!  
= GN1l[X  
public String getParameter() {E6M_qZ  
xbbQ)sH&m  
{ y0!-].5UH  
d5zv8?|X+  
return this.parameter; 4e6x1`Y{xB  
C-i9F%..  
} .lclW0*  
oy8L{8?  
public void setParameter(String parameter) C|#GODA  
42*y27Dtm  
{ :ud<"I]:  
@>>8CU^~  
this.parameter = parameter; ;VhilWaF-  
5*M3sN  
} =:)p\{B  
}HO3D.HE^  
C`qo  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 #&fi[|%X$  
b.h:~ATgN  
Attribute元素 Gjhpi5?%8  
L5(7;  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 RO>3U2  
uY{zZ4iw  
<attribute> }BTK+Tk8  
Un [olp  
<name>attr1</name> vD,ZEKAN  
I4[sf  
<required>true|false|yes|no</required> ]q#w97BxiJ  
1(S0hm[ov  
<rtexprvalue>true|false|yes|no</rtexprvalue> 9|kc$+(+6  
V*xo3hU  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> Hz?C9q3BX  
\<cs:C\h7  
</attribute> &hTe-Es  
.[%^~q7  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 UH8q:jOi  
S511}KPbm/  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 K]~! =j)v  
9'1XZpM1  
<tag> ,]A|z ~q  
5Q)hl.<{o7  
<name>present</name> @1+gY4g  
_/FpmnaY  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> z|KQiLza  
}XOTK^YA  
<body-content>JSP</body-content> C)x>/Qr~  
47S1mxur  
… EC`!&Yp+  
7T\LYDT  
<attribute> gu~JB  
rM?O2n  
<name>parameter</name> :6}Zo  
Q9Tt3h2ga  
<required>false</required> = aO1uC|6C  
kn$2_I9  
<rtexprvalue>true</rtexprvalue> .|$:%"O&X  
Fe r&X  
</attribute> =1kE2u  
Hnq$d6F  
… A_8UPGh8  
P\jnht  
</tag> z%FBHj  
Z<P?P`  
Ch] `@(l  
属性元素的校验 Z-md$=+}w  
~J~@mE2ks  
xE$>;30b_  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 L=7Y~aL=  
y cT@ D/  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 L<7KmN4VX  
-0I]Sm;$  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 Rcn6puZt  
`, lnBP3D"  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: 3]46qk '  
^ gy"$F3{`  
<attribute> 6dH> 0l  
(+(YQ2  
<name>attr1</name> .eBo:4T!d  
sKg IKYG}T  
<required>true</required> Oax6_kmOj  
pr=f6~Z-y  
<rtexprvalue>true</rtexprvalue> ;7:_:o[.  
>'eY/>n{  
</attribute> j1 Ns|oph1  
bjL8Wpk  
a)o-6  
这个定义说明了attr1能在运行期间被赋值。 q0m> NA   
b] EC+.  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 {)CN.z:O  
]QJ N` ;b0  
ydZS^BqG  
Public class TwaTEI extends TagExtraInfo iQT$#"m n  
n<)gS7  
{  Zra P\?  
pu"m(9  
public boolean isValid(Tagdata data) U } K]W>Z  
G?,b51"  
{ Ye=c;0V(w  
?hFG+`"W  
Object o = data.getAttribute(“attr1”); +A;AX.mr  
FQlYCb  
If(o != null && o != TagData.REQUEST_TIME_VALUE) J<9;Ix8R  
)yTBtYw3  
{ GG=R!+p2  
X/8TRiTFv  
if( ( (String)o).toLowerCase().equals(“true”) || 2Wx~+@1y  
 Qi;62M  
((String)o).toLowerCase().equals(“false”) ) Ya*<me>`  
-d*zgP  
return true; nb30<h  
0en Bq>vr  
else _xmS$z)TO  
i-YSt5iq  
return false; :Z R5<Y>  
U =i=E}'  
} H %bXx-  
(i.7\$4  
else I1)t1%6"vJ  
F*4zC@;  
return true; Ivx]DXR|  
}2]m]D@%7  
} ,]LsX"u  
&y+)xe:&S  
} r.ib"W#4  
U)Jwo O  
J=?P`\h  
带body的tag xt zjFfq  
@Rw]boC  
L!LhH  
tag处理类 K} ) w  
GlOSCJZ  
KBg5 _+l  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 QFg{.F?3q>  
<HfmNhI85(  
Tag处理类不与body交互 <-(n48  
\sEH)$R'  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 >mW*K _~  
e6i m_ Tk  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 s= bP@[Gj  
:\"V5  
Tag处理类与body交互 ,Zva^5  
\"| 7o8  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 vUR@P  -  
wv.HPmq  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 TMG|"|  
8D&yFal  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 SH5a&OVZhn  
1~ZFkcV_C  
doInitBody 方法 yt {?+|tXU  
)1E#'v12 "  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 Ca}V5O  
l_i&8*=Px  
doAfterBody方法 J,D^fVIw  
QIC? `hk1  
此方法在body内容已被计算后进行调用。 fA"9eUu  
^u+#x2$Mg  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 pC/13|I  
aXgngw q  
release 方法 7U2?in}?Qi  
 _W  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 oqa8v6yG'  
0]Qk*u<  
y7T<Auue`  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 NI85|*h  
:I(d-,C  
sEHA?UP$<F  
Public class QueryTag extends BodyTagSupport X!|K 4Z!k  
b#W(&b^q  
{ x0||'0I0  
-J;;6aA  
public int doAfterBody() throws JspTagException /wPW2<|"X.  
7{Zs"d{s  
{ !7n`-#)  
6B!v;93U  
BodyContent bc = getBodyContent(); & R,QJ4L  
6$&%z Eh  
//将body的内容以字符串的格式提取出来 -u^f;4|u  
Y-.aSc53  
String query = bc.getString(); H+5S )r  
4O7 {a  
//清除body YM&i  
rCd*'Qg  
bc.clearBody(); f>[{1M]n\  
ddwokXx (  
try{ (g3DI*Z  
+ctJV>  
Statement stmt = connection.createStatement(); !,OY{='  
Sr>5V  
Result result = stmt.executeQuery(query); U"535<mR  
]92=PA>75  
}catch(SQLException e){ >rY^Un{Z  
i?D)XXB85  
throw new JspTagException(“queryTag: “ + e.getMessage() ); |w.h97fj  
l}~9xa}:D|  
return SKIP_BODY; 42=/$V  
SedVp cb+  
} +R',$YzD  
v9 8s78  
} F./P,hhN9  
"h:#'y$V  
hu 5o{8[  
body-content元素 ~_|CXPiQ8  
oA+'9/UY  
ut^6UdJ+`  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: scPvuHzl  
a)' P/P  
<body-content>JSP|tagdependent</body-content> kd OIL2T  
N>IkK*v  
BeFXC5-qat  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 \t]_UNGyW  
x$) E^|A+  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 +&[X7r<  
Z@i,9 a  
LY2QKjgP  
用tags定义脚本变量 [6CWgQ%Ue  
CcZM0  
@c=bH>Oz  
tag处理类 Yb?(Q %  
bd&Nf2  
SN;_.46k  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 ,S?M;n?z_  
]Y3s5#n  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 jZ0/@zOf  
x\!vr.  
对象的生存周期(scope)如下表: =a6e*f  
A\v]ZN4  
对象的生存周期表 Hv</Xam  
n9Ktn}  
名字 u-=VrHff^*  
可访问范围 J+=?taZ  
生存周期 K1t>5zm  
V U~r~  
page COcS w  
当前页面 QG 1vP.K  
一直有效,除非页面向客户提交响应或重定向到一个新页面 g2 tM!IRQ  
;FnS=Z  
request OE2r2ad  
当前页面或当前页面重定向到的页面 pE 6r7  
一直有效,除非页面向客户提交响应 @;Xa&*   
cG!dMab(  
session c3N,P<#  
当前页面或在同一浏览器窗口中的页面 ~8EzK_c  
一直有效,除非关闭当前浏览器、超时、网络故障 o)M<^b3KO  
Wb;D9Z  
application =QhK|C!$A  
整个web应用程序的所有请求 V82hk0*j  
一直有效,除非发生网络故障、服务器故障 (/C 8\}Ox  
AQ)J|i  
提供关于脚本变量的信息 #0c;2}D  
lI;ACF^  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: zd3^k<  
~N8$abQJV  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> m{by%  
YXDuhrs}  
<font color=”red” size=”+2” > ycrM8Mu 3  
MI>_wG5P@  
<%= messages.getString(“CartRemoved”) %> Hx NoV.q  
!Aw.)<teW  
<strong><jsp:getProperty name=”book” property=”title” /></strong> R T/)<RT9  
]%+T+ zg(Y  
</font> ddw^oU  
!BN@cc[%  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: J#?z/3v(  
8b< 'jft  
· 脚本变量名称 !fG}<6&i  
.QB)Y* z  
· 脚本变量所属的类 c>BDw<  
!"dAwG?S  
· 此脚本变量是否引用了一个新的或已存在的对象 Q: j)F|uhc  
O|*-J  
· 此脚本变量的有效性 WU~L#Ih.V  
%jxeh.B3B  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 =$#=w?~%  
rV B\\  
Variable元素 N;* wd<  
dg4q+  
Variable元素有如下子元素: FBS]U$1  
9/dADJe0b  
· name-given ?D?D 给出的名字,是一个常量  e,T^8_>  
Uwg*kJ3H  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 &[kFl\  
%wN*Hu~E  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: 5-POY ug  
CM;B{*En  
· variable-class?D?D变量的类型,缺省为java.lang.String。 ) h=[7}|  
cnj32H^+  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 =21m|8c  
K$5mDScoJ  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: [!U! Z'i  
N_?15R7h  
脚本变量的有效范围 >`I%^+ z  
HH|N~pBJB  
值 5?8jj  
有效性 o`{^ptu1q  
方法 apWv+A  
v>sjS3  
NESTED O#Ho08*Xn  
在tag标签的开始和结束之间 8B3C[?  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 O8/r-?4.  
YA~`R~9d  
AT_BEGIN 6Tsi^((Li  
从tag标签的开始一直到页面结束 \%QA)T%  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 }B&+KO)  
D(#6H~QN%  
AT_END VUzRA"DP|  
从tag标签的结束一直到页面结束 \2M{R  
在doEndTag中调用 N$M:&m3^  
nT=XWM  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: ~xf uq{L;  
KU;J2Kt  
<tag> [H {2<!  
\Yr&vX/[p  
<variable> _eUd RL>  
|J:m{  
<name-from-attribute>id</name-from-attribute> LKYcE;n  
L@`:mK+;  
<variable-class>database.BookDetails</variable-class> eJE!\ucS2W  
l4\!J/df  
<declare>true</declare> k<y~n*{_  
p:3 V-$4X  
<scope>AT_BEGIN</scope> 4VHX4A}CgA  
b?k6-r$j  
</variable> iVA=D&eZ  
+<fT\Oq#  
</tag>  J9lG0  
VM w[M^  
额外tag信息类 fwv.^k x  
Gp2C wyv  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: NGmXF_kqN  
o':K4r;  
· 变量名 s,-}}6WO  
/}nq?Vf  
· 变量所属类名 7E;`1lh7  
vGchKN~_  
· 此变量是否引用了一个新对象 lf_q6y  
p_CCKU  
· 此变量的有效范围 M2LW[z  
&0 SgEUZr  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 CgKFI  
*kt%.wPJ  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: fr8hT(,s)  
>w#&fd  
%FLe@.Ep{D  
public class DefineTei extends TagExtraInfo g:Fo7*i  
LknV47vd  
{ eOJ_L]y-  
`bW0Va N  
public VariableInfo[] getVariableInfo(TagData data) )|KZGr  
R*VEeLx  
{ }ni@]k#q<  
HjZf3VwI  
String type = data.getAttributeString(“type”); j<}y(~  
8?h&FbmB  
If( type == null) I36ClOG  
q0(-"}2l  
type = “java.lang.Object”; NGkWr  
QT\"r T9#  
return new VariableInfo[] { [9\Mf4lh#  
yXBWu=w3`O  
new VariableInfo(data.getAttributeString(“id”), L\\'n )  
yH]w(z5Z  
type, 8r48+_y3u  
pf#~|n#t  
true, s"(F({J  
D'Uv7Mis  
VariableInfo.AT_BEGIN) |v:fP;zc  
4Q~++PKBe  
}; a@m  64l)  
:+%Yul  
} XF?"G<2  
Y.E]U!i*  
}  4q\gFFV4  
7A{,)Y/w ^  
DlQ*'PX7  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: :xC1Ka%~  
<tei-class> T*](oA@  
org.apache.struts.taglib.bean.DefineTagTei 7mnZ,gpb  
</tei-class> #ib?6=sPC  
-"}nm!j /5  
2cko GafG{  
具有协作关系的tag x{1S!A^  
tW%!|T5/  
M)CQ|P  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 (*Q8!"D^6  
S&MF; E6  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 ?F9c6$|  
Z=^~]Mfa  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 r(I&`kF<  
y(Tb=:  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 QQQN}!xPj  
Sb?HRoe_  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 'y|p)r"  
AP0z~e  
X9o6} %Y  
public class QueryTag extends BodyTagSupport -8z@FLUK-  
W.?EjEx  
{ ~Q+J1S]Fs  
@%I-15Jz  
private String connectionId; j0A9;AP;;C  
CMU\DO  
public int doStartTag() throws JspException j "e]Ui  
JF(&+\i<p  
{ #=czqZw  
=A<a9@N}N  
String cid = getConnection(); DVw 04ay%  
=|IY[2^  
if(cid != null) 4Vv$bbu+  
T:S[[#f{5  
{ &cT@MV5  
CB>*(Mu  
//存在一个connection id,使用它。 ]".SW5b_  
7? qRz  
connection = (Connection) pageContext.getAttribute(cid); l *+9R  
kNv/L $oG  
} 3EA`]&d>  
h8:5[;e  
else EO G&Xa  
T49^  
{ 5`{u! QE  
C |P(,Xp  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, Rz=wInFs  
ilkN3J  
ConnectionTag.class); ^) 5*?8#  
dd!Q[]$ }  
if(ancestorTag == null) C$^WW}S  
AO]1`b:  
{ KWH:tFL.  
8P*wt'Q$  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); m&k l_f7  
d5qGTT ~a  
} %VwkYAgA  
Frum@n  
connection = ancestorTag.getConnection(); @P6*4W  
RpU.v `  
} ]I(<hDuRp  
vec4R )S  
} .Tc?PmN  
Q =4~u z|  
} D[<~^R;*  
epxbTJfc  
bs?&;R.5  
]w~ECP(ap  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: [}Y_O*C !  
1NQU96  
eRB K= X  
<tt:connection id=”con01” ...> ... </tt:connection> xs$.EY:k  
X?n($z/ {  
<tt:query id=”balances” connection=”con01” > pu Z0_1uN  
:zsMkdU  
SELECT account, balance FROM acct_table m " c6^)U  
HKG8X="  
where customer_num = <%= request.getCustno() %> ant#bDb/  
d%Nx/DS)  
</tt:query> i} ?\K>BWq  
lcEUK  
7 MG<!U  
或 4[n[Ch=lu  
+=#@1k~  
<tt:connection ...> %(izKJl q  
KqFiS9 N5  
<x:query id=”balances”> i#(+Kxr]>  
Y>I9o)KR  
SELECT account, balance FROM acct_table Mb(hdS90  
2R~[B]2"r  
where customer_num = <%= request.getCustno() %> (n4Uc308  
&f<Ltdw  
</x:query> &-p!Lg&D  
`l+9g"q  
</tt:connection> |]tsf /SA  
z9ZS& =>  
t9[%o=N~lD  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: ew*;mQd  
5~=wia  
<tag> gwN y]!  
X{;5jnpG  
... CzG/=#IU  
!s47A"O&B  
<attribute> R/kfbV-b  
AJ)N?s-=  
<name>connection</name> Zr$D\(hX  
06>+loBG  
<required>false</required> Pv Vn}i   
XseP[  
</attribute> [A#>G4a<  
7WEoyd  
</tag>
描述
快速回复

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