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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! )SGq[B6@I  
7kE n \  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 4V`G,W4^J  
G"t5nHY\.  
在这篇文章中,我们主要讨论: a:w#s}bL  
> ~O.@|  
· 什么是自定义tag标签? i XjM.G  
R6->t #n,  
· 怎么使用tag标签? \9T7A&  
P*j|.63  
o 声明要使用的tag库 3Y$GsN4ln  
O=7CMbS3  
o 找到与之对应的tag处理类 |sE'XT4ag  
WpvhTX  
o tag标签的类型 3JR+O <3D  
S f# R0SA  
· 自定义tag标签 <a3 WKw  
"w<#^d_6  
o tag处理类 kAUymds;O  
ef4 i:.  
o tag库描述 ~P-mC@C  
w7L) '9  
o tag标签示例 4Z0]oI X  
G3T]`Atf  
o 带属性的tag -Q Nh  
~k5W@`"W  
o 带body的tag YoFxW5by  
z F;K  
o 定义了脚本变量的tag Q"#J6@  
}jPSUdo  
o 具有协作关系的tag X:{!n({r=  
A04U /;  
· 自定义tag标签 q) KKvO  
!&E-}}<  
o 一个迭代tag的例子 W(p_.p"  
Ow,b^|  
o 一个模板tag库 8z\xrY  
]Hv[IodJ  
o tag处理类到底是怎样被调用的? #/37V2E  
Fsg*FH7J  
F!K>Kz  
什么是自定义的tag? Tid aa  
\i &<s;  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 COlaD"Y  
Z;"vW!%d  
自定义tag标签有很多特色,诸如: f|(M.U-  
6Kz,{F@  
· 可以在JSP页面中自定义tag标签的属性 I]q% 2ie  
\~wMfP8  
· 访问JSP页面中的所有对象 d0> zS  
G3v5KmT  
· 可以动态地修改页面输出 >yDZw!C  
Y_P!B^z3  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 |y!A&d=xYn  
,/unhfs1q  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 DtnEi4h,  
dAj$1Ke  
Znv,9-  
使用tag标签 % & bY]w  
gBD]}vo-  
lu/ (4ED  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 BJ(M2|VH  
OZ;*JR:  
要使用tag标签,JSP程序员必须做2件事: =2x^nW  
w4Z'K&d=  
· 声明此tag标签的tag库 7K:PdF>/  
\73ch  
· 实现此tag标签 i@J ;G`  
 9gZ$   
声明tag标签所在的tag库 P!k{u^$L  
|ENh)M8}r  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) Xn ;AZu^'R  
>(RkZ}z  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> / XIhj  
+ck}l2&#  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 .N(p=9  
bZV/l4TU  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 %8x#rohP  
*{{89E>wC  
以下taglib指示符直接引用一个TLD: vvOV2n .WD  
syK^<xa  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> TS5Q1+hWHV  
@lph)A Nk  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: k VQ\1!  
rrv%~giU  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> vfo~27T{(  
rVsJ`+L  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: Af{"pzY  
Rx}Gz$   
<taglib> vr^qWn  
,Y48[_ymm  
<taglib-uri>/tutorial-template</taglib-uri> Du){rVY^d  
u<&m]] *  
<taglib-location> H>@+om  
nFs(?Rv*  
/WEB-INF/tutorial-template.tld _J[P[(ab  
;A!BVq  
</taglib-location> hR|MEn6KC  
Q NVa?'0"Y  
</taglib>  8dyg1F  
wlmRe`R  
{]|J5Dgfe  
实现此tag标签 m j@13$=  
5/z/>D;  
X[TR3[1}  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 `y* }lg T  
t&DEb_"De  
jF*j0PkNdb  
tag标签类型 29q _BR *:  
`@|$,2[C  
^sg,\zD 'X  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): C"enpc_C/  
W*w3 [_"sr  
<tt:tag> WMP,\=6k0  
kO-(~];  
body S 6,.FYH  
B?o7e<l[  
</tt:tag> Xb,3Dvf  
BFW&2  
GvlS%  
一个不带body的tag标签如下: OK g qT!  
76` .Y  
<tt:tag /> ,,|^%Ct']  
ei5~&  
n?K  
简单的tag标签 ^/=KK:n~  
k-""_WJ~^  
一个没有body和属性的tag标签如下: 7j)8Djzp|  
W`*r>`krVJ  
<tt:simple /> /5AJ.r  
lB[kbJ  
s(roJbJ_;  
带属性的tag标签 7vj2 `+r.  
dGTsc/$  
:p6M=  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 O<W_fx8_'  
-s'-eQF J  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: ?P c'C  
pFz`}?c0  
<loglic:present parameter = “Clear”> !$>R j  
j$5LN.8J  
而另一个标签logic:iterate是用表达式来给属性赋值: eKqk= (  
EAby?51+  
<logci:iterate collection=”<%= bookDB.getBooks() %>” F1Bq$*'N$w  
y L~W.H  
id=”book” type=”database.BookDetails”> d8x;~RA  
?@ $r  
`pZm?}K  
带body的tag标签 fLAw12;^  
;P&OX5~V  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 E q+_&Wk  
7i1q wRv  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: 7 x?<*T  
8kDp_s i  
<logic:present parameter=”Clear”> U|j`e5)  
O!bOp=  
<% cart.clear(); %> 5.J.RE"M  
w^0nqh  
<font color=”#ff0000” size=”+2”><strong> K,:N   
63x?MY6  
你选择了清除购物车! t5IEQ2  
iMRwp+$  
</strong></font> Ok\7y-w^  
njA#@fU  
</logic:present> Nu~lsWyRI5  
% +\. " eC  
Hg (Gl  
到底是用属性还是用body来传递信息? TrR8?-  
_/<x   
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 j^2j& Ta  
{+Cy U!O  
QoH6  
定义脚本变量的tag标签 @49S`  
KRKCD4  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: d9|<@A  
.Rf_Cl  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> "`1bA"E  
}?v )N).kW  
<% tx.begin(); %> Z>#i**  
2Q:+_v  
... k~FRD?[u  
_``=cc  
>t_6B~x9  
具有协作关系的tag标签 ! #2{hQRu  
.y:U&Rw4  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 $\y'I Q%  
Q>1[JW{$}  
<tt:tag1 attr1=”obj1” value1=”value” /> qK&d]6H R  
3>VL}Ui}  
<tt:tag2 attr1=”obj1” /> CF5`-wj/#  
@cB$iP=Z4  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 ~z;FP$U  
O463I.XAP  
<tt:outerTag> -v|qZ'  
zjoq6  
<tt:innerTag /> e6RPIg  
C8i^P}y  
</tt:outerTag> *<ewS8f*6  
0'?L#K  
UByv?KZi  
Tag处理类 cDH^\-z  
qPfQy  
lQkQ9##*   
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 2x0<&Xy#P  
hODWB&b  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 'Ne@e)s9  
1c{DY  
下表说明不同类型的tag所需要不同的处理过程: WU=59gB+jL  
mvT(.R ..s  
Tag处理类的方法 001FmiV  
5( HG|  
Tag标签类型 x{/g(r={}  
所调用的方法 `$ aZ0+  
WbqWG^W  
基本标签 Czu\RXJR  
doStartTag, doEndTag, release 8StgsM  
_/5H l`  
带属性的标签 Pw!MS5=r  
doStartTag, doEndTag, set/getAttribute1...N, release ChXq4]  
#" iu| D  
带内容的标签 [-oc>; `=l  
doStartTag, doEndTag, release AX/m25x  
w!clI8v/  
带内容的标签,且内容重复循环 H\tUpan6fy  
doStartTag, doAfterBody, doEndTag, release Pdt vU-(  
, ^f+^^  
带内容的标签,且内容与JSP交互 $aXer:  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release U2s /2 [.  
G,Azm }+  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 K?$^@ N  
* *G9H  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 {8,J@9NU  
Y#$%iF  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 B%+T2=&$7  
IG9VdDj  
]^K 4i)\  
Tag库描述(简称TLD) >%8KK|V{  
)+t0:GwP`:  
H-fX(9  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 3]3|  
*>qp:;,DKP  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 H@8sNV/u  
gn".u!9j  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: m<"WDU?y;  
HYSIN^<oy  
<?xml version="1.0" encoding="ISO-8859-1" ?> tr}Loq\y  
*CTlOy  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> (|1A?@sJ#h  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: nq8C'Fo!6T  
2Gaa(rJ5o  
6]%sFy2  
<taglib>的子元素 * U=s\  
pYZ6e_j1 ~  
Element 'o>B'$  
Description -"60d @.  
H6 HVu |  
tlib-version }"!I[Ek> y  
Tag库的版本 q\p:X"j|  
tQYM&6g  
jsp-version +@k+2?] FO  
Tag库所需要的jsp的版本 eu|;eP-+d  
6wECo  
short-name !.(P~j][  
助记符,tag的一个别名(可选) T&o(N3lW  
G.dTvLv  
uri /?F/9hL  
用于确定一个唯一的tag库 (tw)nF  
&/]Fc{]^$f  
display-name :;fHDU|  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) lHe{\N[C  
H{?vbqQ  
small-icon ktBj|-'>  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) v+#}rUTF  
I5n^,@md  
large-icon $jqq `n_  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) UH-*(MfB  
@{tz:f  
description F Yzi~L  
对tag库的描述(可选) 3! oi+_  
dD|OSB7 I7  
listener ^pF&` 2eD  
参见下面listener元素 P?B;_W+~A.  
T@&K- UQ  
tag ll.N^y;a  
参见下面tag 元素 Jx7C'~,J  
H0`]V6+<f  
Listener元素 }"PU%+J  
8sTp`}54 J  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 (I{rLS!o,L  
ZE=Sp=@)j  
Tag元素 K<qk.~ S  
(UvM@]B  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 q[W 0 N >  
Q&=w_Wc  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: 4Vi`* !  
1A G<$d5U|  
Tag元素的子元素 %'7lbpy,f  
WRy aKM  
元素名称 yiC^aY=-  
描述 +&( Mgbna  
qr4pR-Gdr  
name ';jYOVe  
独一无二的元素名 Q)" Nu.m &  
7k9G(i[-+  
tag-class c[4i9I3v  
Tag标签对应的tag处理类 `e|0g"oP  
<vh/4  
tei-class v|%Z+w  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) '~[d=fwH  
kG@@ot" n  
body-content *|>d  
Tag标签body的类型 vV6I0  
jW3!6*93  
display-name P.;aMRMR  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) u:gN?O/G  
 6S*e xw  
small-icon ^O<&f D  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) 2s&*  
J^}V|#  
large-icon 4Thn])%I  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) Ix!Iw[CNd  
`YLD`(\  
description D=m9fFz  
此tag标签的描述 f~y%%+{p  
>x+6{^}Q>  
variable +*T7@1  
提供脚本变量的信息(同tei-class)(可选) Dhw(#{N  
UU mTOJr  
attribute $M lW4&a|  
Tag标签的属性名 Ax?y  
"UGY2skf;  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 _w/EP  
4UlyxA~   
w' OXlR  
简单的tag r(aLEJ"u?  
BJB^m|b)  
D2!X?"[ P  
tag处理类 ,5kKimTt  
O[s{ Gk'>  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 Wm"4Ae:B  
+ SFVv_n  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: BuWHX>H  
C8e !H  
9S7 kUl{  
public SimpleTag extends TagSupport K[Kh&`T  
&7b|4a8B%  
{ TI#''XCB5  
[t7]{d*  
public int doStartTag() throws JspException i2YuOV!  
Q}K#'Og  
{ \h DdU+  
z4+k7a@jn  
try{ [16cFqD  
XZJ+h,f  
pageContext.getOut().print(“Hello.”); Ib\iT:AJ  
YN2sd G  
}catch(Exception e){ X*39c b(b  
ng:9 l3 x  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); ph[#QHB  
wS+ ^K  
} NufLzg{  
#qI= Z0Y  
return SKIP_BODY; {u\Mj  
" '6;/N  
} qg!|l7e  
~j5x+yC  
public int doEndTag() ,:`4%  
jJY"{foWV  
{ f3{MvAy[  
:Jy'# c  
return EVAL_PAGE; C] 9 p5Hs  
*R3f{/DK  
} PBxCx3a{  
6s\Kt3=  
} .k9{Yv0  
7J|VD#DE$Y  
& )vC;$vD`  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 2Sp=rI  
pN9A{v(  
<body-content>empty</body-content> %8Dz o  
a{J,~2>  
Eam  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 tBT<EV{ G  
_5m#2u51i  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, ] GTAq  
$:j G-r  
<logic:present parameter=”Clear”> EV^~eTz  
-gas?^`  
与此相应,此tag处理类应有如下方法和定义: =;|QZ"%E  
FwY&/\J7V  
f<*Js)k  
protected String parameter = null; MR,R}B$  
I,VH=Yn5,  
public String getParameter() 0zCw>wBPW  
3g~^[&|i  
{ vZ N!Zl7S  
+1!qs,  
return this.parameter; V$icWu  
D8nD/||;Z  
} qc!MG_{Y  
v-Fg +  
public void setParameter(String parameter) ofMY,~w  
ZA9sTc[ g  
{ hf<^/@^tK  
mVsIAC$}8  
this.parameter = parameter; N!x =eC  
6uKMCQ=h  
} /c-r  
^/ =#UQ*k  
b}w C|\s  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 k({\/t3i  
ym/fFm6h  
Attribute元素 Q33"u/-v  
%#Z/2<_  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 lR`'e0Lq  
^o@,3__7Q  
<attribute> Y<b-9ai<w  
l?DJJ|>O  
<name>attr1</name> ,\d6VBP&  
q@~L&{  
<required>true|false|yes|no</required> kctzNGF|  
^(f4*m6`  
<rtexprvalue>true|false|yes|no</rtexprvalue> L0]_hxE?  
tpEI(9>  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> 5P+t^\  
:@xm-.D  
</attribute> R@yyur~'_(  
TtDg*kZ  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 wpt='(  
 6vTo*8D  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 ).HDru-2  
*tX{MSYW  
<tag> %|l8f>3[  
%q322->Z  
<name>present</name> hv$m4,0WB  
H,<7G;FPT  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> g3sUl&K  
b7\ cxgRq  
<body-content>JSP</body-content> q7m6&2$[  
vF/ =J  
)|<_cwz  
4YMX|1wd)  
<attribute> Grz 3{U  
0Hw-59MK  
<name>parameter</name> xf>z@)e  
|nk3^;Yf  
<required>false</required> l\!-2 T6Y  
]G}B 0u3  
<rtexprvalue>true</rtexprvalue> Q2%QLM:.,  
O:/y Ac`  
</attribute> 0l#)fJo  
qxJQPz  
W"xP(7X  
G>Em! 4h  
</tag> HFQR ;9]  
rJ'I>Q~x6  
o:dR5v  
属性元素的校验 i=32KI(%  
V' 2EPYB  
^Ori| 4}'  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 l  n }}5Q  
"%QD{z_L  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 Y ?r po  
v)kEyX'K2d  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 aSYs_?&.  
zMK](o1Vj  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: &MgeYpd  
\hP=-J[~C  
<attribute> yWHiw<  
Zx?b<"k  
<name>attr1</name> 6ZqgY1  
0gF!!m  
<required>true</required> cM&'[CI  
HT_TP q  
<rtexprvalue>true</rtexprvalue> Y/8K;U|  
[$(R#tZ+  
</attribute> cQZ652F9  
$\Tkhq<  
VnJMmMM  
这个定义说明了attr1能在运行期间被赋值。 "x&C5l}n  
2 vKx]w  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 >1irSUj"~  
A~{f/%8D  
AzpV4(:an.  
Public class TwaTEI extends TagExtraInfo $ 'QdFkOr  
]&i+!$N_  
{ [{<dbW\ 9  
6a>H|"P NE  
public boolean isValid(Tagdata data) W*xX{$NL  
>^"BEG9i:  
{ M`,XyIn  
=j /hl  
Object o = data.getAttribute(“attr1”); I7\ &Z q  
&,-p',\-  
If(o != null && o != TagData.REQUEST_TIME_VALUE) #G,XDW2"w  
EkKnUD  
{ _#qe#  
I(n* _bFq  
if( ( (String)o).toLowerCase().equals(“true”) || re,.@${H  
a%J6f$A#  
((String)o).toLowerCase().equals(“false”) ) vU/ D7  
FX,$_:f6Y  
return true; I8op>^N"  
'CS.p!Z\  
else NyI ;v =  
c! H 9yk  
return false; r.FLGD U  
m<3v)R[>  
} /k7wwZiY@  
5y_"  
else 2N6=8Xy 5K  
/'>;JF  
return true; !Zwf 397  
l@d gJ  
} X#+`e+Df  
h[ 6hM^n  
} bEr.nF  
s5Fr)q// !  
FyEDt@J  
带body的tag R~B0+:6  
uJ'9R`E ]1  
A1,4kqmE  
tag处理类 B$`lY DqaG  
`.k5v7!o  
o|2 87S|$  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 C?Qf F{!7  
t,vTAq.))  
Tag处理类不与body交互 zw:/!MS  
\kwe51MQ  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 +|nsu4t,<  
+X!+'>  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 .9\Cy4_qSd  
Jc~E"x  
Tag处理类与body交互 J7a-CI_Tf  
y-`I) w%  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 .w FU:y4r  
z(d4)z 8'6  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 lfMH1llx  
K M]Wl_z  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 L^KdMMz;  
$k(9 U\y-  
doInitBody 方法 o#d$[oa  
8)Tj H'  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 1e$[p[  
L+Nsi~YVq  
doAfterBody方法 qU6BA \ZL  
712=rUI%!  
此方法在body内容已被计算后进行调用。 c57bf  
nJ# XVlHc  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 >7FSH"8[,  
-g2{68 1`r  
release 方法 FYeEG  
[u\CDsX  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 px&=((Z7>  
H*qD: N  
iy 3DX|]  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 [oHOHp/V  
A1!:BC  
#6FaIq92V  
Public class QueryTag extends BodyTagSupport ECdfLn*c  
QBjY&(vY  
{ >DmRP7v   
chwh0J;  
public int doAfterBody() throws JspTagException vadM1c*z  
0O ['w<_  
{ !`h~`-]O  
:+pPr Gj"  
BodyContent bc = getBodyContent(); bVmvjY4  
(j`l5r#X#/  
//将body的内容以字符串的格式提取出来 ArdJ."  
8c?8X=|D7  
String query = bc.getString(); wR1K8b".DC  
wG6FS  
//清除body (E]"Srwh  
KH)pJG|NY  
bc.clearBody(); 3z$\&& BR  
@S}|Ccfc_  
try{ 0XQ-   
.??rqaZ=  
Statement stmt = connection.createStatement(); ^k9rDn/AW  
K-Y* T}?  
Result result = stmt.executeQuery(query); $U mE  
h=wf>^l  
}catch(SQLException e){ r2)pAiTM*  
 bn|DRy  
throw new JspTagException(“queryTag: “ + e.getMessage() ); A@ { !:_55  
][ N) 2_^M  
return SKIP_BODY; /op/g]O}  
RQJ9MG w  
} .hnF]_QQ  
.kzms  
} 9w$7VW;  
Ty iU1,oO  
[EcV\.  
body-content元素 4}PeP^pj  
K+t];(  
0 wYiu  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: n%8#?GC`  
YmA) @1@U  
<body-content>JSP|tagdependent</body-content> zXDd,ltm  
[@s=J)H  
Cg?I'1]o6  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 |7Yvq%E  
_.hIv8V  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 i&B?4J)  
pJ$(ozV  
^K*~ <O-  
用tags定义脚本变量 j!"iYtgV  
\j/}rzo]  
>R) F}  
tag处理类 f@#w{W,3  
l+'`BBh*]  
AzW%+ LUD  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 /!o1l\i=5  
DD)mN) &T  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 cEtZ}2,j  
(O<abB(  
对象的生存周期(scope)如下表: 1pl2;!  
Ld'EABM  
对象的生存周期表 A1Ibx|K  
/G[+E&vj  
名字 )SC`6(GW  
可访问范围 L_`Xbky  
生存周期 =54Vs8.  
T\.7f~3  
page " Tw0a!  
当前页面 e*6U |+kJ  
一直有效,除非页面向客户提交响应或重定向到一个新页面 ~m3V]v(q7  
@ICejB<  
request =k_XKxd  
当前页面或当前页面重定向到的页面 `mWQWx$V!  
一直有效,除非页面向客户提交响应 1@s^$fvW  
y`T--v3mI  
session Y|Nfwqz  
当前页面或在同一浏览器窗口中的页面 a'o}u,e5  
一直有效,除非关闭当前浏览器、超时、网络故障 ,OFq'}q  
w@4t$bd7  
application oT$(<$&<  
整个web应用程序的所有请求 +YkmLD  
一直有效,除非发生网络故障、服务器故障 v_[)FN"]Y.  
F?!};~$=Z  
提供关于脚本变量的信息 zT2F&y q  
,Uv{dG  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: {EZFx,@t  
{A !;W  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> CAA tco5  
6eW1<p  
<font color=”red” size=”+2” > j P{:A9T\  
dY48S{  
<%= messages.getString(“CartRemoved”) %> uVoF<={  
i,C0o   
<strong><jsp:getProperty name=”book” property=”title” /></strong> ?nj"Ptzs  
jcT{ugpq  
</font> )@sJTAK  
RcKQER  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: m&(%&}g  
)ylv(qgV  
· 脚本变量名称 r|u6OF>  
A} x_zt  
· 脚本变量所属的类 |8&\N  
>F_qa=t%[  
· 此脚本变量是否引用了一个新的或已存在的对象 g>d7%FFn}  
1oXz[V  
· 此脚本变量的有效性 YqK+F=0  
-PIA;#Gs  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 B Lsdx }  
(xjoRbU*  
Variable元素 Fv5x6a  
QYODmeu  
Variable元素有如下子元素: W o<PmSt9i  
({ :yw  
· name-given ?D?D 给出的名字,是一个常量 S&;T_^|  
{Zd)U "  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 ui0J}DM  
z&6]vN'  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: n0>5'm%ES  
YL0WUD_>  
· variable-class?D?D变量的类型,缺省为java.lang.String。 JI{OGr  
1"~O"msb  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 KqG/a  
J7 Oa})-+'  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: %M4XbSN|  
{+9^PC_hm;  
脚本变量的有效范围 cQUH%7m  
lN*1zM<6;  
9Y!0>&o  
有效性 DkF@XK0c3  
方法 cP$wI;P  
GA%"w=M\  
NESTED Azdz3/  
在tag标签的开始和结束之间 5Xq.=/eX  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 2<\yky  
Ah8^^h|TPJ  
AT_BEGIN P?yOLG+)l)  
从tag标签的开始一直到页面结束 WsK"^"Z  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 tq4"Q BIKh  
w<8O=  
AT_END -E,{r[Sp  
从tag标签的结束一直到页面结束 0& SrKn  
在doEndTag中调用 r7wx?{~ 28  
)\:lYI}Wpm  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: *cI6 &;y  
 !z "a_  
<tag> m;$F@JJ  
!)l%EJngL  
<variable> z_[ 3IAZ  
hhh: rmEZl  
<name-from-attribute>id</name-from-attribute> af`f*{Co3  
0qotC6l~_w  
<variable-class>database.BookDetails</variable-class> _ z"ci$[  
 5K_N  
<declare>true</declare> zd*W5~xKg  
nJM9c[Ou^H  
<scope>AT_BEGIN</scope> y<Z#my$`|n  
(dGM;Dq8  
</variable> >uqS  
G74a9li@  
</tag> ]'bQ(<^#  
nfCd*f  
额外tag信息类 zei9,^ C  
b|V4Fp  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: ^|:{,d#Y  
2)j#O  
· 变量名 %+j]vP  
$'I$n  
· 变量所属类名 41f m}  
(VF4FC  
· 此变量是否引用了一个新对象 V~gUMu4ot  
ZF11v(n  
· 此变量的有效范围 #k|g9`  
}IalgQ(i  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 Q e2 /4j4  
*t]&b ;=gE  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: +oKpA\mz  
zLIa! -C  
`'WY'\|C  
public class DefineTei extends TagExtraInfo l2KxZteXY0  
>-./kI "  
{ =[tls^  
QWQ6j#`  
public VariableInfo[] getVariableInfo(TagData data) X0r#,u  
Stp*JU  
{ { P\8g8  
>i#_)th"U!  
String type = data.getAttributeString(“type”); z6>ZV6(d2^  
#t9=qR~"  
If( type == null) rc{[\1 -N  
l4BO@   
type = “java.lang.Object”; 5fDtSsW  
5l7L@Ey  
return new VariableInfo[] { LZAj4|~,m  
vM>`CZ  
new VariableInfo(data.getAttributeString(“id”), %`uRUex  
/IQ-|Qkg  
type, `b'|FKc]  
F~0%j}ve  
true, N~K)0RETn  
Q!A3hr$IF  
VariableInfo.AT_BEGIN) 'frL/[S  
X-) ]lAP  
}; kBQenMm  
N\?Az668?  
} Nz;*;BQK:  
}W>[OY0^A  
} }SvWC8  
OTjryJ^  
:\= NH0M  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: QIz N# ;g  
<tei-class> g(}8n bTA  
org.apache.struts.taglib.bean.DefineTagTei =A&*SE o5  
</tei-class> 5]n<%bP\  
!Pjg&19  
-D^y)  
具有协作关系的tag EvardUB)  
~b<4>"7y.  
x%?*]*W  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 <}'B-k9  
 F3r  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 lp%.n= '\  
:g:h 0'G  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 Pge}xKT  
9QQ@Y}  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 z&J ow/  
1^"aR#  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 WuQ<AS=   
#1hz=~YO  
.AI'L|FQ%c  
public class QueryTag extends BodyTagSupport [^BUhm3a  
)B5gs%u]  
{ <XcMc<h~  
JhXN8Bq33  
private String connectionId; ]?^xc[  
6)2M/(  
public int doStartTag() throws JspException )tQ6rd'  
U.sPFt  
{ T9v#Jb6  
!U~#H_  
String cid = getConnection(); j I@$h_n  
?RAR  
if(cid != null) o*ED!y7  
8q[WfD  
{ zZ0V6T}  
Cspm\F  
//存在一个connection id,使用它。 -oT+;2\2  
iwx0V  
connection = (Connection) pageContext.getAttribute(cid); F,2#;t4  
Pi sr&"A  
} J9t?]9.,:  
Z/UVKJm>:  
else |a:VpM  
){|Lh(  
{ UNLNY,P/!)  
0guc00IN  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, v5ddb)  
f<:SdtG5  
ConnectionTag.class); w*kFtNBfU  
W_n.V" hN  
if(ancestorTag == null) {%~ Ec4r  
f]65iE?x  
{ )KQv4\0y<  
uB"m!dL  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); BU{ V,|10a  
.wn_e=lT  
} tpzdYokh >  
,$ret@.H  
connection = ancestorTag.getConnection(); !PTbR4s  
(G!J==  
} 4$w-A-\ t  
BcO2* 3  
} CKw)J}z  
<Y'YpH`l  
} w3UJw  
_ShJ3\,K  
/4BXF4ksi,  
)@|Fh@|  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: =C2C~Xd  
PBnn,#  
b<cM[GaV~  
<tt:connection id=”con01” ...> ... </tt:connection> n.>'&<H>9  
\-id[zKb  
<tt:query id=”balances” connection=”con01” > z`7C)p:  
*fX)=?h56  
SELECT account, balance FROM acct_table K1nwv"  
R@aT=\u+  
where customer_num = <%= request.getCustno() %> 9+|,aG s  
IoX 9yGq  
</tt:query> -T6%3>h  
>{=RQgGy  
YAG3PWmD  
ADUI@#vk  
")buDU6_  
<tt:connection ...> R6.#gb8^oS  
+34jot.!  
<x:query id=”balances”> )BrqE uX@"  
Gnq~1p5^  
SELECT account, balance FROM acct_table 2b` M(QL  
  `.-C6!  
where customer_num = <%= request.getCustno() %> 0t0:soZ x  
2xj`cFT  
</x:query> ts$UC $  
G\AQql(f4  
</tt:connection> H<?yG->  
55KL^+-~  
haK5Oe/cE  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: IsL/p3|  
:|Ty 0>k  
<tag> 2p[3Ap  
^yZEpQN_  
... C(+BrIS*  
EZW?(%b>H  
<attribute> h2 <$L  
4(ZV\}j1  
<name>connection</name> >GRuS\B  
%c{)'X  
<required>false</required> 5E|2 S_)G  
Z:Am\7 I  
</attribute> KgS xF#  
!!>G{  
</tag>
描述
快速回复

您目前还是游客,请 登录注册
批量上传需要先选择文件,再选择上传
认证码:
验证问题:
10+5=?,请输入中文答案:十五