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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! cT5BBR   
KV)if'  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 Wl7S<>hg4  
T65"?=<EB  
在这篇文章中,我们主要讨论: X[!S7[d-y  
sd9b9?qiu  
· 什么是自定义tag标签? Jcy+(7lE)  
 p9 G{Q  
· 怎么使用tag标签? #-i#mbZ e  
a/</P |UG  
o 声明要使用的tag库 | |L^yI~_d  
&5[B\yv  
o 找到与之对应的tag处理类 Wo(m:q(Om  
Eunmc  
o tag标签的类型 lc3N i<3v  
a!EW[|[Q  
· 自定义tag标签 ;t M  
U[?f@.&  
o tag处理类 $>7T s>8  
)5NWUuH 5  
o tag库描述 ik](k"1{  
f/QwXO-U  
o tag标签示例 ^T#jBqe  
+ 9I|F m  
o 带属性的tag Qz89=#W  
S,EL=3},=  
o 带body的tag *07?U")  
^/VnRpU  
o 定义了脚本变量的tag {+]tx46$  
"@^Q" RF  
o 具有协作关系的tag &>!-67  
f@gvDo]Y  
· 自定义tag标签 b0/YX@  
AB{zkEuK  
o 一个迭代tag的例子 +cbF$,M4  
.C.b5x!  
o 一个模板tag库 _K&Hiz/'  
XG!6[o;  
o tag处理类到底是怎样被调用的? ]j!pK4  
mMvAA;  
%LM6=nt  
什么是自定义的tag? L?Ys(a"k  
~MP |L?my  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 ;%Px~g  
NG`Y{QT6N  
自定义tag标签有很多特色,诸如: P,xIDj4d  
^?wR{q"8  
· 可以在JSP页面中自定义tag标签的属性 M.xZU\'ty  
D2GF4%|  
· 访问JSP页面中的所有对象 }'?qUy3x  
8A5/jqnqt  
· 可以动态地修改页面输出 x4/{XRQ  
6{{<+ o  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 {kBsiSvsA;  
]28j$)6  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 QT5pn5+ z  
C_'EO<w$  
E[7E%^:Mg  
使用tag标签  q(X7e  
WNZYs  
V= -  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 *o38f>aJl  
R(*t 1R\  
要使用tag标签,JSP程序员必须做2件事: RO|8NC<oj  
<W>A }}q  
· 声明此tag标签的tag库 ~ g-(  
m"-kkH{I  
· 实现此tag标签 LuHRB}W  
;aj;(Z.p)  
声明tag标签所在的tag库 Alo L+eN@  
^_i)XdPU  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) b;{"@b,Y  
Zk/ejhy0  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> Hq+QsplG  
LR{bNV[i  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 4lWqQVx  
 '6})L  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 AorY#oq  
Z#B}#*<C  
以下taglib指示符直接引用一个TLD: _5H~1G%q  
M PDRMGR@i  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> d:w/{m% #  
<i4]qO(0u  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: .d r Y  
4H (8BNgzV  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> ;Ce?f=4  
#g0_8>t  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: Ws7fWK;  
:o ~'\:/  
<taglib> LSA6*Q51  
Q(cLi:)X2  
<taglib-uri>/tutorial-template</taglib-uri> RRPPojKZ  
<tBT?#C9+  
<taglib-location> 2J{vfF  
Z$g'h1,zW  
/WEB-INF/tutorial-template.tld /&Cq-W  
Xz^k.4 Y{4  
</taglib-location> b r Iz8]  
tM;cvc`/  
</taglib> ;4ybkOD  
R6BbkYWrX  
m~*qS4  
实现此tag标签 0 K#|11r  
K}cA%Y  
87[ ,.W  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 Za1mI^ L1  
[ i, [^  
E"_{S.Wc  
tag标签类型 1HKA`]D"p  
Jw@X5-(Cp  
R[v0T/  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): 9#9bm  
?g{[U0)  
<tt:tag> T)sIV5bk  
yNXYS  
body O5vfcX4>  
krFp q;  
</tt:tag> |f @A-d X  
u9|Eos i  
']eN4H&=?}  
一个不带body的tag标签如下: 2F`#df  
yQUrHxm  
<tt:tag /> d@g29rs  
+B " aUF  
L=qhb;  
简单的tag标签 3))CD,|  
 mjP  
一个没有body和属性的tag标签如下: |Vqm1.1/Zv  
zHz>Gc  
<tt:simple /> "hI"4xSg  
K"XwSZ/  
T@.+bD  
带属性的tag标签 &Pm@+ML*x  
P$Vh{]4i{  
WN{8gL&y  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 ^8~TsK~  
8 <;.[l  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: DvQV_D  
J.:  
<loglic:present parameter = “Clear”> lqv}~MC  
Q2Ey RFT  
而另一个标签logic:iterate是用表达式来给属性赋值: ? OF $J|h  
QxLrpM"O  
<logci:iterate collection=”<%= bookDB.getBooks() %>” Yb 5@W/'  
)cRHt:  
id=”book” type=”database.BookDetails”> :FC)+OmJ  
hNZ_= <D!  
53:u6bb;  
带body的tag标签 q6$6:L,<  
d+v| &yN  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 TM{m:I:Z*n  
JS8pN5   
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: 5]]QW3  
4y+hr   
<logic:present parameter=”Clear”> SaF0JPm4z  
_ps4-<ugC  
<% cart.clear(); %> Zy3F%]V0  
`Zo5!"'  
<font color=”#ff0000” size=”+2”><strong> ~FYC'd  
*!y04'p`<  
你选择了清除购物车! c^1JSGv  
OfBWf6b  
</strong></font> aC1 xt(  
.Qn#wub  
</logic:present> M5+R8ttc  
=/|GWQ j  
=Xr{ Dg  
到底是用属性还是用body来传递信息? ,e1c,}  
p+b9D  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 ,/Gp>Yqx  
{@7UfJh>  
^Ff fc@=  
定义脚本变量的tag标签 |>U<EtA"  
2N &B  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: }])j>E  
[7`S`\_NK  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> UV;I6]$}A7  
l2Py2ZI-b  
<% tx.begin(); %> b_{+OqI  
{)r[?%FMgV  
... 4%nK0FAj  
g=4P-i3   
`O3#/1+  
具有协作关系的tag标签 Om:Gun\%  
1iR\M4?Frf  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 #Qz 9{1\G  
K ~\b+  
<tt:tag1 attr1=”obj1” value1=”value” /> qfFa" a  
LL3| U  
<tt:tag2 attr1=”obj1” /> fy>3#`T-  
!$iwU3~<  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 Z%.L d2Q{  
x?{l<mc  
<tt:outerTag> lxXF8c>U  
L67yL( d6a  
<tt:innerTag /> H/x 9w[\+[  
QrmGrRH  
</tt:outerTag> lp$,`Uz`  
6tVp%@  
e jk?If 07  
Tag处理类 : LX!T&  
o%]b\Vl6  
j y p.2c  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 DP*V|)  
Sb?v5  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 K~UT@,CS60  
iuEe#B;!  
下表说明不同类型的tag所需要不同的处理过程: PB8U+  
E(S$Q^  
Tag处理类的方法 :Oj!J&A  
Us&~d"n  
Tag标签类型 vy5{Vm".4  
所调用的方法 @d3yqA  
25xt*30M  
基本标签 #CeWk$)m  
doStartTag, doEndTag, release Pvkr$ou  
m7> )p]]  
带属性的标签 78Zb IL  
doStartTag, doEndTag, set/getAttribute1...N, release V^G+_#@,,  
%7TG>tc  
带内容的标签 b7M)  
doStartTag, doEndTag, release [F *hjGLc}  
%tkL<e  
带内容的标签,且内容重复循环 gY-}!9kW]  
doStartTag, doAfterBody, doEndTag, release JKYl  
R^ I4_ZA  
带内容的标签,且内容与JSP交互 ]Ah<kq2sk  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release &s.-p_4w^D  
r)qow.+&  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 $I4J Kh  
g fv?#mp  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 :NwFJc  
P]4u`&  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 14-uy.0[  
@DR?^ qp  
)lx;u.$4  
Tag库描述(简称TLD) Q?m= a0g  
y7R{6W_U>  
?y*yl  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 Z +}# Ic  
FO|Eg9l  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 hdH-VR4  
.a]av   
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: '! ;Xxe5  
5Obv/C  
<?xml version="1.0" encoding="ISO-8859-1" ?> \xZ6+xZd1  
t_X=x`f  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> F,GG>(6c  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: QbAEW m  
UD]RWN  
h5H#xoCXp  
<taglib>的子元素 98l-  
2;ogkPv'  
Element W2,Uw1\:1  
Description wAF#N1-k  
r$d'[ZcX  
tlib-version 6CWm;%B#G  
Tag库的版本 {1wjIo"ptg  
g>f_'7F&  
jsp-version H]f8W]"c[  
Tag库所需要的jsp的版本 v.H@Ey2  
\"=@uqar2  
short-name `Yu4h+T  
助记符,tag的一个别名(可选) 8bEii1EM  
Ria*+.k@"B  
uri ]:]w+N%7  
用于确定一个唯一的tag库 <m?/yRE K2  
dy0xz5N-  
display-name y"0! 7^  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) uchz<z1  
.sPa${  
small-icon Ba|76OBRJ  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) RZKczZGZg  
G?{uR6s>#  
large-icon I9r> 3?  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) p8u -3  
c f1GA  
description jJY!;f  
对tag库的描述(可选) a s?)6  
yy3-Xu4  
listener >9]i#So^  
参见下面listener元素 4ze4{a^  
L{i|OK^e  
tag Rlf#)4  
参见下面tag 元素 *[['X%f  
}#f~"-O  
Listener元素 baM@HpMhM  
/3v`2=b  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 L[:b\ O/p,  
3/((7O[  
Tag元素 < G:G/  
ob.=QQQs  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 w!^{Q'/,Q  
PP)-g0^@  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: W[tX%B  
::rKW *?  
Tag元素的子元素 -}*YfwK  
MXU8QVSY"  
元素名称 lAPvphO  
描述 L9)nRV8  
vb Mv8Nk  
name ];o[Yn'>o  
独一无二的元素名 ~~'UQnUN4  
zc#aQ.  
tag-class 5S ?+03h~  
Tag标签对应的tag处理类 ;O7<lF\7o  
)o8]MWT\;  
tei-class w[wrZ:[  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) </8F  
J'>i3e Lq  
body-content tO ^KCnL  
Tag标签body的类型 ~<#!yRy>r  
U#!f^@&AB  
display-name !G3d5d2)C  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) 07L 1 "  
/"<o""<]  
small-icon zcNv T  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) ta 66AEc9  
PxHH h{y%c  
large-icon Os-sYaW  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) H|0GRjC  
AlRng& o~  
description IvyBK]{|  
此tag标签的描述 _7"G&nZ0  
Pb^Mc <j  
variable ("L&iu\`@  
提供脚本变量的信息(同tei-class)(可选) Bzw!,(u/ "  
4U;6 2 jq  
attribute k/ 9S  
Tag标签的属性名 ^B|Q&1  
B@W`AD1^{  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 @ukIt  
!h0#es\  
le-Q&*  
简单的tag 2= 6}! Y  
>)3[CU,  
,1+)qv#|i  
tag处理类 $fwv'  
2%Y]M%P  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 KGsH3{r  
5 5_#?vw  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: }t[?g)"M#-  
Y&Sk/8  
Z'vGX,:  
public SimpleTag extends TagSupport Je#vl4<L  
X^U)j N2  
{ j[fVF3v  
lklMdsIdj  
public int doStartTag() throws JspException g= ql 3N  
$i+ 1a0%n  
{ ni@N/Z?!pA  
}0P5~]S<5A  
try{ <QyJJQM  
*c+Kqz-  
pageContext.getOut().print(“Hello.”); F`$V H^%V  
$=iV)-  
}catch(Exception e){ .}>DEpc:n  
9o]h}Xc  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); N{u4  
 H)),~<s  
} %/o8-N|_[  
 4_E{  
return SKIP_BODY; ^hhJ6E_W  
MW^,l=kqW)  
} ZV`D} CQ  
=!b<@41  
public int doEndTag() G02(dj  
|[ tlR`A$  
{ (C RY$+d  
S(c,Sinc  
return EVAL_PAGE; y^#jM  
8#9 di  
} L)5YX-?  
Jbud_.h9  
} J3oj}M*  
DL5`A?/  
<wt#m`Za  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 <(YmkOS+  
xbFoXYqgP  
<body-content>empty</body-content> ][|)qQ%V  
06 kjJ4  
`[<j5(T  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 D 6trqB  
/;t42 g9w  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, X&1R6 O  
-'FzH?q:  
<logic:present parameter=”Clear”> .u3!%{/v(c  
w z-9+VN6  
与此相应,此tag处理类应有如下方法和定义: 0f).F  
$= '_$wG 8  
\Gh]$s p  
protected String parameter = null;  o *2TH2  
Vx5ioA]{  
public String getParameter() .z u0GsU=  
[:x^ffs  
{ >5{Z'UWxh  
A2{u("^[6  
return this.parameter; +'9l 2DI;  
sgdxr!1?y  
} KJPCO0"  
ozZW7dveU  
public void setParameter(String parameter) B w1ir  
PN ,pEk|  
{ }Yt/e-Yg%r  
Pa%;[hbn  
this.parameter = parameter; q -%;~LF  
fD3}s#M*G  
} ,E{z+:Es  
=B9Ama   
vA rM.Bu>b  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 }5~|h%  
8<UD#i@:C  
Attribute元素 %xtTh]s  
8RJXY:%  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 TfaL5evio  
w=.w*?>  
<attribute> 3.M<ATe^  
~^((tT  
<name>attr1</name> QiB ^U^f  
H79XP.TtE  
<required>true|false|yes|no</required> 0 1U/{D6D  
q<mDs$^K  
<rtexprvalue>true|false|yes|no</rtexprvalue> S(kj"t*3  
!+tz<9BBY  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> {ndL]c'v  
g 4,>cqRkq  
</attribute> =e'b*KTL,  
XXsN)2  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 8&g|iG  
R7: >'*F  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 x/*ndH  
w '?xewx  
<tag> ?bwF$Ku  
t(69gF\"  
<name>present</name> ~^*IP1.3  
Kbjt  CI7  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> r|t ;#  
x&qC~F*QR%  
<body-content>JSP</body-content> MW|Qop[  
NZ:A?h2JR  
xQV5-VoFC  
FSZQ2*n5  
<attribute> 7Io]2)V  
x ;V7D5 q  
<name>parameter</name> fx@Hd!nO~"  
44T>Yp09  
<required>false</required> 2_@vSwC  
!e?;f=1+E  
<rtexprvalue>true</rtexprvalue> $ 2'AY  
`$j"nP F_  
</attribute> u^H:z0  
JBa( O- T  
1<#J[$V  
#~J)?JL  
</tag> 4:\1S~WW  
@i`*i@g  
~IvAnwQ'  
属性元素的校验 iHy=92/Ww  
rblEyCR  
&6%%_Lw$  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 `Oz c L  
TCAtb('D  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 X;JptF^  
'@1oM1  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 b e[KNrO  
~_C[~-  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: S#+Dfa`8X  
kL;sA'I:S  
<attribute> ]k~k6#),;  
GtcY){7  
<name>attr1</name> bDI#'F  
bqEQP3t^  
<required>true</required> ~\A(xmW}  
uJ jm50R<  
<rtexprvalue>true</rtexprvalue> :wiQ^ea  
 y/t{*a  
</attribute> E!.>*`)?.  
3vx*gfr3  
UJ-IK|P.#  
这个定义说明了attr1能在运行期间被赋值。 ]i'hCa $$  
g:0-` ,[  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 ER0nrTlB<  
ssbvuTr  
LGx]z.30B  
Public class TwaTEI extends TagExtraInfo _:oB#-0  
}3sj{:z{  
{ |^jl^oW  
#" {wm  
public boolean isValid(Tagdata data) N)Fy#6  
wi'CBfr'z  
{ \T)2J|mW  
 qW8sJ=  
Object o = data.getAttribute(“attr1”); h3rdqx1  
^2-2Jz@  
If(o != null && o != TagData.REQUEST_TIME_VALUE) x(J|6Ey7!n  
I}JC~=`j  
{ ?Fgk$ WqC  
|sd0fTK  
if( ( (String)o).toLowerCase().equals(“true”) || dh r)ra]  
< GoUth.#  
((String)o).toLowerCase().equals(“false”) ) 5Vo8z8]t`  
3!_XFV  
return true; 9PXG*r|D  
W]E6<y'  
else ,B|~V 3)(  
7x8/Vz@\  
return false; &NbhQY`k  
GSzb  
} 7: 7i}`O  
bup)cX^  
else Db"jzMW.  
rro92(y  
return true; S?pWxHR]  
olc7&R  
} 0mcZe5RS  
;T1OXuQ  
} $#R@x.=  
Pn:L=*  
3^m0 k E  
带body的tag Pf`HF|NI  
o6LeC*  
 ~DYUI#x  
tag处理类 N!R>L{H>  
;Fw{p{7<  
r8.R?5F@  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 bgD4;)?5b  
[(Z{5gK  
Tag处理类不与body交互 I8*_\Ez  
QWL$F:9:  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 jK`b6:#(,  
Z$qLY<aV  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 G 3))3]  
 )l 0\TF  
