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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! xZMAX}8v  
"!o|^nN,  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 C^ ~[b o  
n1y*`5!  
在这篇文章中,我们主要讨论: wqt/0,\  
1(a+|  
· 什么是自定义tag标签? O]9PYv=^  
S^SF!k=  
· 怎么使用tag标签? `{nzw$  
QLH6Nmk  
o 声明要使用的tag库 MBFn s/  
}Szs9-Wns  
o 找到与之对应的tag处理类 tHH @[E+h  
tj" EUqKQ  
o tag标签的类型 };~I#X  
YD;"_yH  
· 自定义tag标签 v<]$,V]  
9 E  
o tag处理类 e[.JS6  
hJoh5DIE95  
o tag库描述 E@)9'?q  
D{]9s  
o tag标签示例 $4>x4*  
E vD g{M}  
o 带属性的tag k= .pcDX  
6p~8(-nG  
o 带body的tag jbu+>  
2,'%G\QT  
o 定义了脚本变量的tag f_r4*#&v  
7pZd?-6M^  
o 具有协作关系的tag l]geQl:7`r  
^A t,x  
· 自定义tag标签 &jF[f4:7  
(=QiXX1r  
o 一个迭代tag的例子 G -RE  
o:RO(oA0?  
o 一个模板tag库 >m`<AynJ  
!4fT<V (  
o tag处理类到底是怎样被调用的? Y ^}c+)t  
WeS$$:ro  
P<R'S  
什么是自定义的tag? f:/"OCig  
 @@+BPLl  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 *>7Zc  
