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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! &mj98  
ffo{ 4er  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 DZGM4|@<7Y  
=\Td~>  
在这篇文章中,我们主要讨论: i,>yIPBU!  
ON~jt[  
· 什么是自定义tag标签? g1-^@&q  
wowv>!N!X-  
· 怎么使用tag标签? C Sx V^  
F8S -H"  
o 声明要使用的tag库 d0YN :lJc  
 ~0 <?^  
o 找到与之对应的tag处理类 `(A>7;]:  
bY:A7.p7#  
o tag标签的类型 omQa N#!,  
r(./00a  
· 自定义tag标签 \O 9j+L"  
ikf6Y$nWfF  
o tag处理类 >h>X/a(=~  
!kZ9Ox9^  
o tag库描述 3# G;uWN-  
4R-Y9:^t  
o tag标签示例 ]Ga}+^  
8/X#thG  
o 带属性的tag w=>~pYASH  
T-pes1Wu  
o 带body的tag fMRBGcg7Dc  
&U:bRzD  
o 定义了脚本变量的tag :lQl;Q -e  
,w%cX{  
o 具有协作关系的tag %(h-cuhq  
}MAvEaUd  
· 自定义tag标签 a]^hcKo4  
K@lZuQ.1  
o 一个迭代tag的例子 nsWenf  
Z_{`$nW  
o 一个模板tag库 1qXqQA  
lquY_lrri  
o tag处理类到底是怎样被调用的? ^Nl)ocHv!  
*het_;)+{  
q B-9&X  
什么是自定义的tag? cwi HHf>  
;=piJ%k  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 U^<\'`  
BU-+L}-48  
自定义tag标签有很多特色,诸如: ZzET8?8  
EMME?OW$  
· 可以在JSP页面中自定义tag标签的属性 sr%tEKba)  
"TB4w2?=  
· 访问JSP页面中的所有对象 +-~hl  
],vUW#6$N  
· 可以动态地修改页面输出 6B 4Sd  
^mr#t #[e  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 9B &QY 2v  
0MDdcjqw  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 K r $R"  
)%'Lm  
~ qe9U 0  
使用tag标签 wW s<{ T  
Zp~2WJQ  
Erz{{kf]1V  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 {B$cd?}  
"4N%I  
要使用tag标签,JSP程序员必须做2件事: .),%S}  
EIO!f[]o  
· 声明此tag标签的tag库 J~7E8  
v%c r   
· 实现此tag标签 O8#}2  
ZC+F*:$  
声明tag标签所在的tag库 g7!P|  
<1#v}epD#  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) V*P3C5 l  
7e$\|~<  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> t/z]KdK P  
sIQd }  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 hYRGIpu5  
Ql8E9~h  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 |eT?XT<=o  
q H&7Q{  
以下taglib指示符直接引用一个TLD: sXm8KV  
-FA]%Pl<'  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> 8`E9a  
nnLE dJ}n  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: Am3^3>  
DE3>F^ j  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> [oN}zZP]  
{?*3Ou  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: ^)=c74;;  
]UyIp`nV;  
<taglib> Qo+_:N  
l/[0N@r~  
<taglib-uri>/tutorial-template</taglib-uri> z#*M}RR  
>xu}eWSz  
<taglib-location> QW :-q(s  
0JTDJZOz@#  
/WEB-INF/tutorial-template.tld "(j.:jayd  
h _6QVab@  
</taglib-location> fhqc[@Y[  
xi=Z<G  
</taglib> | ZBv;BW  
?CGbnXZ4Ug  
9u<4Q_I`  
实现此tag标签 =)5eui>{  
hPtSY'_@_  
w :2@@)pr  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 Sd?:+\bS;  
:@KU_U)\  
wWm 1G)  
tag标签类型 1GB$;0 W),  
krwY_$q  
]F5?>du@~  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): ##VS%&{  
g+8{{o=  
<tt:tag> +P,hT  
#I[tsly}  
body T'.U?G  
p~1,[]k  
</tt:tag> 7m0sF<P{g  
YGrmco?G  
+ 5E6|  
一个不带body的tag标签如下: P6w!r>?6N  
wic"a Y<m  
<tt:tag /> ]0P-?O:  
eaP,MkK&  
Bv,u kQ\CH  
简单的tag标签 }8cL+JJU  
m@o/W  
一个没有body和属性的tag标签如下: TNBFb_F  
xvP<~N-  
<tt:simple /> yiyyw,iy  
[ 9)9>-  
INrl^P*  
带属性的tag标签 t(/b'Peq  
[FLRrTcE  
cy|]}n85  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 Nzj7e 1=  
i6wLM-.)  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: 68 d\s 4  
cA%70Y:AV  
<loglic:present parameter = “Clear”> "R@N}q<*v2  
#W[/N|~wx  
而另一个标签logic:iterate是用表达式来给属性赋值: cE[B (e  
2ILMf?}  
<logci:iterate collection=”<%= bookDB.getBooks() %>” vum6O 3  
88 ~BE ^  
id=”book” type=”database.BookDetails”> y BF3Lms  
s,>_kxuX  
]~~PD?jh  
带body的tag标签 UO^"<0u  
;taTdzR_  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 xe}d&  
5Z{i't0CQ  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: u'cM}y&  
[ L% -lJ  
<logic:present parameter=”Clear”> vU&I,:72 H  
HSHY0  
<% cart.clear(); %> `*nVLtT Y  
WP-?C<Iw  
<font color=”#ff0000” size=”+2”><strong> B6&PYMFK?*  
KP" lz  
你选择了清除购物车! )G6{JL-I  
)s^D}I(  
</strong></font> zs!,PQF(  
.G#wXsJj  
</logic:present> A&_H%]{<:  
AcV 2l  
'Ba Ba=  
到底是用属性还是用body来传递信息? d`9% :2qE  
+{Yd\{9  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 9[}L=n  
]pi"M 3f_  
n'a=@/  
定义脚本变量的tag标签 JK:i-  
!-1UJqO  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: $ )q?z.U  
c?oNKqPzg  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> /IS_-h7>XS  
"<6X=|C  
<% tx.begin(); %> "IbXKS>t  
b4%sOn,  
... 9xL8 ];-  
X5i?B b.  
5.!iVyN  
具有协作关系的tag标签 jA@jsv  
 5,  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 \IB@*_G  