Tag处理类与body交互 [n%=2*1p  
| Q0Wv8/  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 qffVF|7  
fTb&k;'LR<  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 #mhR^60,  
7l Q@I}i  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 NDsF<2A4  
X2CpA;#;7l  
doInitBody 方法 }>`rf{T  
@smjXeF o  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 WdQR^'b$   
A HnXN%m  
doAfterBody方法 '3B"@^]  
tzH~[n,  
此方法在body内容已被计算后进行调用。 pC=kvve  
WC2sRv4]3  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 D^]g`V*N  
.|ZO2MCd  
release 方法 TsiI5'tx  
BO5\rRa0  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 +5AWX,9,-  
l@edR)n <  
{'O,G$Ldkr  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 l X g.`  
FU]jI[  
p./9^S  
Public class QueryTag extends BodyTagSupport ngmHiI W  
eK8y'VY  
{  .7GTL  
2c)Ez?  
public int doAfterBody() throws JspTagException cp| q  
/6Bm <k%  
{ BqoGHg4iq  
ks3ydHe`  
BodyContent bc = getBodyContent(); b!lS=zIN  
|aD8  
//将body的内容以字符串的格式提取出来 MS7rD%(,'  
t4Q&^AC  
String query = bc.getString(); &YiUhK  
SM? rss.=  
//清除body c&> S  
NW=gi qB  
bc.clearBody(); 92F 9)S{"  
(:|g"8mQm  
try{ QOT|6)Yb  
&/+LY_r'<I  
Statement stmt = connection.createStatement(); h*X5O h6  
Ms>CO7Nvy  
Result result = stmt.executeQuery(query); 3UR'*5|'  
Bp:PAy  
}catch(SQLException e){ $kAal26z  
3Gk\3iU!  
throw new JspTagException(“queryTag: “ + e.getMessage() ); Z'!Ii+'6  
pB(|Y]3A  
return SKIP_BODY; =lb5 #  
lE=&hba  
} dbe\ YE  
f;{K+\T  
} 4:zyZu3fm  
rq(9w*MW:  
bukdyo;l  
body-content元素 s:/Wz39SY3  
jjJvyZi~J  
UlNx5l+k  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: 7!;48\O]w  
i]$/& /  
<body-content>JSP|tagdependent</body-content> u{J\X$]  
f%[0}.wp  
U;w| =vM  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 (fqU73  
xwhS[d  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 ;{j@ia  
RKb{QAK!v  
->9waXRDz)  
用tags定义脚本变量 R+&{lc  
;owU]Xk%8K  
TdKo"H*C  
tag处理类 Y@l>4q")  
'/U%-/@  
VX6M4<8  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 'hNRIM1  
V*,6_ -^l  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 7W.z8>p  
]^>RBegJBO  
对象的生存周期(scope)如下表: \Dx5=Lh  
GeFu_7u!|  
对象的生存周期表 U-.A+#<IT9  
?910ki_  
名字 zq Cr'$  
可访问范围 P0c6?K6 j  
生存周期 Wr6y w#  
yc7 "tptfF  
page INNTp[  
当前页面 WQ1K8B4  
一直有效,除非页面向客户提交响应或重定向到一个新页面 VJbn/5+P  
o>^ @s4t  
request 2=RQ,@s  
当前页面或当前页面重定向到的页面 pP)> x*1  
一直有效,除非页面向客户提交响应 fn3DoD+I  
/P[@o  
session @W.0YU0|J  
当前页面或在同一浏览器窗口中的页面 "ivSpec.V  
一直有效,除非关闭当前浏览器、超时、网络故障 ]N^>>k  
0f;`Zj0l8  
application 1 ~s$<  
整个web应用程序的所有请求 =`+c}i?  
一直有效,除非发生网络故障、服务器故障 R+<M"LriR&  
=<.h.n  
提供关于脚本变量的信息 j"Z9}F@  
'>Uip+'  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: Hdda/?{b  
zlhU[J}"1|  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> }>yQ!3/i  
;mauA#vd  
<font color=”red” size=”+2” > c :u2a/Q?  
- (VX+XHW  
<%= messages.getString(“CartRemoved”) %> >>.4@  
f)#nXTXeC  
<strong><jsp:getProperty name=”book” property=”title” /></strong> -~TgA*_5]  
|>v8yS5  
</font> se S)`@n  
i:sb_U+M  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: eMOnzW|h  
}&Ul(HR  
· 脚本变量名称 -&0HAtc  
ia*Bcx_RW+  
· 脚本变量所属的类 h,x'-]q  
O[5u6heNMr  
· 此脚本变量是否引用了一个新的或已存在的对象 JL=s=9N;3  
8z`Ne(h;  
· 此脚本变量的有效性 df8aM<&m3  
>U6 2vX"  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 qlg?'l$03)  
,3bAlc8D7  
Variable元素 dk.VH!uVb  
PbIir=  
Variable元素有如下子元素: </li<1  
l.%[s6  
· name-given ?D?D 给出的名字,是一个常量 3h4'DQ.g  
:rnj>U6<>  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 s}Q*zy  
2 X`5YN;  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: nD!5I@D  
te b/  
· variable-class?D?D变量的类型,缺省为java.lang.String。 6B&ERdoX  
G0Wv=tX|  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 K&;;{~md.  
]GmXZi  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: j9 O"!9$vQ  
e"]DIy4s  
脚本变量的有效范围 8]A`WDO3  
9~6~[z  
i3<ZFR  
有效性 m:C|R-IL  
方法 vx4Jk]h+=L  
:M\3.7q  
NESTED I7HP~v~  
在tag标签的开始和结束之间 6#(rWW "_  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 ,H:{twc   
9Fh1rZD<  
AT_BEGIN |YK4V(5x  
从tag标签的开始一直到页面结束 !--A"  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 r=:o$e  
"dFuQB  
AT_END Y5\=5r/  
从tag标签的结束一直到页面结束 &BkdC,o  
在doEndTag中调用 O;SD90  
iNEE2BPp  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: KO&oT#S  
]V.0%Ccw;.  
<tag> xYD.j~  
vj+ S  
<variable> Qh!h "]  
+^V%D!.$@  
<name-from-attribute>id</name-from-attribute> nI<Ab_EB  
|emZZj  
<variable-class>database.BookDetails</variable-class> ]?n~?dD{]  
j[&C6l+wH  
<declare>true</declare> |<w Z;d  
4<l&cP  
<scope>AT_BEGIN</scope> p WLFJH}N  
Ukg iSv+  
</variable> '`/w%OEVC5  
U Y')|2y 5  
</tag>  FA#8  
Cl'3I%$8K  
额外tag信息类 )+v' @]r  
.h@HAnmE  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: "bk'#?9  
(  V H0+  
· 变量名 v@;!fBUt  
(g#,AX  
· 变量所属类名 Q0-}!5`E1$  
$+Zj)V(  
· 此变量是否引用了一个新对象 N83g=[  
JN<IMH  
· 此变量的有效范围 "M4 gl  
Ilv _.  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 >TQnCG =  
# `b5kqQm  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: ma7@vD  
O"~BnA`dJ  
r-IG.ym3  
public class DefineTei extends TagExtraInfo *u?N{LkqS  
G,JK$j>*l  
{ KvfZj  
IiRII)  
public VariableInfo[] getVariableInfo(TagData data) o7WK"E!pF'  
{ZrB,yK  
{ Sn ~|<Vf  
PXJ`<XM  
String type = data.getAttributeString(“type”); +oe%bk|A  
84UI)nE:Q  
If( type == null) ?~s23%E  
n;,>Fv  
type = “java.lang.Object”; s2M|ni=  
{rWFgn4Li  
return new VariableInfo[] { &0QtHcXpR  
~<&47'D  
new VariableInfo(data.getAttributeString(“id”), ye-R  
_Vf0MU;3f+  
type, bRb+3au_x  
of>"qrdZ  
true, RmcQGQ  
K^fH:pV  
VariableInfo.AT_BEGIN) -+w^"RBV  
XVNJ3/  
}; GO=3<Q{;  
t ]yD95|  
} T{Rhn V1  
o6~9.~_e  
} gBCO>nJws  
[!CIBK99  
ZJeTx.Gi6  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: v9 K{oB  
<tei-class> ~[d|:]  
org.apache.struts.taglib.bean.DefineTagTei ^lYa9k  
</tei-class> 1L:sck5k  
+Xjevg6DU  
gjnTG:}}}+  
具有协作关系的tag _ZD8/?2QV  
T($6L7 j9  
N&'05uWY}  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 u"*Wo'3I|  
XexslzI  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 PK7 kpC  
%.3] F2_Q  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 IoI ,IX]i)  
7)y9% -}  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 D%=FCmL5@=  
84uHK)h<%  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 Wu9))Ir  
3Az7urIY  
!1s^TB>N  
public class QueryTag extends BodyTagSupport _Bhm\|t  
qe\JO'g#e  
{ {f kP|d  
@p}"B9h*^  
private String connectionId; ;[>g(W+  
hRWRXC 9  
public int doStartTag() throws JspException DRUvQf  
Ar:ezA  
{ 2UGnRZ8:1Y  
-g;cg7O#(  
String cid = getConnection(); KqH_?r`  
a1n j}1M%  
if(cid != null) S66. .sa  
{~RS$ |  
{ b\^q9fy  
E")g1xGaK  
//存在一个connection id,使用它。 O5?Gv??@  
C0bOPn  
connection = (Connection) pageContext.getAttribute(cid); bEz1@"~ p  
aHvsgp]  
} OKH4n/pq  
+~~&FO2  
else CS<,qvLpL  
D ^~G(m;-  
{ ZSo#vQ  
n6f  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, g)@d(EYY  
KNw{\Pz~w  
ConnectionTag.class); zu@5,AH  
H ^<LnYZ  
if(ancestorTag == null) m)aNuQvy:Z  
l5R0^!t  
{ D'! v9}  
keYvscRBI  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); AM ZWPU  
>){"x(4`  
} &S8Pnb)d  
,py:e>+^t  
connection = ancestorTag.getConnection(); I|#1u7X%]  
b+g(=z+  
} gPu0j4&-  
q|23l1 PI  
} RrPo89o  
1Y-m=~J7  
} /s\_"p  
GkT:7`|C  
cxNb!G  
4R~f   
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: <e s>FD  
UY!N"[&  
OZ /!= ;  
<tt:connection id=”con01” ...> ... </tt:connection> EMV<PshW=  
S-8wL%r  
<tt:query id=”balances” connection=”con01” > D_HE!fl  
EPZ^I)  
SELECT account, balance FROM acct_table ![{>$Q?5  
mF?GQls`  
where customer_num = <%= request.getCustno() %> %L\buwjy$  
(|F} B  
</tt:query> >brf7h  
Eep*,Cnt0  
eoC@b/F4  
#ZPU.NNT?  
\;h+:[<e1  
<tt:connection ...> Jx:t(oUR+  
0M'[|ci d|  
<x:query id=”balances”> VGVZ`|  
[CBhipoc  
SELECT account, balance FROM acct_table QBNnvg4v  
b~1]}9TJ  
where customer_num = <%= request.getCustno() %> nJvDkh#h1  
Jf/X3\0N7  
</x:query> mv,<#<-W  
"K"]/3`k-  
</tt:connection> AV%?8-  
cNX0.7Ls  
33{(IzL0  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: WCg*TL}  
%SwN/rna  
<tag> z g@,s"`>  
Ls<.&3X2  
... I-fjqo3  
RW!_Zz Z  
<attribute> #9{9T"ed  
9'qU4I  
<name>connection</name> Y SvZ7G(m>  
4@qKML  
<required>false</required> C;T:'Uws  
=*AAXNs@3  
</attribute> y}fF<qih'>  
yN0!uzdW*  
</tag>
描述
快速回复

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