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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! E{_p&FF  
+<Uc42i7n  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 'S)}mG_  
.B"h6WMz  
在这篇文章中,我们主要讨论: CcLP/  
x>!#8?-h  
· 什么是自定义tag标签? Av _1cvR:  
o\g",O4-  
· 怎么使用tag标签? j Bl I^  
X[(u]h`  
o 声明要使用的tag库 gK9@-e  
jQj`GnN|  
o 找到与之对应的tag处理类 ds4ERe /  
Zc{at}{  
o tag标签的类型 BQ)zm  
kZ[E493bV  
· 自定义tag标签 n3g3(} Q0  
Zvk O#j  
o tag处理类 0V}%'Ec<e  
L/F!Y%=;[  
o tag库描述 ql2>C.k3L  
2Af1-z^^K  
o tag标签示例 -$QzbRF5R  
?r'rvu'/  
o 带属性的tag R}#?A%,*  
3(}W=oI  
o 带body的tag E/Q[J.$o  
z$QYl*F1  
o 定义了脚本变量的tag TF^Rh4  
# yAt `  
o 具有协作关系的tag =BMON{K  
H .JA)*b-  
· 自定义tag标签 ;xN 4L  
6*lTur9ni  
o 一个迭代tag的例子 T5=3 jPQ  
,*+F*:o(m  
o 一个模板tag库 {uM*.]  
<KoiZ{V   
o tag处理类到底是怎样被调用的? f2`[skNj  
Ev,>_1#Xm  
:tl* >d~  
什么是自定义的tag? %|I~8>m  
>KNiMW^V  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 }:])1!a  
k^w!|%a[  
自定义tag标签有很多特色,诸如: K63OjR >H  
Ovxs+mQ  
· 可以在JSP页面中自定义tag标签的属性 4[44Eku\  
_rdEur C6  
· 访问JSP页面中的所有对象 'P0:1">  
`WboM\u  
· 可以动态地修改页面输出 Rp^k D ,*  
h#dp_#  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 *?zmo@-  
_K<H*R  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 j2#RO>`,I  
Q( U+o-  
&GGJ=c\  
使用tag标签 |C301ENZ  
8d?r )/~  
jdiH9]&U  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 W4%I%&j  
5/F1|N4  
要使用tag标签,JSP程序员必须做2件事: @SjISZw_  
X4_1kY;  
· 声明此tag标签的tag库 U>H"N1  
+DmfqKKbd  
· 实现此tag标签 2Nrb}LH  
*|{1`{8n  
声明tag标签所在的tag库 Ngi] I#V z  
H*51GxK  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) aZn]8jC%  
%CV@FdB  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> !w2J*E\  
$REz {xgA=  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 Rsd~t_a1  
{k*rD!tT  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 p{ X?_F  
`k2YH?  
以下taglib指示符直接引用一个TLD: /*Iq,"kGz  
O$z XDxn  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> 6C k 3tCr  
1[p6v4qO{  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: +i^@QNOa  
o|(Ivt7jk  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> Vl'Gi44)3"  
H c,e&R  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: Gf71udaa  
V1di#i:  
<taglib> o-i9 :AHs  
.3>`yL  
<taglib-uri>/tutorial-template</taglib-uri> iOY: a  
uJ-Q]yQ  
<taglib-location> A\ARjSdb  
e_=TkG1E6  
/WEB-INF/tutorial-template.tld StLFq6BO  
=Ot|d #_  
</taglib-location> =D;n#n7  
+*uaB  
</taglib> 9UDanj P  
$ /`X7a{  
Hq$&rNnq\  
实现此tag标签 Rax]svc  
fVf @Ngvu  
tVQq,_9C  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 sU Er?TZ  
=$mPReA3v  
.>#X*u  
tag标签类型 ;P *`v  
mHe[ NkY6  
fofYe0z  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): ,="hI:*<  
{ooztC   
<tt:tag> FD'yT8]"  
cl04fqX  
body Ef @  
~aPe?{yIUa  
</tt:tag> f8e :J#jbS  
sGFvSW  
9*Q6/?v  
一个不带body的tag标签如下: *Xcqnu('  
hKnAWKb0  
<tt:tag /> %lq[,6?>5  
Ty<."dyPW  
U7#C.Z  
简单的tag标签 ^'\JI  
y0f:N U  
一个没有body和属性的tag标签如下: w**~k]In  
Z_U4Yy'NNw  
<tt:simple /> JR_%v=n~x  
E)%D LZ  
+pPfvE`  
带属性的tag标签 ee/3=/H|;  
`^ZhxFX  
Gg e X  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 z~"Q_gme  
O!!N@Q2g  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: j*\oK@  
40%fOu,u`  
<loglic:present parameter = “Clear”> [*C%u_h  
 WD55(  
而另一个标签logic:iterate是用表达式来给属性赋值: x8w l  
/ 3eGt7x#  
<logci:iterate collection=”<%= bookDB.getBooks() %>” Jxf>!\:AZu  
&@K6;T  
id=”book” type=”database.BookDetails”> B"YN+So  
AL!ppi  
/!?b&N/d)  
带body的tag标签 7KesfH?  
G2<$to~{  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 qj9[mBkP"  
U&i#cF   
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: Z`_x|cU?J  
Lk)I;;  
<logic:present parameter=”Clear”> C$p012D1  
L;lu)|b"  
<% cart.clear(); %> i?ZVVE=r  
!2Gua1z!CJ  
<font color=”#ff0000” size=”+2”><strong> 5dGfO:Dy_  
9wlp AK  
你选择了清除购物车! -T}r$A  
15@2h  
</strong></font> %~I&T". iC  
egK~w8`W%  
</logic:present> "cyRzQ6EH  
iX o(  
-AD@wn!wCJ  
到底是用属性还是用body来传递信息? n }b{u@$  
NE.h/+4  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 L3w.<h  
idB1%?<  
@0]w!q  
定义脚本变量的tag标签 A_l\ij$Y  
vf zC2  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: t{g@z3  
,,H;2xYf  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> ;vneeW4|  
ep~+]7\  
<% tx.begin(); %> ber&!9  
0$ON`Vsu|  
... &@,lF{KTL  
X~UL$S;  
pV(k6h  
具有协作关系的tag标签 Z^]jy>dj  
c(uD kX  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 }W@refS  
#8sy QWlG  
<tt:tag1 attr1=”obj1” value1=”value” />  LtH j  
P4HoKoj2`  
<tt:tag2 attr1=”obj1” /> tmOy"mq67  
De>e`./56  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 k,$/l1D  
Rz&`L8Bz  
<tt:outerTag> L@z[b^  
i6P}MtC1  
<tt:innerTag /> r&Nh>6<&/  
YO-B|f  
</tt:outerTag> e,{k!BXU#'  
ysZ(*K n(?  
q_6lD~~q^  
Tag处理类 sZ~03QvkT  
K>vl o/#!  
L*dGo,oN  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 $3B%4#s  
|$6Ten[B#  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 qtdkK LT  
vmEn$`&2t  
下表说明不同类型的tag所需要不同的处理过程: w&f>VB~,1  
X $V_  
Tag处理类的方法 C+P.7]?&  
rHjDf[5+  
Tag标签类型 C[<{>fl)  
所调用的方法 'zav%}b]L  
+'SL5d*  
基本标签 8G3 Z,8P4(  
doStartTag, doEndTag, release 1) K<x  
mhv6.W@  
带属性的标签 Qy"%%keV'T  
doStartTag, doEndTag, set/getAttribute1...N, release EcX7wrl9x  
34X]b[^  
带内容的标签 MM]0}65KG  
doStartTag, doEndTag, release Zyr| J!VF  
Q|P M6ta  
带内容的标签,且内容重复循环 W!T[ ^+  
doStartTag, doAfterBody, doEndTag, release b:'8_jL  
BJ]L@L%  
带内容的标签,且内容与JSP交互 FX9WX b4w  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release *J]p/<> {  
\ a7m!v  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 IJKdVb~   
c~/poFj  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 O7_y QQAA  
G /$+e  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 ygV_"=+|N  
J/D~]U  
v(R^LqE  
Tag库描述(简称TLD) f+ZOE?"  
*;McX  
g]JRAM  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 ^wc:qll  
kCEo */,  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 M:(.aEe  
)MSCyPp5  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: {`k&Q +gY  
7[0Mr,^  
<?xml version="1.0" encoding="ISO-8859-1" ?> ^t71${w##  
x^_c4,i)  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> |A,.mOT  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: 1u5^a^O(|  
?Fl O,|   
9{ge U9&Z  
<taglib>的子元素 nh0gT>a>@  
?D7zty+}^  
Element 8+7*> FD)1  
Description RTvOaZ  
(e~9T MY  
tlib-version |OAiHSW"V  
Tag库的版本 BMQ4i&kF|  
~N}Zr$D  
jsp-version 4,W,E4 7  
Tag库所需要的jsp的版本 J!RRG~  
82+2 PE{  
short-name Z_dL@\#|  
助记符,tag的一个别名(可选) ^\ln8!;  
kG9aH Ww  
uri h+!R)q8M  
用于确定一个唯一的tag库 kI04<!  
js;YSg{m  
display-name E_$nsM8?  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) ~ArRD-_t  
a%a0/!U[  
small-icon ^~TE$i<   
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) i9rv8 "0>  
~.J*_0~Ze  
large-icon 6vTnm4  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) gaNe\  
8 "NPj0  
description {/N8[?zML  
对tag库的描述(可选) LkK&<z  
DzA'MX  
listener pbqk  
参见下面listener元素 ToKG;Ff4b  
lTN^c?  
tag +_vf=d  
参见下面tag 元素 .X(qs1  
@c"s6h&  
Listener元素 eHGx00:  
:5&UWL|  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 \+/ciPzA-  
thX4-'i  
Tag元素 90Sras>F  
b{ A/M#=  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 -$#2?/uqC  
4bdCbI  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: D%?9[Qb  
z[Qe86L  
Tag元素的子元素 nQ|($V1?W  
@qW$un:  
元素名称 s:_j,/H0A}  
描述 b KIL@AI  
$_eJ@L#  
name +>2.O2)%q  
独一无二的元素名   < /5  
wL]#]DiE  
tag-class snu?+*6  
Tag标签对应的tag处理类 7F]Hq  
E+e),qsbO  
tei-class /zQx}U)TP  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) So~QZ%YA  
Jy "\_Vv l  
body-content 20haA0s  
Tag标签body的类型 `D=d!!1eUi  
j"pyK@v2B  
display-name Z-_Xt^N  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) omPxU2Jw  
1=9GV+`n  
small-icon r58<A'#  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) Y[>h |@  
-`z%<)!Y  
large-icon >o`+j$j  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) UH+#Nel+!  
L})*ck  
description x;} 25A|  
此tag标签的描述 31#jLWY'0  
0Y0`$   
variable nra)t|m  
提供脚本变量的信息(同tei-class)(可选) pStb j`Eq  
N'l2$8  
attribute ;l0%yg/}  
Tag标签的属性名 "H@I~X=  
:9x]5;ma  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 }y J,&N'p  
s?k:X ~m  
SfrM|o  
简单的tag h -091N  
L*4= b (3  
pEN`6*  
tag处理类 t,0}}9%?  
\h0+` ;Q  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 M%Vp_ 0  
OUO'w6m!  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: + !nf?5;  
vgg)f~  
aCIz(3^  
public SimpleTag extends TagSupport \`2EfYJ{  
i&%dwqp  
{ G-]<+-Q$4  
kJNg>SN*@#  
public int doStartTag() throws JspException YD9vWk \/  
BNr%Q:Q  
{ E&L ml?@  
HB*BL+S06  
try{ 'Ce?!U O  
#}~?8/h!  
pageContext.getOut().print(“Hello.”); 5 /oW/2"  
#u\~AO?h  
}catch(Exception e){ z-"P raP  
S+mBVk"-~S  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); I1dOMu9  
Q[H4l({E  
} u%1JdEWZd  
yiH;fK+x  
return SKIP_BODY; ;yjw(OAI*  
Z?9G2<i  
} };Df ><  
Y-+Kf5_[  
public int doEndTag() A5 4u}  
j!;E>`g  
{ ma) + G!  
G@T_o4t  
return EVAL_PAGE; !B9 Yw/Ba  
H ]](xYy.  
} 9q&~!>lt  
gF2 93Ez  
} q%]5/.J  
e~,+rM  
V!TGFo}  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 "^ dMCS@  
B(eiRr3  
<body-content>empty</body-content> f= }!c*l"  
gd7! +6  
E\9HZ;}G  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 8LuU2Lo  
{aopGu?i  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, ~0Zy$L/D  
;uZeYY?   
<logic:present parameter=”Clear”>  91fZ r  
F<*zL:-Z  
与此相应,此tag处理类应有如下方法和定义: /:,}hy+U  
!SLfAFcS  
oIE3`\xS  
protected String parameter = null; \"5p )(  
=dWq B&  
public String getParameter() Vy=+G~  
7MKZ*f@x;  
{ -y$<fu9 e  
lx ~C{tl2  
return this.parameter; o?#-Tkb  
{9Q**U`w  
} O[|X=ZwR:l  
#??[;xjs!  
public void setParameter(String parameter) /}eb1o  
E429<LQI/  
{ N~?#Qh|ZnU  
jPc,+?  
this.parameter = parameter; :C&6M79k  
p<FqK/  
} {t]8#[lo  
&$~irI  
6"r _Y7%  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 :/>Zky8,k  
{aU|BdATI  
Attribute元素 {817Svp@  
A9GSeW<  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 PT4iy<  
.rlLt5b%  
<attribute> _@_EQ!=  
sv6m)pwh  
<name>attr1</name> q1rD>n&d  
ow'CwOj$  
<required>true|false|yes|no</required> [mG!-.ll  
F$YT4414  
<rtexprvalue>true|false|yes|no</rtexprvalue> !bn=b>+  
' Yy+^iCus  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> 2LCOB&-Ww  
[[ll4|  
</attribute> Y44[2 :m  
+h1X-K:I  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 pMf ?'l  
.kfx\,lgm  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 Y7')~C`up^  
/%b nG(4  
<tag> aR)w~s\6  
q{xF7}i  
<name>present</name> yQN^F+.  
EO/41O  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> +u`4@~D#  
@oD2_D2  
<body-content>JSP</body-content> |[)pQGw  
S>s+ nqcP  
+iNp8  
(7"CYAe:;  
<attribute> Y3H5}4QD  
]i>,oxBWe  
<name>parameter</name> sH%Ts@Pl  
wZ_"@j<  
<required>false</required> onIZ&wrk  
5>VX]nE3!  
<rtexprvalue>true</rtexprvalue> {r#uD5NJ/  
-'^:+FU  
</attribute> KppYe9?  
2g5jGe*0  
n.G.f bO  
*bzqH2h8  
</tag> qXoq< |  
R.YUUXT  
sg4(@>  
属性元素的校验 RW<4",  
UMK9[Iy$<M  
blkPsp)m"  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 m\MI 6/  
3XDuo|(  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 1aPFpo!  
'#jZ`  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 Qve5qJ  
hG272s2  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: \:2z!\iP`  
tY#Zl 54~{  
<attribute> `w)yR>lqh  
02-% B~oP  
<name>attr1</name> 6lUC$B Y  
7/)0{B4U'  
<required>true</required> =JxEM7r  
B) dG:~  
<rtexprvalue>true</rtexprvalue> XQ8q)B=  
*aGJ$ P0  
</attribute> C(M?$s`  
4P#4R B  
$v5 >6+-n  
这个定义说明了attr1能在运行期间被赋值。 ~JP3C5q  
|<uBJ-5  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 !=u=P9I  
apnpy\in  
[I7=]X  
Public class TwaTEI extends TagExtraInfo gLK0L%"5  
U U#tm  
{ d ]jF0Wx*  
?A-f_0<0  
public boolean isValid(Tagdata data) ~(:0&w%e  
:m>Vp  
{ Hoi~(Vc.  
{ _Y'%Ggh  
Object o = data.getAttribute(“attr1”); Vt:\llsin  
^oNcZK>  
If(o != null && o != TagData.REQUEST_TIME_VALUE) KEf1GU6s  
3_]QtP3  
{ &-m}w:j=  
p(9[*0.};  
if( ( (String)o).toLowerCase().equals(“true”) || 5Fbb5`(  
<;cch6Z  
((String)o).toLowerCase().equals(“false”) ) fUPYCw6F  
N2lz {  
return true; "~Zdv}^xS  
SL +\{V2  
else EYi{~  
+]0hSpZ"p  
return false; D%6}x^`Qk  
c5pK%I}O  
} - b`  
BgY|v [M&  
else Dj6^|R$z&  
8?|W-rN  
return true; n#B}p*G  
w4zp%`?D'  
} jc@= b:r=  
k L4#  
} fJe5 i6`(  
WcpH= "vm  
C'jCIL  
带body的tag LvU/,.$  
R[TaP 7n  
Mgu9m8 `J  
tag处理类 @gQ?cU7  
fG{3S:TQq  
Bx.hFEL  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 dKL9}:oUa  
z80*Ylx  
Tag处理类不与body交互 `>RM:!m6=$  
h]IoH0/  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 U.ZA%De  
q6x}\$mL  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 :`0,f?cE  
P]L%$!g  
Tag处理类与body交互 579 t^"ja~  
K9 K.mGYc  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 [g{fz3 O6  
{}=5uU2Tu  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 <,H/7Ba  
A>(EM}\,  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 cBHUa}:  
9_Z_5w;h  
doInitBody 方法 #W8c)gkG9  
YF%]%^n  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 nhd.c2t\  
M3dUGM  
doAfterBody方法 ZvK3Su)f1  
@(."[O:  
此方法在body内容已被计算后进行调用。 w2^s}NO  
b>d]= u  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 kHQn' r6  
&]anRT#  
release 方法 `}8)P#  
Cn.dv-  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 8-smL^~%#  
#}8VUbJ  
Z$35`:x&h  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 +.$:ZzH#  
[T,Df&  
DYe w6B-  
Public class QueryTag extends BodyTagSupport ]]5(:>l  
F'_z$,X6  
{ .li)k[] ts  
#X6=`Xe#  
public int doAfterBody() throws JspTagException P#;pQC  
kjSzu qB  
{ -7EwZRS@9  
472'P  
BodyContent bc = getBodyContent(); 5F :\U  
P+3 ]g{2w  
//将body的内容以字符串的格式提取出来 ]0{,P !  
&((04<@e  
String query = bc.getString(); dE (d'*+a  
!'>#!S~h3  
//清除body d 5h x%M  
>q&e.-qL  
bc.clearBody(); *LvdrPxU=  
UG6\OgkL+  
try{ 9s*UJIL  
I."s&]FZ  
Statement stmt = connection.createStatement(); y cWY.HD  
u#->?  
Result result = stmt.executeQuery(query); qz!^< M  
q"LT8nD\  
}catch(SQLException e){ 6-nf+!#G  
frWY8&W^H  
throw new JspTagException(“queryTag: “ + e.getMessage() ); "7?xaGh8  
1+tPd7U  
return SKIP_BODY; ^SwU]e  
ikPr>  
} 2%]#rZ  
gOaK7A  
} w *o _s  
EV~?]Kt~  
5%DHF-W)  
body-content元素 Rr\fw'  
vLCm,Bb2L  
73!])!SVI  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: <*p  
[,|4%Y  
<body-content>JSP|tagdependent</body-content> v\XO?UEJ2  
Ba n^wX  
=1mIk0H`  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 X`I=Z ysB  
|@)jS.Bn  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 {_4zm&  
 o7AI  
r \} O{ZO  
用tags定义脚本变量  <XnxAA  
2{L[D9c/6  
*(VwD)*  
tag处理类 ?gXdi<2Qn  
 V#+J4   
f:9qId ;/M  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 <|:$_&(  
`iwGPG!  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 3d_g@x#9  
) KYU[  
对象的生存周期(scope)如下表: c*)PS`]t  
&Fch{%S>  
对象的生存周期表 =Flr05}m  
m=]}Tn  
名字 * @&V=l  
可访问范围 d,t'e?  
生存周期 &|Vzo@D(!  
8noo^QO  
page 75']fFO@!  
当前页面 =5h ,ZB2A  
一直有效,除非页面向客户提交响应或重定向到一个新页面 M,P:<-J  
0O?!fd n  
request bj 0-72V  
当前页面或当前页面重定向到的页面 W-vEh  
一直有效,除非页面向客户提交响应 X""}]@B9z  
6^nxw>-   
session 4n.EA,:g:(  
当前页面或在同一浏览器窗口中的页面  ~&_BT`a  
一直有效,除非关闭当前浏览器、超时、网络故障 `I5So-^&z  
b"~Ct}6f  
application DQ_ pLXCC  
整个web应用程序的所有请求 zMAlZ[DN  
一直有效,除非发生网络故障、服务器故障 qTnk>g_oS&  
Pv3 e*I((  
提供关于脚本变量的信息 UC"_#!3  
n UD;y}}n  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: b#_u.vP  
a]R1Fi0n  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> z%L\EP;o}  
`~ R%}ID  
<font color=”red” size=”+2” > :FI 4GR*?  
p87VJ}  
<%= messages.getString(“CartRemoved”) %> K]Q1VfeL=  
$:0?"?o);  
<strong><jsp:getProperty name=”book” property=”title” /></strong> </7?puVR  
4B@L<Rl{\  
</font> iYzm<3n?  
1V2"sE  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: ?rv5Z^D'  
&V7{J9  
· 脚本变量名称 /9 soUt  
o2NU~Ub  
· 脚本变量所属的类 E3o J;E  
/'>#1J|TlK  
· 此脚本变量是否引用了一个新的或已存在的对象 '~kAsn*/  
dK?vg@|'  
· 此脚本变量的有效性 4krK CD>|G  
YW)& IA2  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 Nn|~ :9#  
%NfbgJcL_  
Variable元素 swT/ tesj  
1\BQq  
Variable元素有如下子元素: 9WsGoZP n  
+;wu_CQu  
· name-given ?D?D 给出的名字,是一个常量 <Q? X'.  
<YBA 7i  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 L&SlUXyt.c  
?W4IAbT\G  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: ^H UNq[sQ  
4F>?G{ci  
· variable-class?D?D变量的类型,缺省为java.lang.String。 I^fKZ^]8P  
QBfsdu<@^  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 O&u[^s/^  
Ok&u4'<  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: _,;|,  
F;^GhiQVS  
脚本变量的有效范围 !|gln)|A  
]za1=~[  
.I&]G  
有效性 @I^LmB9*  
方法 U[UjL)U  
7 -hSso.'  
NESTED lnoK.Vk9,  
在tag标签的开始和结束之间 L5tSS=  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 O7z -4r  
L0H kmaH  
AT_BEGIN l|P(S(ikh  
从tag标签的开始一直到页面结束 2|n~5\K|t  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 wLf=a^c#  
J9 iQW  
AT_END FF"`F8-w>Z  
从tag标签的结束一直到页面结束 n-7|{1U  
在doEndTag中调用 ,!?&LdPt>  
k )T;WCia  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: hw [G  
K2glkGK  
<tag> _pv<_ Sm  
R8 lBh Ls  
<variable> 45;{tS.z,B  
CYZx/r<  
<name-from-attribute>id</name-from-attribute> ?=;dNS@i@  
BtN@P23>k.  
<variable-class>database.BookDetails</variable-class> )wROPA\uA  
> ^b6\  
<declare>true</declare> gUoTOA,  
"3"9sIZ(  
<scope>AT_BEGIN</scope> U0/X!@F-  
MDCK@?\  
</variable> l`s_ #3  
k]=Yi;  
</tag> $6a55~h|(  
=sk]/64h``  
额外tag信息类 }.x&}FqXE  
i#M$i*H*A  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息:  d!%:Ok  
4epE!`z_&  
· 变量名 i(XcNnn6  
*LbRLwt  
· 变量所属类名 'W/E*O6BY  
_T 5ZL  
· 此变量是否引用了一个新对象 iv*Ft.1t  
-$#'  
· 此变量的有效范围 ptXLWv`  
E5P?(5Nv  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 :6 ?&L  
P%v7(bqL4+  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: TixXA:Mf  
.r/6BDE"  
.FS`Fh;  
public class DefineTei extends TagExtraInfo vt3yCS  
w6M EY"<L  
{ G(-1"7  
}>\+eG  
public VariableInfo[] getVariableInfo(TagData data) %G& Zm$u=  
}kaU0 P  
{ = X?jId{  
s5X .(;+  
String type = data.getAttributeString(“type”); <0!/7*;#ZT  
*,Bo $:(n  
If( type == null) Ik_u34U  
}lZfZ?oAz  
type = “java.lang.Object”; ~Xa8\>  
bnS"@^M  
return new VariableInfo[] { JY4sB8  
XD>(M{~  
new VariableInfo(data.getAttributeString(“id”), IyvJwrO  
f=%k9Y*)  
type, We]mm3M3  
NijvFT$V1  
true, 8. 9TWsZ  
A1`y_ Aj  
VariableInfo.AT_BEGIN) =<nx [J  
uZ}=x3B  
}; 4 \*!]5i  
s>8;At-  
} biZwxP3  
Dk$[b9b  
} 34lt?6%j  
~s_n\r&23  
P{qi>FJqe  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: %J`cYn#  
<tei-class> `Oxo@G*@}W  
org.apache.struts.taglib.bean.DefineTagTei rSGp]W|  
</tei-class> ]F:5-[V#  
+r0ItqkM  
Z]H`s{3  
具有协作关系的tag rp*f)rJ  
C^sHj5\(  
c#l W ?  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 ")%)e;V3  
W-9?|ei  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 y_bb//IAG  
V-Ebi^gz5W  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 ESdjDg$[u  
.<Y7,9;YEF  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 Y/\y"a  
laVqI|0q  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。  WW5AD$P*  
Y](kMNUSg  
sdkKvo. y0  
public class QueryTag extends BodyTagSupport 5r#0/1ym!  
}A@op+0E  
{ .L;M-`^  
@f<q&K%FJ  
private String connectionId; u,]?_bK)  
3C8cvi[IS  
public int doStartTag() throws JspException G&P[n8Z$  
1:2 t4}  
{ [l;9](\8O  
]w2nVC 3  
String cid = getConnection();  U/v }4b  
U Ke!zI  
if(cid != null) v[S>   
FdT@}  
{ Yvky=RM  
-oSfp23u  
//存在一个connection id,使用它。 9 gt$z}oU  
.c#G0t<i[  
connection = (Connection) pageContext.getAttribute(cid); TL%2?'G  
oA_T9uh[  
} .Y;ljQ  
3ya_47D  
else ZbS* zKEW  
`/WX!4eR,  
{ UZsn14xSA  
/5@4}m>Z@  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, :Taequk  
6 w"-&  
ConnectionTag.class); +4<Ij/}p  
&~ =q1?  
if(ancestorTag == null) 8T3j/ D<r  
3vs;ZBM  
{ zq(R!a6  
Q& p'\6~  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); Aw]W-fx  
r!DUsE  
} VK7lm|J+  
gEFs4; CN  
connection = ancestorTag.getConnection(); }E?{M~"<  
sA( e  
} y'gIx*6B@  
xMck A<E  
} 9rO,h|L   
8Ja't8  
} D;~c`G "f  
4d\1W?i-  
3`V #ImV>  
[QC|Kd^#  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: %XIPPEHU  
;QVX'?  
Gag=GHG  
<tt:connection id=”con01” ...> ... </tt:connection> LV$@J  
zkFx2(Hq-f  
<tt:query id=”balances” connection=”con01” > 2m$\]\kCUv  
%hEhZW{:  
SELECT account, balance FROM acct_table Oy> V/  
F=/@D)hND  
where customer_num = <%= request.getCustno() %> h]|E,!H  
KJ/ *BBf  
</tt:query> HY (|31  
D_n(T ')  
)0RznFJ+X  
BQ\o?={  
P, (#' W  
<tt:connection ...> P5vxQR_*lc  
@j|B1:O  
<x:query id=”balances”> az5 $.  
b+Ly%&  
SELECT account, balance FROM acct_table +:JyXF u  
g\Ck!KJ/y  
where customer_num = <%= request.getCustno() %> -+#QZ7b  
s<}d)L(  
</x:query> ^#^\@jLm  
jJ(()EJ  
</tt:connection> 8efQ -^b.  
]<9KX} B  
Sqt '}  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: yXuc< m  
!|SVRaS  
<tag> Rds_Cd C  
!!jitFHzb  
... nPAVrDg O  
g~>g])  
<attribute> DU@ZLk3  
%Ls5:Z=  
<name>connection</name> L?W F[nF R  
G;^},%<  
<required>false</required> {$dq7m(  
tEj-c@`"x-  
</attribute> Oa8lrP`(  
\( S69@f  
</tag>
描述
快速回复

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