TtA6N8G  
<tt:tag1 attr1=”obj1” value1=”value” /> $g? ]9}p  
apsR26\^  
<tt:tag2 attr1=”obj1” /> Ax &Z=  
@H%)!f]zWt  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 Cx(|ZD^  
( <~  
<tt:outerTag> A2 'W  
;"/[gFD5u  
<tt:innerTag /> akg$vHhK4  
r(=  
</tt:outerTag> wyF' B  
x'dU[f(  
8Mx+tA  
Tag处理类 '%U'%')  
T](N ^P  
o@SL0H-6|  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 zJC!MeN  
N.r8dC  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 {C+blzh6  
_}8hE v  
下表说明不同类型的tag所需要不同的处理过程: 45g:q  
oSd TQ$U!D  
Tag处理类的方法 1+wmR4o  
7.V'T=@x3)  
Tag标签类型 2% ],0,o  
所调用的方法 @ \{L%y%a0  
bYs K|n  
基本标签 5q<cZ)v#&  
doStartTag, doEndTag, release S$O+p&!X  
SZVNu*G!H  
带属性的标签 j1[Ng #.  
doStartTag, doEndTag, set/getAttribute1...N, release Bi}uL)~rD  
}STTDq4  
带内容的标签 XPJsnu  
doStartTag, doEndTag, release V { #8+  
(<bYoWrK#  
带内容的标签,且内容重复循环 m |Isi  
doStartTag, doAfterBody, doEndTag, release An0Dq jR  
l', +l{\Z  
带内容的标签,且内容与JSP交互 j@g`Pm%u`  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release 1Ce7\A  
.|XG0M  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 b'x26wT?  
V\1pn7~V  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 dnEIR5%+.  
*dmB Ji}  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 m5c=h  
OKW}8qM  
YK xkO  
Tag库描述(简称TLD) n 0/<m.  
xxnvz  
`!BP.-Zv  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 FX1[ 2\  
"2l$}G  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 "Zh3,  
7+(on  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: 0^lCZ,uq;  
38<Z=#S  
<?xml version="1.0" encoding="ISO-8859-1" ?> <8J_[ S  
CjRU3 (Q  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> oz.#+t%X$b  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: #uRj9|E7  
?/@ U#Qy  
rXh*nC  
<taglib>的子元素 r`dQ<U,  
e4h9rF{Cxn  
Element ey/{Z<D  
Description _%R]TlL  
$O'IbA  
tlib-version QUQw/  
Tag库的版本 zf4\V F  
/Z~} dWI  
jsp-version \\R$C  
Tag库所需要的jsp的版本 Ji#eA[  
?Yf0h_>  
short-name "26=@Q^Y  
助记符,tag的一个别名(可选) uM"_3je{W2  
Q[n*ce7L0  
uri o=]\Jy  
用于确定一个唯一的tag库 IGnP#@`5]  
;_~9".'<d  
display-name 0 s$;3qE  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) @S<6#zR  
&7J-m4BI  
small-icon :pH3M[7  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) ` n#Db  
UdOO+Z_K%  
large-icon pN4gHi=  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) ^TZ`1:oL#  
|[_%zV;p>v  
description ]x(cX&S-9  
对tag库的描述(可选) @ogj -ol&  
_C3O^/<n4V  
listener kBeYl+*pk  
参见下面listener元素 *S<d`mp[  
]3Y J a  
tag dQs>=(|t  
参见下面tag 元素 {ePtZyo0  
]iY O}JuX  
Listener元素 Sby(?yg  
_iF*BnmN  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 %M,^)lRP  
C %i{{Y&l  
Tag元素 nX_w F`n"  
zRMz8IC.  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 r"9hpZH  
[XhG7Ly  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: 6DG%pF,  
cTBUj  
Tag元素的子元素 tR\cS )  
D (WdI  
元素名称 9~J#> C0}  
描述 N9#5 P!  
fuU 3?SG  
name Z*+y?5+L"P  
独一无二的元素名 &. MUSqo9  
\1O wZ@  
tag-class GOsOFs"I  
Tag标签对应的tag处理类 #p<(2wN  
_fdD4-2U  
tei-class jmG)p|6  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) 9tWpxrig%  
 (l-l Y  
body-content PA*1]i#2M=  
Tag标签body的类型 T/PmT:Qg `  
|'``pq/}_  
display-name t*J?#r  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) !>#gm7  
AqAL)`#K  
small-icon P(UY}oU  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) +G6 Ge;  
CofTTYl  
large-icon 3a[LM!  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) dZY|6  
l{gR6U{e  
description Kk,u{EA  
此tag标签的描述 o)GesgxFa5  
#w@FBFr@  
variable 6:q,JB@i  
提供脚本变量的信息(同tei-class)(可选) YwS/O N  
&Oc `|r*  
attribute bcUSjG>  
Tag标签的属性名 o:B?hr'\  
&]tm 'N25  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 Xf[;^?]X  
r PTfwhs  
<G0Ut6J>  
简单的tag f _Hh"Vh  
8!b>[Nsc  
0#NbAMt  
tag处理类 D~FIv  
Y>T<Qn^D  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 ::_bEmk  
J/QqwoR  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: 2tg07  
<J>k%,:B  
d)3jkHYEjj  
public SimpleTag extends TagSupport !ALq?u  
C[';B)a  
{ ,vo]WIQ\:  
bk1.H@8  
public int doStartTag() throws JspException },{sJ0To  
1\%@oD_zG  
{ +s6v!({Z  
vQGv4  
try{ LM(r3sonb  
wv`ar>qVL  
pageContext.getOut().print(“Hello.”); b%KcS&-6  
KG4zjQf  
}catch(Exception e){ vw$b]MO!  
A)gSOC{3F)  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); .mNw^>:cq  
oVr:ZwkG3  
} ^oYRB EIJH  
6XHM`S  
return SKIP_BODY; LqXVi80  
3<l}gB'S[  
} }ik N  
\mTi@T!&  
public int doEndTag() ;n.h!wmJ}  
W56VA>ia  
{ >l #D9%  
>5E1y!  
return EVAL_PAGE; E,dUO;  
#?`S+YN!q)  
} _#Lq~02 %  
]t~'wL#Z  
} Mnk-"d  
,c0t#KgQ.  
E3(o}O  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 D+jE{v'  
S_ nAO\h  
<body-content>empty</body-content> JIjo^zOXsc  
?~IdPSY  
cv1PiIl  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 %pH|2VB#  
4<vi@,s  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, I(WIT=Wi<  
Y@< j vH1  
<logic:present parameter=”Clear”> =}@1Z~  
@nMVs6  
与此相应,此tag处理类应有如下方法和定义: 2s> BNWTU  
#qUGc`  
uix/O*^  
protected String parameter = null; Q, "8Ty  
pr1bsrMuL  
public String getParameter() )pe17T1|  
$pKegK;'z  
{ xX9snSGz  
dz>Jl},`k  
return this.parameter; #d<|_  
|H]0pbC)w  
} 1G67#L)USq  
34[TM3L].  
public void setParameter(String parameter) *-(o. !#1  
Ycx}FYTY  
{ WbBd<^Q  
+V9xKhR;x  
this.parameter = parameter; kwqY~@W  
ADVS}d!;]  
} k4!_(X%8  
yGSZ;BDW:K  
VXlAK(   
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 lzz;L z  
=F Y2O`%a  
Attribute元素 pq\N 2d  
ASrRMH[  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 qJf\,7mi  
8h4]<T  
<attribute> "nb.!OG~(  
~R~.D  
<name>attr1</name> .p*?g;  
<3/_'/C  
<required>true|false|yes|no</required> GD'Z"rhI  
|Ldvfd  
<rtexprvalue>true|false|yes|no</rtexprvalue> qX; F+~  
EaHJl  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> uFb 9Ic]`  
U 8p %MFD  
</attribute> =yM%#{t&W  
80 T2EN:$  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 lUA-ug! ^  
WC37=8mA  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 <%`Rku  
:<k (y?GB  
<tag> ZBFn  
km][QEXs%  
<name>present</name> ~(yW#'G  
L|:CQ  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> om9'A=ZU  
>Yk|(!v  
<body-content>JSP</body-content> w)RedJnf  
rly%+B `/  
}<@-=  
?G!~&  
<attribute> 2/tx5Nc  
o1?-+P/  
<name>parameter</name> dKC*QHU  
Xdl dUK[  
<required>false</required> /988K-5k  
I1l^0@J   
<rtexprvalue>true</rtexprvalue> tg==Qgz  
u*W! !(P/  
</attribute> (xWsyo(4  
' Q(kx*;  
_x3=i\O,  
[hpkE lE  
</tag> Jc}6kFgO6  
jpS$5Ct  
2kDv (".  
属性元素的校验 N-&ZaK  
,Wu$@jD/ ]  
ys>n%24qP  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 _KkaseR  
x3#:C=  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 ]h' 38W  
5#N<~  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 Hm!"%  
 U#K4)(C  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: c}|.U  
QA;,/iw`  
<attribute> M*D_p n&  
im9EV|;  
<name>attr1</name> rl~Rbi  
sJ^Ff  
<required>true</required> TbT/ 5W3  
do.>Y}d  
<rtexprvalue>true</rtexprvalue> 2RF3pIFrm  
&a e!lB  
</attribute> F.i}&UQ%  
+Yq?:uBV  
W94u7a  
这个定义说明了attr1能在运行期间被赋值。 OPE+:TvW^  
WQ.{Ag?1  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 t?)]xS)  
8IWT;%  
]3,  
Public class TwaTEI extends TagExtraInfo LVm']_K(f  
RMpiwO^  
{ :<{ 15:1  
qxAh8RR;/  
public boolean isValid(Tagdata data) EA1&D^nT  
4|I;z  
{ Ja4M@z  
&v1E)/q{Z  
Object o = data.getAttribute(“attr1”); 5 -|7I7(G$  
C9MK3vtD.  
If(o != null && o != TagData.REQUEST_TIME_VALUE) <pa-C2Ky  
d}Guj/cx,  
{ -AD` (b7q  
!\d~9H%`B  
if( ( (String)o).toLowerCase().equals(“true”) || He4HI Z  
yHC[8l8%  
((String)o).toLowerCase().equals(“false”) ) ,X:3w3nr^  
SSla^,MHef  
return true; 2dKt}o>   
^z{Xd|{"  
else l59 N0G  
m-tn|m!J  
return false; qN' 3{jiPL  
7G;1n0m-T  
} ml^=y~J[  
:=+YZ|&j  
else a3w6&e`  
}:{ @nP  
return true; YT'V/8US  
qrj f  
} e1JH N  
lg2I|Z6DH  
} [\<#iRcP  
8au Gz ,"  
mOHOv61  
带body的tag pCo3%(  
"fhQ{b$i  
YIZu{  
tag处理类 <A|z   
6LCR ;~ ]  
fibudkg'>  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 C@]D*k  
)CE]s)6+2  
Tag处理类不与body交互  !O`j  
p< 0=. ~  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 -EFdP]XO  
#6YpV)  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 H<q|je}e  
??P\v0E  
Tag处理类与body交互 !t~tIJ>6  
L aA<`  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 kb"Fw:0  
q27q/q8  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 `EvO^L   
LD NdHG6  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 eAI|zk6  
M;3q.0MU  
doInitBody 方法 pp1Kor  
sUmpf4/  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 ,?qJAV~>  
]}l.*v\uK  
doAfterBody方法 cV@^<  
rr(kFQ"  
此方法在body内容已被计算后进行调用。 <vV"abk  
a=y%+E'a '  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 X@Zt4)2#  
:8}Qt^p  
release 方法 Tmu2G/yi  
G,P k3>I'  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 *\}$,/m['  
6|n3Q$p  
sGNHA( ;  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 vRW;{,d  
?6ssSjR}  
;w]1H&mc*A  
Public class QueryTag extends BodyTagSupport 9eP*N(m<  
EXH,+3fQp  
{ }QQl.'  
lH/" 47  
public int doAfterBody() throws JspTagException [N%InsA9k  
Ez-AQ'  
{ ;g+fY 6  
(vi^ t{k  
BodyContent bc = getBodyContent(); DoO ;VF  
zPHx\z"  
//将body的内容以字符串的格式提取出来 i,Z-UA|f=T  
.=G3wox3  
String query = bc.getString(); s[UV(::E  
hR2 R  
//清除body cw)J+Lyh  
QqW N7y_9  
bc.clearBody(); U1/ww-!Z  
Gx4uf  
try{ 8dt=@pwx&  
mRyf+O[  
Statement stmt = connection.createStatement(); y0O e)oP  
%G6x\[,  
Result result = stmt.executeQuery(query); l& sEdEA  
%z[=T@  
}catch(SQLException e){ 1B&XM^>/  
sRcS-Yw[S  
throw new JspTagException(“queryTag: “ + e.getMessage() ); l<S3<'&  
SJLs3iz_)  
return SKIP_BODY; "W4|}plnu  
Yh"9,Z&wiR  
} ngd4PN>{4  
i Pl/I  
} 7J$rA.tu  
(M{wkQTO  
|d6/gSiF  
body-content元素 ;O,&MR{;|n  
g}hNsU=$5~  
+gBD E :  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: mKV31wvK}  
pK_zq  
<body-content>JSP|tagdependent</body-content> rij%l+%@#  
'h~IbP  
~=HPqe8  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 SbMRrWy  
JW2f 6!b  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 nDckT+eJ  
l$l6,OzS@  
tx+P@9M_Aq  
用tags定义脚本变量 S}0-2T[  
&A/b9GW^-  
7OXRR)]V  
tag处理类 =*+f2  
8<Yv:8%B6  
> 9z-/e  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 vKdS1Dn1  
g?}h*~<b  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 MOB'rPIUI  
}y+a )2  
对象的生存周期(scope)如下表: OzRo  
w+!V,lU"^  
对象的生存周期表 :l Z\=2D  
8/,s 8u  
名字 } MP_  
可访问范围 \fUVWXv  
生存周期 B"*PBJuOA  
ga;t`5+d  
page F60m]NUM)c  
当前页面 KqaEHL  
一直有效,除非页面向客户提交响应或重定向到一个新页面 r"x}=# b!  
>oEFuwE  
request l#>A.-R*`  
当前页面或当前页面重定向到的页面 {ynI]Wj`L  
一直有效,除非页面向客户提交响应 v6x jLP;O  
33hP/p%  
session Z~|%asjFE  
当前页面或在同一浏览器窗口中的页面 ~WB-WI\  
一直有效,除非关闭当前浏览器、超时、网络故障 #q&N d2y  
k#mL4$]V5N  
application 56NDU>j$  
整个web应用程序的所有请求  _qt  
一直有效,除非发生网络故障、服务器故障 s6 K~I  
v Oo^H  
提供关于脚本变量的信息 P$clSJW  
?&U~X)Q  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: @fVz *  
pMUUF5  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> y=SpIbn{  
Y~lOkH[z  
<font color=”red” size=”+2” > pg<c vok  
P{2ED1T\  
<%= messages.getString(“CartRemoved”) %> .0X 5Vy  
~1,$  
<strong><jsp:getProperty name=”book” property=”title” /></strong> = P$7 "  
0\"]XYOH  
</font> O=!EqaExW  
LR"7e  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: &oK&vgcj  
jcxeXp|00  
· 脚本变量名称 f=4q]y#& X  
1x+w|h  
· 脚本变量所属的类 O#vIn}  
0? KvR``Aj  
· 此脚本变量是否引用了一个新的或已存在的对象 YQO9$g0% ~  
\[B#dw#  
· 此脚本变量的有效性 HXqG;Fds(  
?i~mt'O  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 7~D5Gy  
x:]_z.5  
Variable元素 H3ob 8+J  
j(_6.zf  
Variable元素有如下子元素: 8}Maj  
c&SSf_0O*  
· name-given ?D?D 给出的名字,是一个常量 :%zAX  
kH62#[J)yM  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 2>Kn'p  
q\fai^_  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: #CB`7 }jq  
R}OjSiS\  
· variable-class?D?D变量的类型,缺省为java.lang.String。 3.?oG5 P#  
IU]@%jA_:A  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 eGbjk~,f'  
pr1>:0dg  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: 7 /DDQ  
>?$qKu  
脚本变量的有效范围 !OR %AdxB  
0'`#I  
nh"LdHqiDB  
有效性 %#lJn.o  
方法 j5 W)9HW:  
il:RE8  
NESTED vH?3UW  
在tag标签的开始和结束之间 YJ01-  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 >#xIqxV,  
0VI[6t@  
AT_BEGIN E-$N!KY  
从tag标签的开始一直到页面结束 "Za'K+4  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 3 DZ8-N S  
=G1 5 eZW  
AT_END D}pN sQ  
从tag标签的结束一直到页面结束 gBy7 q09r  
在doEndTag中调用 - I j  
t hQ)J|1  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: T`Qg+Q$  
R"JT+m  
<tag> (V8lmp-F  
SRyot:l   
<variable> Q$^Kf]pD  
fq[,9lK  
<name-from-attribute>id</name-from-attribute> 9,A HC2kn%  
3*<~;Z' z4  
<variable-class>database.BookDetails</variable-class> EwOi` g  
E#M4{a1  
<declare>true</declare> V#d8fRm  
6vZ.CUK9  
<scope>AT_BEGIN</scope> /q6 ^.>b  
um mkAeWb  
</variable> _n3"  
E&2mFg  
</tag> P%kJq^&  
sfEy  
额外tag信息类 rp,PhS  
.h>tef  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: |(UkI?V  
!XrnD#  
· 变量名 fGDjX!3-S  
*Zk$P.]  
· 变量所属类名 H=>;M j  
Xx=c'j<  
· 此变量是否引用了一个新对象 :|E-Dx4F6H  
P }$DCD<$U  
· 此变量的有效范围 ZklZU,\!|v  
Qj/.x#T  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 FTZaN1%`  
oxgh;v*  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: Z3nmC-NE  
4qLH3I[Y  
 Qf(mn8  
public class DefineTei extends TagExtraInfo TmO3hKaP  
t(.xEl;Ma  
{ $_&gT.>  
_6&TCd<  
public VariableInfo[] getVariableInfo(TagData data) 9A9yZlt  
*D$Hd">X  
{ *lws7R  
d^ YM@>%  
String type = data.getAttributeString(“type”); |a[Id  
 Cdbh7  
If( type == null) #~>ykuq  
YA4;gH+  
type = “java.lang.Object”; *Z=:?4u  
j= Ebk;6p  
return new VariableInfo[] { A@k`$xevVj  
aMycvYzH  
new VariableInfo(data.getAttributeString(“id”), j?cE0 hz  
|c5r&oM&m  
type, dd@-9?6M  
_^"0"<,  
true, ]W>kbH Imz  
h`%}5})=  
VariableInfo.AT_BEGIN) \4pWHE/  
W_P&;)E  
}; 2<' 1m{  
BD (  
} ,Z6\%:/  
2n8spLZYGY  
} I w-3Z'hOX  
%N }0,a0  
j6{9XIR o_  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: :")iS?l  
<tei-class> 4! V--F  
org.apache.struts.taglib.bean.DefineTagTei ,"Nfo`7  
</tei-class> ag\xwS#i5H  
NU?05sF  
12MWO_'g8  
具有协作关系的tag MehMhHY  
wnoL<p  
V:vYS  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 UL   
:#=XT9  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 h1`u-tc2x  
iw ==q:$  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 ^saH^kg1"  
<; (pol|  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 BYBf`F)4  
kX)Xo`^Ys  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 Y &"rf   
.W)%*~ O!;  
|X$O'Gf#n  
public class QueryTag extends BodyTagSupport Nn%[J+F  
LU=`K4  
{ r#CQCq  
I"<ACM  
private String connectionId; ySk'#\d  
xmI!N0eta  
public int doStartTag() throws JspException O0VbKW0h3  
3"ii_#1  
{ -'iV-]<  
N-O"y3W}  
String cid = getConnection(); fxKhe[;  
mlmp'f  
if(cid != null) ?onTW2cG;  
FnFJw;:,{  
{ Z*Fxr;)d  
' *6S0zt  
//存在一个connection id,使用它。 ..g?po  
97%S{_2m/  
connection = (Connection) pageContext.getAttribute(cid); 9+o`/lk1  
sD[G?X  
} bm+ #OI  
'4""Gz  
else B]o5 HA<k  
&2EimP  
{ SQ_w~'(  
 XAb!hc   
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, ?'dsiA[  
vCB0 x:/  
ConnectionTag.class); 4._ U  
.(7 end<  
if(ancestorTag == null) l,pI~A`w_  
).BZPyV<  
{ #@#/M)  
lLb"><8a  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); sr+Y"R  
xKl!{A9$w  
} (")IU{>c6  
{O4y Y=G  
connection = ancestorTag.getConnection(); f ;[\'_.*  
X \1grM  
} ;E"TOC  
Z+qTMm  
} ^` 96L  
Y2)2 tzr]  
} 1${lHVx]  
HFr#Ql>g  
uTemAIp $u  
b xU13ESv  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: a2{ nrGD  
zO)>(E?  
B-@ ]+W  
<tt:connection id=”con01” ...> ... </tt:connection> &K1\"  
o:E_k#Fi  
<tt:query id=”balances” connection=”con01” > <K$X>&Ts  
? x*Ve2+]  
SELECT account, balance FROM acct_table 7~2/NU?  
Zr&~gXmVS  
where customer_num = <%= request.getCustno() %> jP]I>Tq  
3kl<~O|Fs  
</tt:query> @213KmB.  
ww_gG5Fc$  
w4S0aR:yL  
AS} FRNIVx  
$[p<}o/6v]  
<tt:connection ...> !OVTs3}  
)<.BN p  
<x:query id=”balances”> M:!Twz$  
~F</ s.  
SELECT account, balance FROM acct_table 'pJ46"D@m  
J^Dkx"1GD  
where customer_num = <%= request.getCustno() %> y?t2@f]!XK  
*$t<H-U-  
</x:query> N^G:m~>  
$6(,/}==0  
</tt:connection> ]/o0p  
MQ9Nn|4  
(Hr_gkGtM  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: Mn- f  
=`8%qh  
<tag> I$#B#w?!$r  
0X`sQNx  
... }\9elVt'2  
Zd~l_V f  
<attribute> 3Ishe"  
+}XFkH~  
<name>connection</name> Ddf7wszW  
[a\U8 w  
<required>false</required> .=j]PckJO  
B{#*PAK=  
</attribute> ,9(=Iu-?1  
bJ[{[|yEd  
</tag>
描述
快速回复

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