#}nDX4jI  
自定义tag标签有很多特色,诸如: @D=i|f  
Ug^vVc)  
· 可以在JSP页面中自定义tag标签的属性 bqm%@*fZo  
Qr*7bE(a  
· 访问JSP页面中的所有对象 +bcJm  
G/_9!lE  
· 可以动态地修改页面输出 1(m[L=H5>  
jRSY`MU}t+  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 zFO#oW,D  
]*yUb-xY  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 sj%\lq  
Xwk_QFv3  
M[5fNK&nD  
使用tag标签 4mwAo  
uBxs`'C  
%9`\ 7h7K  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 "5$2b>_UE  
Y-:dPc{  
要使用tag标签,JSP程序员必须做2件事: v\Xyz )  
C3e0d~C  
· 声明此tag标签的tag库 ;Qdw$NuW  
:pg]0X;  
· 实现此tag标签 } !RBH(m%  
4j-%I7  
声明tag标签所在的tag库 s7na!A[  
LE4P$%>H  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) HT=-mwa_]  
]MV=@T^8#  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> bRK[u\,  
0z=^_Fb  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 rn%q*_3-o  
WRfhxl  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 3^p;'7x  
Vi\kB%  
以下taglib指示符直接引用一个TLD: ./E<v  
C;oT0(  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> 'n4 iW  
GF^ ?#Jh  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: qZDP-  
dp#'~[j  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> JAP4Vwj%j  
s<fzk1LZ  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: n*vhCeL  
. I#dR*  
<taglib> dpI! {'"M  
!ZTBiC5R  
<taglib-uri>/tutorial-template</taglib-uri> 3q:>NB<  
Bq#B+JwX  
<taglib-location> K._* ~-A  
gqQ"'SRw  
/WEB-INF/tutorial-template.tld lc\f6J>HT  
nM6/c  
</taglib-location> X1~ WQ?ww  
]R8JBnA  
</taglib> 8d*W7>rq  
g0-J8&?X  
p;YS`*!s  
实现此tag标签 s!F` 0=J^  
2]f?c%)I  
])uhm)U@  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 ; `-@L  
k<!xOg  
xE%sPWbj  
tag标签类型 )NL_))\  
$WHmG!)*  
)6 [d'2  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): #a=~a=c(^  
v* /}s :a  
<tt:tag> `%A>{A"  
k&SI -jxj  
body xO2CgqEb  
p}O[A`  
</tt:tag> x^P~+(g  
>'96SE3  
0dKi25J  
一个不带body的tag标签如下: *Z C$DW!-  
Hlye:.$  
<tt:tag /> J}37 9  
bO\E)%zp  
a>XlkkX  
简单的tag标签 S67>yqha  
@Zov&01  
一个没有body和属性的tag标签如下: -iJ @K  
;Alw`'  
<tt:simple /> EwH_k  
7z^\}&  
t~@~XI5  
带属性的tag标签 Z/w "zCd  
x;p7n 2_  
47 *,  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 [Uw/;Kyh  
z9 )I@P"  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: L>Soj|WUy(  
Xj("  
<loglic:present parameter = “Clear”> [[ ;vZ  
!$5.\D  
而另一个标签logic:iterate是用表达式来给属性赋值: FF7  
>@wyiBU  
<logci:iterate collection=”<%= bookDB.getBooks() %>” ?RVY%s;g  
_k2*2db   
id=”book” type=”database.BookDetails”> nFY6K%[  
VQ((c:+!  
/WWD;keP5  
带body的tag标签 :Mq-4U.e  
v<c@bDZ>  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 d0MF\yxh  
.S =^)  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: qe"t0w|U?  
7 G<v<&  
<logic:present parameter=”Clear”> us TPr  
~Dz`O"X3  
<% cart.clear(); %> ?*h 2:a$  
&m J +#vT  
<font color=”#ff0000” size=”+2”><strong> ~i ImM|*0  
g8^YDrH  
你选择了清除购物车! ,Kw]V %xOb  
B qA  
</strong></font> xesZ 7{ o  
G(6MLh1  
</logic:present> )r^)e 4UI  
3 2MdDa  
Fv(1A_~IS  
到底是用属性还是用body来传递信息? mz kv/  
rp^G k  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 /9..hEq^  
NiCB.a  
drc]"6 k  
定义脚本变量的tag标签 A:-r 2;xB  
quEP"  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: lE@ V>%b  
d}`Z| ex  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> {j{H@rHuy  
5o&noRIIr  
<% tx.begin(); %> gN("{j1Q  
4$^\s5K  
... ]gHi5]\NC  
sS5:5i  
h &R1"  
具有协作关系的tag标签 ,|r%tNh<8$  
D#I^;Xg0h  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 CCQ38P@rv  
a\BV%'Zqg  
<tt:tag1 attr1=”obj1” value1=”value” /> fI([vI  
|)pRkn8x  
<tt:tag2 attr1=”obj1” /> 8:)W!tr  
v3`k?jAaI  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 ;I^+u0ga  
,4&?`Q  
<tt:outerTag> v==b. 2=  
BlrZ<\-/  
<tt:innerTag /> wG\ +C'&~  
hhU: nw  
</tt:outerTag> 'zg; *)x1/  
nGqD{!i<  
O ^+H:Y|  
Tag处理类 yD-L:)@"  
7ZsBYP8%  
k,mgiGrQ  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 c\\'x\J7  
sOY+ X  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 f0lpwwe  
OdrnPo{  
下表说明不同类型的tag所需要不同的处理过程: ?{Rv/np=F  
i6Kcj  
Tag处理类的方法 \=yWJ  
=5v=<, ]  
Tag标签类型 */7+pk(  
所调用的方法 T|o ]8z  
;;#_[Zl  
基本标签 nH=8I~jp  
doStartTag, doEndTag, release R;]z/|8  
mz'r<v2Tc  
带属性的标签 = @EN]u  
doStartTag, doEndTag, set/getAttribute1...N, release Ac2,A>  
BsJ d*-:X  
带内容的标签 ,3As Ng  
doStartTag, doEndTag, release DNGXp5I  
qz@k-Jqq d  
带内容的标签,且内容重复循环 |*T3TsP u  
doStartTag, doAfterBody, doEndTag, release ~g|Z6-?4Jj  
B,_/'DneQK  
带内容的标签,且内容与JSP交互 !)1gGXRY  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release M:9 6QM~  
m 3 Y@p$i5  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 fQkfU;5  
t6+c"=P#  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 ]"2;x  
C2[* $ 1U  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 XDtMFig  
1[g -f ,  
uSl&d  
Tag库描述(简称TLD) u3B[1Ae:K  
6Kbc:wlR  
E<~Fi .M;\  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 X^td`}F/=V  
djk?;^8  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 =,])xzG%  
T{"[Ih3Mbl  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: E0s|eA&  
(T9Q6 \sa  
<?xml version="1.0" encoding="ISO-8859-1" ?> DT Cwf  
J dK' ~-L  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> _-M27^\vV  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: S#^2k!(|G  
5OR2\h!XZt  
&&daQg4Ha  
<taglib>的子元素 nhu;e}[>  
+}.~"  
Element R_7[7 /a  
Description wigs1  
QCD MRh n  
tlib-version g5OKhL0u  
Tag库的版本 x%!Ea{ s  
2&,jO+BqE@  
jsp-version tpY]Mz[J  
Tag库所需要的jsp的版本 nc2=S^Fqu  
RXD*;B$v  
short-name X>la!}sV  
助记符,tag的一个别名(可选) p|gzU$FWbk  
:Rftn6!  
uri J\@W+/#dF  
用于确定一个唯一的tag库 !2o1c  
MP3Vo|}3  
display-name i!a. 6Gq  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) Sf>#Zqj/  
$0mR_pA\fW  
small-icon pK|~G."6e  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) -P.51q  
F4*ssx  
large-icon g!\H^d4  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) @BmI1  
;}dvc7  
description F<+!28&h  
对tag库的描述(可选) [X%Wg:K  
Z^[ ]s1iP}  
listener j%`% DQ  
参见下面listener元素 4F`&W*x  
_t/~C*=:=  
tag BI|TM2oa  
参见下面tag 元素 z%E ok  
(B^rW,V[R  
Listener元素 M/mm2?4  
 ;H4s[#K  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 !\}X?G f  
B" 0a5-pkr  
Tag元素 1s_N!a  
P U2^4h/[`  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 o}p^q:T*  
)4e8LO  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: B6yTD7  
{6tj$&\)  
Tag元素的子元素 WbWEgd%8.  
5<>"d :9  
元素名称 ^ 7SE2Zi  
描述 T! ww3d  
>\o._?xSA  
name Ab In\,x  
独一无二的元素名 kj>!&W57  
;I/ A8<C  
tag-class i,B<k 0W9  
Tag标签对应的tag处理类 dJjkH6%}  
4o<rj4G>  
tei-class #I"s{*  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) [0n[\& 0  
3OB=D{$V  
body-content x:6c@2  
Tag标签body的类型 ,(A $WT@e  
YvG=P<_xw  
display-name eev-";c  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) B2,c_[UZ.  
)kT.3 Q  
small-icon {ldt/dl~  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) bP Q=88*  
^m/7T wD  
large-icon ^~;"$=Wf  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) agkGUK/  
+^DDWVp  
description QnA~,z/ .w  
此tag标签的描述 }n( ?|  
;Rljx3!N  
variable {SkE`u4Sz  
提供脚本变量的信息(同tei-class)(可选) f#kT?!sP  
+'$5Jtz  
attribute :>y;*x0w  
Tag标签的属性名 X`fb\}~R(  
ka_(8  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 jVPX]8  
S J2l6  
al"=ld(  
简单的tag f~10 i D  
[jv+Of IZ  
)|=4H>?%  
tag处理类 I.[Lv7U-  
}/lyrjV  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 P-/"sD  
E)`:sSd9  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: }P'c8$  
,`bmue5  
klR\7+lK  
public SimpleTag extends TagSupport . 1+I8qj  
+BVY9U?\"  
{ E/zclD5S  
A5T&i]  
public int doStartTag() throws JspException '3 b'moy  
X'88W-  
{ M@z_tR'3\  
.JOZ2QWm<  
try{ oOHY+'V  
a4[t3U  
pageContext.getOut().print(“Hello.”); Q5b9q$L$  
e%lxRN"b  
}catch(Exception e){ jV[;e15+  
8iTB  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); xnf J ruT  
4f&"1:  
} ? G`6}NP  
.8->n aj|  
return SKIP_BODY; J&iSS9c  
_X|prIOb=  
} R@-x!*z  
a^8PB|G  
public int doEndTag() '55G:r39  
I~;w Q  
{ { V) `6  
2M*i'K;;)P  
return EVAL_PAGE; 58d[>0Xa[g  
\wD L oR  
} r1TdjnP,2^  
H,c`=Ii3  
} Gr4v&Mz:  
K9-9 c"cz  
Cv@)tb  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 n.rn+nuwv  
nEUUD3a  
<body-content>empty</body-content> ps;dbY*s6  
%E5b }E#  
Y]7503J  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 Jt[,V*:#  
"g)V&Lx#X  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, t>AOF\  
=7JSJ98  
<logic:present parameter=”Clear”> q-+:1E  
Rpv[rvK'  
与此相应,此tag处理类应有如下方法和定义: %ioVNbrR7  
S@Rd>4  
0QT:@v2R  
protected String parameter = null; -|Zzs4bx  
ALy7D*Z]w  
public String getParameter() /`l;u 7RD  
Q`W2\Kod]  
{ 2l O(f+  
$~iZaX8&  
return this.parameter; zPc"r$'0 U  
h=0a9vIXF  
} P%)r4+at  
Ix6\5}.c9  
public void setParameter(String parameter) cFt&Efj  
XPU>} 4{  
{ |1 "&[ .  
/OWwC%tM/  
this.parameter = parameter; xnt)1Q  
oOaFA+0x  
} |?#JCG  
aopZ-^  
#-\5O  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 DnFzCJ  
4qz+cB_  
Attribute元素 ZMb+sUK  
Y+ UJV6  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 Ps>:|j+  
9OV@z6  
<attribute> YR*gO TD  
rD~/]y)t  
<name>attr1</name> .wD $Bsm`t  
 0U@#&pUc  
<required>true|false|yes|no</required> }L)[>  
GTM0Qvf?  
<rtexprvalue>true|false|yes|no</rtexprvalue> ;aV3j/  
L FkDb}  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> vMB61 |O  
aZ4?! JW.  
</attribute> kqm(D#  
aTTkj\4  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 RARA_tii  
VaY#_80$s  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 k9f|R*LM  
>]pZ;e$  
<tag> |67Jw2  
L?j0t*do  
<name>present</name> j(Lz& *4  
P*A+k"DU1  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> Yu\$Y0 {]  
XZ~kXE;B(  
<body-content>JSP</body-content> .Pponmy  
a1~|?PCbY  
tg@61V?>  
A{ ~D_q  
<attribute> -n&&d8G^s  
:31_WJ^  
<name>parameter</name> ()IZ7#kL?  
Ik$$Tn&;  
<required>false</required> le\-h'D  
*,4rYb7I w  
<rtexprvalue>true</rtexprvalue> pE&G]ZC  
V ml 6\X  
</attribute> wn5OgXxG<  
"D _r</b  
=^rt?F4  
lc[6Mpi7s[  
</tag> ywAvqT,  
dGYR  'x  
M; wKTTQy  
属性元素的校验 l.o/H|  
Qc3d<{7\~  
Dj(PH3^  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 |${4sUR  
Ze~P6  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 Uv(R^50>  
22ON=NN  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 7]vmtlL  
`!vqT 3p,  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: `FPQOa*%3  
94+^K=lAX  
<attribute> }ouGxs+^[  
{&n- @$?  
<name>attr1</name> zsXgpnlHT  
Pp-N2t86#2  
<required>true</required> *~)6 sm  
E:x@O8F  
<rtexprvalue>true</rtexprvalue> g:M;S"U3*Y  
K<e #y!  
</attribute> yMz#e0k  
m"n74 cxS  
hn8xs5vN  
这个定义说明了attr1能在运行期间被赋值。 -lhIL}mGf  
k sv]  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 x vs=T  
.jCGtR )%  
X[o+Y@bc  
Public class TwaTEI extends TagExtraInfo !0,q[|m  
Wlhh0uy  
{ T]De{nHu  
SA +d4P_T  
public boolean isValid(Tagdata data) e,xL~P{|  
z< L2W",  
{ EfEgY|V0  
e P@#I^_  
Object o = data.getAttribute(“attr1”); \#HW.5  
JD$g%hcVZa  
If(o != null && o != TagData.REQUEST_TIME_VALUE) YGo?%.X  
 4u:SE   
{ }gkLO TJ/,  
;d6Dm)/(  
if( ( (String)o).toLowerCase().equals(“true”) || BYq80Vk%@  
mKZzSd)p  
((String)o).toLowerCase().equals(“false”) ) eTa_RO,x  
,ErfTg&^  
return true; zWEPwOlI1P  
 O`@Nl  
else G ?$ @6  
Ab@ G^SLX  
return false; irAXXg  
!q2zuxq!R  
} D.a>i?W  
Q/S ^-&~  
else -{\(s=%  
#%"G[B  
return true; Zk=,`sBC  
kEDpF26!  
} duG3-E  
(bb!VVA  
} y!=,u  
7[1Lh'u  
SboHo({5VA  
带body的tag wb$uq/|  
CeYhn\m5K0  
4-yK!LR  
tag处理类 CVfV    
e34>q:#5l  
ZM.'W}J{ *  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 Z=]SAK`  
zKd@Ab  
Tag处理类不与body交互 XDY]LAV  
U!(.i1^n  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 [[$C tqLg  
~m6=s~Vn  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 hp~q!Q1=  
cU6*y!}9  
Tag处理类与body交互 B]X8KzLu  
"#~>q(4^  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 w5%Yi {  
t8*Jdd^3Z/  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 UGO#o`.G}  
(.4lsKN<  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 Tvx1+0Z%z  
)=5 &Q  
doInitBody 方法 aD: #AmbJ  
>&(#p@#  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 nJ;^Sz17Q  
:AzT=^S  
doAfterBody方法 P 2WAnm  
oai=1vt@  
此方法在body内容已被计算后进行调用。 |oPRP1F-;e  
GKt."[seV  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 36=aahXd\  
(uC8M,I\  
release 方法 fu5L)P^T  
q/ljH_-  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 -ZaeX]^&Q\  
b}K,wAx  
pl]|yIZ  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 KqFI2@v   
i=gZ8Q=H  
, #)d  
Public class QueryTag extends BodyTagSupport Af _4Z]F  
{M**a  
{ L2XhrLK.|  
n\"6ol}>E  
public int doAfterBody() throws JspTagException c~ R'`Q  
Xd(^7~i  
{ XKWq{,Ks  
,\M77V  
BodyContent bc = getBodyContent(); xgk~%X%K  
kq}byv}3I  
//将body的内容以字符串的格式提取出来 tpJA~!mG3  
DPI[~  
String query = bc.getString(); B\Nbt!Ps  
'7?Y+R@|L  
//清除body Tdi^P}i_  
=~;~hZj  
bc.clearBody(); 8US#SI'x  
GLf!i1Z  
try{ r9ulTv}X  
Dj\nsc@e3  
Statement stmt = connection.createStatement(); _WEJ,0* #'  
H,(vTthd  
Result result = stmt.executeQuery(query); #~ x7G  
`p()ko  
}catch(SQLException e){ u9"=t  
7P<VtS  
throw new JspTagException(“queryTag: “ + e.getMessage() ); h&'|^;FM  
l'"nU6B&  
return SKIP_BODY; &ksuk9M  
D;R~!3f./b  
} /QQRy_Z1)  
kE:[6reG  
} NH/A`Wm  
Tx.N#,T|  
}t^wa\   
body-content元素 u$d[&|`>_  
6}6Q:V|  
*)E${\1'<  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: d"FB+$  
G0 )[(s  
<body-content>JSP|tagdependent</body-content> LzU'6ah';5  
E f\|3D_  
^2k jO/  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 Rt#QW*h\|i  
YmC}q20;  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 r XJx~ g  
_KM? ?&  
}B-$}  
用tags定义脚本变量 lUu0AZQmG  
QD@O!}; T  
?\Z pVL<>  
tag处理类 w % Hj'  
M@.l# [@U  
(l99a&] t  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 7fR5V  
yI^Yh{  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 "L~Oj&AN[  
:M"+  
对象的生存周期(scope)如下表: _WZx].|A=  
F+hV'{|w`  
对象的生存周期表 G=cRdiy`C  
t<v.rb  
名字 :`N&BV  
可访问范围 TanWCt4r  
生存周期 ZO%^r%~s  
LQ~|VRRX<  
page v[ iJ(C_  
当前页面 '7'/+G'~&  
一直有效,除非页面向客户提交响应或重定向到一个新页面 jF?0,g  
\ *t\=4  
request DSLX/u o1  
当前页面或当前页面重定向到的页面 5sJ>+Rg  
一直有效,除非页面向客户提交响应 fJ*^4  
(9u`(|x  
session k{+cFG\C&  
当前页面或在同一浏览器窗口中的页面 q9vND[BQ  
一直有效,除非关闭当前浏览器、超时、网络故障 4FaO+Eo,8  
Z|_V ;*  
application #f#6u2nF\  
整个web应用程序的所有请求 3 `_/h' ~  
一直有效,除非发生网络故障、服务器故障 Xe);LhDC  
O&7.Ry m  
提供关于脚本变量的信息 GN|"RuQ  
PlB3"{}0Q  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: .s<0}<Aq>  
fS"u"]j*e  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> Nw. )O  
] 0R*F30]  
<font color=”red” size=”+2” > =aVvv+T  
7]rIq\bM  
<%= messages.getString(“CartRemoved”) %> nFlN{_/  
fK7 ?"^`/  
<strong><jsp:getProperty name=”book” property=”title” /></strong> xo@1((|z  
25OQY.>bE  
</font> +t,b/K(?]  
I%.nPOQ 8  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: $s _k/dM~&  
M]o]D;N~l  
· 脚本变量名称 vl/!w2  
}[eUAGhDU  
· 脚本变量所属的类 &0T.o,&y  
r%;|gIky  
· 此脚本变量是否引用了一个新的或已存在的对象 Y7S1^'E 3  
dz@+ jEV  
· 此脚本变量的有效性 nq_$!aB_K  
9fX0?POG  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 ZRjM^ d;  
x;W!sO@$  
Variable元素 ,[ 2N3iH  
7FH-l(W  
Variable元素有如下子元素: M %,\2!$  
q;9X8 _  
· name-given ?D?D 给出的名字,是一个常量 p.:|Z-W$  
RZxh"lIo  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 a?W5~?\9  
B*G]Dr)e  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: cWQJ9.:7  
@|(cr: (=H  
· variable-class?D?D变量的类型,缺省为java.lang.String。 ;jgf,fbM  
pBAAwHD  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 `RY}g;  
DQ0S]:tC  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: ZW?h\0Hh  
-9 LvAV>  
脚本变量的有效范围 P'h39XoZ  
IS8 sJ6")  
V~PGmn[V  
有效性 ]n4PM=hz  
方法 ;C-ds  
}h1BAKg  
NESTED {eU>E /SQ  
在tag标签的开始和结束之间 p@78Xmu?q  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 UG.:D';3,  
$x }R2  
AT_BEGIN { 5r]G  
从tag标签的开始一直到页面结束 GpPM?  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 i?B<&'G  
T ?Om]:j  
AT_END 7s%D(;W_Mo  
从tag标签的结束一直到页面结束 GipiO5)1C  
在doEndTag中调用 X#T|.mCdC  
6c+29@  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: ~0CNCP  
OR&pGoW  
<tag> 4j;IyQDvM  
qdQ4%,E[  
<variable> ?n<F?~  
ot7f?tF2<J  
<name-from-attribute>id</name-from-attribute> to13&#o  
!9gpuS[  
<variable-class>database.BookDetails</variable-class> %(s|  
=X(N+(1~  
<declare>true</declare> 'sAkrl8kt  
~V(>L=\V;  
<scope>AT_BEGIN</scope> 8/2Wq~&  
UK OhsE  
</variable> .;31G0<w2  
u"5/QB{  
</tag> J4]"@0?6  
Hd4 ~v0eS  
额外tag信息类 iM!V4Wih6  
3T(ft^~  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: >? o5AdZ  
oBmv^=cH  
· 变量名 yVzV]&k  
&H+ wzx<  
· 变量所属类名 o?O ZsA  
lLVD`)  
· 此变量是否引用了一个新对象 R)d_0Ng  
3B[tbU(  
· 此变量的有效范围 4qDa: D"5  
g&RhPrtl  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 `Zp*?  
(M;d*gN r  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: 5<X"+`=9  
,h5 FX^  
`!N.1RP _  
public class DefineTei extends TagExtraInfo Wv5=$y  
>mQD/U  
{ Up-^km  
?/}IDwuh  
public VariableInfo[] getVariableInfo(TagData data) /  !h<+  
K4Ed]hX  
{ ?`vGpi~  
e]1) _;b*  
String type = data.getAttributeString(“type”); Dg^s$2  
+ d>2'  
If( type == null) J%Y-3{TQK  
wR 2`*.O  
type = “java.lang.Object”; Nba1!5:M  
LB7$&.m'B  
return new VariableInfo[] { &%3}'&EBv  
T#E,^|WEk  
new VariableInfo(data.getAttributeString(“id”), M+-odLltw  
cl23y}J_?  
type, c(Xm~ 'jeH  
.4 NcaMj  
true, 1OY 5tq  
z xgDaT  
VariableInfo.AT_BEGIN) &B8x0 yi  
EP4?+"Z  
}; g:^Hex?Yfd  
&iuMB0rbu  
} Yk{4 3yw  
mr>E'd.'  
} rf/]VAK  
1"A"AMZf  
T*k{^=6"!  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: s Wj:m)  
<tei-class> {o'(_.{  
org.apache.struts.taglib.bean.DefineTagTei ]q #"8 =  
</tei-class> m{*_%tjN0  
O~Jf"Ht  
UM1h[#?&V)  
具有协作关系的tag d|tNn@jN  
z\k 6."e_&  
Hm 0;[i  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 2e,cE6r  
 (=%0x"'  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 EwfL.z  
OS~Z@'Eg  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 BMzS3;1_  
d^Cv9%X  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 mg3YKHNG  
o -x=/b  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 9-Qu5L~  
Ta8lc %0w3  
% Q93n {?  
public class QueryTag extends BodyTagSupport ,=u!hg  
yBqKldl  
{ >U:.5Tch'V  
O8*yho  
private String connectionId; 1OFrxSg  
z4[ 8*}  
public int doStartTag() throws JspException /GP:W6:6z6  
LqQ&4I  
{ V'N]u (^  
\ 0F ey9c  
String cid = getConnection(); 3 lKBwjW  
CTB qX  
if(cid != null) 30cb+)h(  
"f!H[F1~  
{ zM%2h:*+{  
E zU=q E  
//存在一个connection id,使用它。 ]D>\Z(b  
x50ZwV&j  
connection = (Connection) pageContext.getAttribute(cid); -C* UB  
.A6Jj4`-  
} ?Ql<s8  
|dqAT.  
else K}dvXO@=|c  
D<4cpH  
{ .L3D]  
v00w GOpW  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, XJ1<!tl  
Vg`32nRN  
ConnectionTag.class); yD^Q&1  
c_6~zb?k+m  
if(ancestorTag == null) h],l`lT1\  
}(UU~V  
{ >s%m\"|oh  
/n9,XD&)  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); V*+Z=Y'  
IDt7KJ@hc  
} @ ojV8  
&~N@M!`Dn  
connection = ancestorTag.getConnection(); kSqMI'89  
0e~4(2xK  
} Q$S|LC  
D14i]  
} qAVZ&:#  
Z&Z= 24q_  
} Z-'xJq  
"&TN}SBW  
wn>?r ?KIB  
lDtl6r/  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: Ix+\oq,O  
>f~y2YAr  
c ^+{YH;k  
<tt:connection id=”con01” ...> ... </tt:connection> }C{wGK+o[  
-]Q6Ril  
<tt:query id=”balances” connection=”con01” > Xa=oEG  
FJ V!B&  
SELECT account, balance FROM acct_table ,a@jg&Mb]  
-* piC(  
where customer_num = <%= request.getCustno() %> +Ft@S(IE  
|D[4 G6&  
</tt:query> iJEKLv  
MryY<s  
5tu 4uYp;  
Ov~>* [  
)tR@\G>%  
<tt:connection ...> ]n&Eb88  
d7!,  
<x:query id=”balances”> #s]`jdc  
H.s:a#l?  
SELECT account, balance FROM acct_table W"H*Ad(V  
,mvU`>Ry  
where customer_num = <%= request.getCustno() %> s% (|z  
Jbqm?Fy4X  
</x:query> J*"G*x#u  
wD`jks  
</tt:connection> *gL-v]V  
`RL n)a  
J4^aD;j  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: ]w9\q*S]  
8al%F_r]  
<tag> ;{K/W.R  
A@#D_[~  
... nG !6[^D  
}SBpc{ch  
<attribute> ^@n?&  
}*M>gvPo  
<name>connection</name> Yuqt=\? #  
fg0zD:@rA  
<required>false</required> )2y# cM*  
xe!6Pgcb  
</attribute> C.q4rr  
"~ eF%}.  
</tag>
描述
快速回复

您目前还是游客,请 登录注册
如果您在写长篇帖子又不马上发表,建议存为草稿
认证码:
验证问题:
3+5=?,请输入中文答案:八 正确答案:八