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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! Fps.Fhm  
(Q09$  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 w_!]_6%{b  
T&`H )o  
在这篇文章中,我们主要讨论: SNK _  
#e8NF,H5  
· 什么是自定义tag标签? M%8:  
jFBnP,WQ  
· 怎么使用tag标签? &<sN( ;%0R  
p$cSES>r:  
o 声明要使用的tag库 u*$ 1e  
-Fj:^q:@u  
o 找到与之对应的tag处理类 -]h3s >t  
G_] (7  
o tag标签的类型 A[6$'IJ  
e/<Og\}P/  
· 自定义tag标签 :A{ US9D  
-IB~lw  
o tag处理类 &v^LxLt+s  
Sgt@G=_o  
o tag库描述 QDC]g.x  
*?`:=  
o tag标签示例 T?+xx^wYk  
i }5 #n  
o 带属性的tag v* nX  
\5%T'S@5  
o 带body的tag Iz#h:O  
|'2E'?\/x  
o 定义了脚本变量的tag WlnI`!)d  
b:S#Sz$  
o 具有协作关系的tag P==rY5+s`  
2EOt.4cP  
· 自定义tag标签 ,z?Re)q m  
dfo{ B/+  
o 一个迭代tag的例子 j_?U6$xi  
(,E.1j]ji  
o 一个模板tag库 g=;c*{  
Xa2QtJq  
o tag处理类到底是怎样被调用的? a"{tqNc  
{}ZQK  
CW Y'q  
什么是自定义的tag? I hvL2 zB  
3`&2 -  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 ]OoqU-q  
|/g\N, ]  
自定义tag标签有很多特色,诸如: hIw<gb4J%  
.(  vS/  
· 可以在JSP页面中自定义tag标签的属性 @>J4K#"  
zb}:wUR  
· 访问JSP页面中的所有对象 m&OzT~?_>N  
\HDRr*KO  
· 可以动态地修改页面输出 NwmO[pt+  
H;<hmbN?d  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 S)GWr"m-  
gJ>?<F;  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 .h^."+TJ  
cT8jG ,+"}  
;""V s6  
使用tag标签 :JqH.Sqk  
 _tN"<9v.  
L^ VG?J  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 p~28?lYv  
j]6j!.1  
要使用tag标签,JSP程序员必须做2件事: 5-}4jwk  
VuFH >8n  
· 声明此tag标签的tag库 2_0OSbFv'P  
TE0hV w0c  
· 实现此tag标签 8p7Uvn+m*  
1P4jdp=~  
声明tag标签所在的tag库 4)iSz>  
7 #_{UJ%  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) $CO^dFf  
VZJs@qx:Z  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> ?G1-X~Z8  
u|=_!$8  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 q?&vV`PG5  
APuG8 <R,  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 .8l\;/o|  
;|b D@%@  
以下taglib指示符直接引用一个TLD: u%#bu^4"  
*:3flJt  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> CO1D.5  
+is;$ 1rq  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: o8RagSIo8  
a>Uk<#>2?a  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> ;&P%A<[`  
X<_(gg  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: xe|o( !(  
%K /=7  
<taglib> "W|Sh#JF  
7f'9Dm`  
<taglib-uri>/tutorial-template</taglib-uri> $TL~SVHj;{  
2Q)"~3  
<taglib-location> mKPyM<Q  
(J][(=s;a  
/WEB-INF/tutorial-template.tld 1/3Go97/qV  
c{6!}0Q4  
</taglib-location> .3A66 O~zT  
q.t>:`  
</taglib> KDuM;  
;c_X ^"d  
sE-E\+  
实现此tag标签 & p"ks8"  
pA+W 8v#*  
E:f0NV3"1  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 "ZNiTND  
oJUVW"X6  
0Oc' .E9  
tag标签类型 +%=Ao6/#  
^LE`Y>&m  
T c4N\Cy  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): SY["dcx+  
Z+=WgEu1  
<tt:tag> g9H~\w  
q[nX<tO  
body B5IS-d  
(01M0b#  
</tt:tag> MZB0vdx  
+g<2t,  
ync2X{9D  
一个不带body的tag标签如下: v-3In\T=^  
9;k_"@A6  
<tt:tag /> !uii|"  
[2gK^o&t  
F"#bCnS  
简单的tag标签 -]~&Pi|  
@H"~/m_o  
一个没有body和属性的tag标签如下: :se o0w]  
z[B*sbS  
<tt:simple /> &7!&]kA+  
Ka&[ Oz<w  
.vj`[?T  
带属性的tag标签 xN:ih*+,v  
iE, I\TY[  
K3$83%E  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 _$s9o$8$  
-LJbx<'  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: ]vMr@JM-G  
YQvN;W  
<loglic:present parameter = “Clear”> t>.mB@se|  
\C5YVl#  
而另一个标签logic:iterate是用表达式来给属性赋值: <LIL{g0eX  
rP>iPDf  
<logci:iterate collection=”<%= bookDB.getBooks() %>” 6e(|t2^  
fHCLsI  
id=”book” type=”database.BookDetails”> dq28Y$9~  
XMd-r8yYr  
!jL|HwlA  
带body的tag标签 '3O@Nxof4  
0'wB':v  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 I$9^i#O'3  
U+F?b\  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: bYGK}:T8U  
XZYpU\K  
<logic:present parameter=”Clear”> IqJ7'X  
x+x 6F  
<% cart.clear(); %> ce{(5IC  
$@"o BCc  
<font color=”#ff0000” size=”+2”><strong> N@lTn}U  
n#[-1 (P  
你选择了清除购物车! (= } cc  
D]S@U>]M!  
</strong></font> Kv^ez%I  
"Lk -R5iFd  
</logic:present> !qsk;Vk7Z  
Kq@nBkO4  
XW w=3$  
到底是用属性还是用body来传递信息? [`nY /g:  
-B-?z?+(O  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 0OO$(R*  
Fk@A;22N  
e>vV8a\  
定义脚本变量的tag标签 d0$dQg  
,_@C(O  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: w DswK "T  
LW<DhMV  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> k~Qb"6n2  
AuuZWd  
<% tx.begin(); %> <`,pyvR Kv  
MG)wVS<d_  
... PPSf8-MLW  
JRt^YX  
bfy `UZr  
具有协作关系的tag标签 }_93}e  
c`}-i6  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 /nEt%YYh;x  
=!u9]3)  
<tt:tag1 attr1=”obj1” value1=”value” /> |g<1n  
^HYmi\`  
<tt:tag2 attr1=”obj1” /> ,RIGV[u  
VP[ -BK[  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 "S#4  
\?uaHX`1  
<tt:outerTag> vH/<!jtI  
H }w"4s  
<tt:innerTag /> 9s\(yC8h  
4np,"^c  
</tt:outerTag> 0!X;C!v;  
w@RVg*`%7D  
c@9jc^CJ  
Tag处理类 V#8]io  
v Yt-Nx  
\pI)tnu6'U  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 .2?tx OKh  
\l!^6G|c  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 /N6sH!w  
b<,Z^Z_  
下表说明不同类型的tag所需要不同的处理过程: i(DoAfYf/q  
n5CjwLgu\b  
Tag处理类的方法 YT7,=k_  
[P,YW|:n  
Tag标签类型 RDU,yTHq  
所调用的方法 Q` mw2$zv  
'@enl]J  
基本标签 wq &|V  
doStartTag, doEndTag, release 3=o^Vv  
P Z5BtDm  
带属性的标签 i*3 4/  
doStartTag, doEndTag, set/getAttribute1...N, release 9F+i+(\,b  
U 7mA~t2E  
带内容的标签 = 7U^pT  
doStartTag, doEndTag, release }G^Bc4@b  
0v6(A4Y  
带内容的标签,且内容重复循环 'Okitq+O  
doStartTag, doAfterBody, doEndTag, release 4T#B7wVoM  
T&Dt;CSF  
带内容的标签,且内容与JSP交互 ;0*T7l  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release >C""T`5]  
OiPE,sv  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 ZUGuV@&-T  
jR~2mf!h*e  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 2yqm$i9C  
A:Y]<jt  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 y Q\K;  
?^iX%   
> Q1r^  
Tag库描述(简称TLD) fsc^8  
#PYTFB%  
A#9@OWV5f  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 F@Bh>Vb  
(WT0 j  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 ".+wz1  
c-nBB  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: EoLF7j<W  
AHsp:0Ma#  
<?xml version="1.0" encoding="ISO-8859-1" ?> E<]l]?  
n"B"Aysz  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> (1e;7sNG@  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: ) *:<3g!  
x7$U  
2^ 'X  
<taglib>的子元素 /'U/rjb_h{  
B.2F\ub g  
Element 5A]IiX4Z  
Description 9:0JWW^so  
hg7`jE&2  
tlib-version k#k!AcC  
Tag库的版本 n y6-_mA]  
(bH*i\W  
jsp-version 7NG^X"N{Ul  
Tag库所需要的jsp的版本 Nt42v  
cWIX!tc8  
short-name 'qBg^c  
助记符,tag的一个别名(可选) =]x FHw8A  
`T  $lTP  
uri <~# ZtD$G  
用于确定一个唯一的tag库 ]D&$k P(  
d#7 z N  
display-name D6Ov]E:fa  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) Q1V4bmM  
qA:CV(Z  
small-icon \2i4]V  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) G`E%uyjG$j  
Vf6lu)Z c1  
large-icon ?b, eZ+t  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) '/ 3..3k  
Bt|S!tEy  
description UMUr"-l =  
对tag库的描述(可选) b8)>:F  
B]]_rl,  
listener (A`/3Aq+  
参见下面listener元素 ' U{?"FP  
`9b/Q  
tag c_a*{L|c  
参见下面tag 元素 cF_`m  
<jU[&~p  
Listener元素 msg&~" Z  
k!O#6Z  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 ]qL#/   
\Oh9)X:I  
Tag元素 H?ssV^k  
q{Hk27kt  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 Y cE:KRy  
O-:#Q(H!  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: [>&Nhn0iY  
f33'2PYl  
Tag元素的子元素 )K>XLaG)  
"v4;m\g&:  
元素名称 [qlq&?"  
描述 laqKP+G  
/ow/)\/}  
name bmna*!l^M  
独一无二的元素名 RvV4SlZz  
 f]q3E[?/  
tag-class LlL\7?_;  
Tag标签对应的tag处理类 g*\u8fpRq  
p #'BV'0bl  
tei-class >[,Rt"[V  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) ~;#J&V@D  
r]Da4G^  
body-content qO[6?q=c:  
Tag标签body的类型 6'395x_ .\  
MX6*waQ-<  
display-name r Y|'<$wvg  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) F%bv vw*(  
E*>tFw&[  
small-icon enlk)_btp  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) RfDIwkpp  
vlIet$ k  
large-icon _ZIaEJjH/  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) P1 =bbMk  
Q[scmP^$^  
description *RUB`tEL  
此tag标签的描述 *fW&-ic  
1gts=g.  
variable 8^&)A b  
提供脚本变量的信息(同tei-class)(可选) ;SeDxyKG  
?(>7v[=iT  
attribute W"AWhi{h  
Tag标签的属性名 #B"ki{Se*  
f( hK>H  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 Wt()DG|[  
.\X/o!xC  
NwD*EuPF:  
简单的tag 9c9-1iS  
gl:vJD  
;gy_Qf2U  
tag处理类 c)#b*k,lw<  
>#*]/t  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。  Us k@{  
RPP xiYU^  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: (' /S~  
71 hv~Nk/x  
o DPs xw  
public SimpleTag extends TagSupport /#20`;~F)  
`x~k}  
{ a36n}R4Q  
g10$pf+L  
public int doStartTag() throws JspException 8\!0yM#yK  
E0\ '  
{ fC.-* r  
UY*Hc  
try{ VaJX,Q  
Otj=vGr0  
pageContext.getOut().print(“Hello.”); s!nFc{  
_D1bR7  
}catch(Exception e){ ]2QZ47  
M7Cq)cT  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); >wej1#\3  
y mY,*Rb  
} H&[CSc  
W>K2d  
return SKIP_BODY; (-(,~E  
tNjb{(eO\h  
} lEQ 63)Z  
8?W\kf$  
public int doEndTag() cInzwdh7  
}EE  
{ uh\I'  
"@Ra>qb  
return EVAL_PAGE; j,/OzVm9  
!\JG]2 \  
} 1& YcCN\k  
$V]D7kDph*  
} W!4GL>9m}A  
Dgj`_yd  
j8M}*1  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 hx+a.N  
DvF`KHsy  
<body-content>empty</body-content> *oY59Yf  
t&mw@bj  
mc?5,oz;pz  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 -/~^S]  
W ;,Uh E  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, FnP/NoZa>  
Z]1~9:7ap  
<logic:present parameter=”Clear”> s_.q/D@vu  
4_&$isq  
与此相应,此tag处理类应有如下方法和定义: RB\>$D  
8/-GrdyE  
G- Sw`HHo  
protected String parameter = null; LdU, 32  
b^y#.V.|k  
public String getParameter() 'hVOK(o 0  
Z2PLm0%:  
{ qX0IHe  
"h_n/}r=  
return this.parameter; 3+{hO@ O  
f>\?\!  
} :&2RV_$>=  
.<u<!fL2  
public void setParameter(String parameter) rP2^D[uM.  
7w @.)@5  
{ 2(5wFc  
gEO#-tMjOQ  
this.parameter = parameter; kzLj1Ix2  
w/d9S(  
} $*xnq%A  
Gw~^6(Qu  
uTbI\iq  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 yIXM}i:  
\&2GLBKpe  
Attribute元素 q}ZZqYk  
!g=,O6  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 k#JFDw\  
q0`Vw%  
<attribute> @K4} cP  
H^K(1  
<name>attr1</name> v_{`O'#j^  
5}*aP  
<required>true|false|yes|no</required> EK@yzJ%  
WB6g i2  
<rtexprvalue>true|false|yes|no</rtexprvalue> 5>KAVtYvc  
V/"0'H\"1  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type>  Ca@[]-_H  
p tv  
</attribute> "LaNXZ9  
P6i4Dr  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 s:*gjoL  
gBYL.^H^l  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 Yah3I@xGy  
]'~'V2Ey  
<tag> O5Yk=-_m  
Arir=q^2  
<name>present</name> 9^v|~f  
`USR]T_`  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> zi-zg Lx  
wE%v[q[*X  
<body-content>JSP</body-content> M`BD]{tN}  
8Dhq_R'r  
9VV  
F m h;d*IT  
<attribute> L9fhe,en  
87~. |nu  
<name>parameter</name> :/~`"`#1  
$aE %W? \  
<required>false</required> 4mNL;O  
Y)c9]1qly  
<rtexprvalue>true</rtexprvalue> n@T4z.*~lA  
"h$A.S  
</attribute> C~'}RM  
K+ufcct  
\ts:'  
$o/ ?R]h  
</tag> pA(@gisg  
YXrTm[P  
k-e_lSYk&c  
属性元素的校验 W qci51y>#  
%pL ,A5M  
wF?THkdFo  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 a3R#Bg(  
w^G<]S {l  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 U>:CX XHRt  
N=tyaS(YJ  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 ],qG!,V  
NZ7a^xT_)  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: bi#o1jR  
#`y7L4V*o  
<attribute> 1ReO.Dd`R  
f IQ$a >  
<name>attr1</name> UbY-)9==  
8* >6+"w  
<required>true</required> :ozHuHJ#  
N+HN~'8r  
<rtexprvalue>true</rtexprvalue> C*kZ>mbc  
9zi/z_G  
</attribute> f 7d)  
Pa0tf:  
Gp; [WY\  
这个定义说明了attr1能在运行期间被赋值。 .LnXKRd{  
Yfxc$ub  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 kW6}57iV  
qi7dcn@d  
LeQ2,/7l:  
Public class TwaTEI extends TagExtraInfo L G{N  
P)>WIQSr  
{ ""CJlqU  
oo- ^BG  
public boolean isValid(Tagdata data) OaU} 9&  
.Zf#L'Rf  
{ <adu^5BI  
qLA  
Object o = data.getAttribute(“attr1”); #\%Gr tM  
<C# s0UX  
If(o != null && o != TagData.REQUEST_TIME_VALUE) YA{Kgc^  
2r PKZ|  
{ tQo"$ JN}  
@_N -> l  
if( ( (String)o).toLowerCase().equals(“true”) || 9dqD(S#C;"  
k?|VFh1  
((String)o).toLowerCase().equals(“false”) ) q_cqjly<  
rAP+nh ans  
return true; jD H)S{k  
la|#SS95  
else uZ<Bfrc  
gJ vc<]W8!  
return false; IK~ur\3  
,2&'8:B  
} 3i35F.=X,  
MW'z*r|,  
else _I5p 7X  
Y*wbFL6`  
return true; GN=F-*2  
g6 7*Bs  
} 6u8`,&U  
$Cc4Sggq  
} .Ddl.9p5  
F^`sIrZvs  
_@?]!J[  
带body的tag &(Xp_3PO  
a`/[\K6  
G=yQYsC$  
tag处理类 ;qG a|`#j  
`I6)e{5t  
M&Ycw XV:Z  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 Z!LzyCVl  
~a/yLI"'g  
Tag处理类不与body交互 6"ZQN)7  
hrEKmRmF-  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 f)"O( c  
$JX_e  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 J8/>b{Y  
4I{|M,+  
Tag处理类与body交互 Y;-"Z  
#-e3m/>  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 Dk ]Y\:  
63:ZDQ  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 [DjdR_9*I  
6 D!,vu  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 8)R )h/E>  
cC4*4bMm  
doInitBody 方法 9%\q*  
7p u*/W~  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 7(gQ6?KsZ  
[Hn+r &  
doAfterBody方法 {yspNyOx  
-R6z/P (}  
此方法在body内容已被计算后进行调用。 9D8el}uHf  
Y*J`Wf(w  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 T*A_F [  
puMpUY  
release 方法 2!&:V]  
YW/YeID  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 hnE@+(d=qJ  
'<1T>|`/t  
mjy%xzVr6^  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 tYmWze. j  
O-  r"G  
K 7YpGGd5  
Public class QueryTag extends BodyTagSupport m$[ \(Z(/  
Qj 0@^LA  
{ #C !8a  
UN,@K9  
public int doAfterBody() throws JspTagException NSM-p.I9  
qx`*]lX  
{ W0gaOew(^  
S' TF7u  
BodyContent bc = getBodyContent(); ,h>0k`J:a  
)(75dUl  
//将body的内容以字符串的格式提取出来 xj%h-@o6  
chfj|Ce]x  
String query = bc.getString(); Oo=} j  
=b9?r  
//清除body 8$3Tu "+;  
u-jGv| ,|  
bc.clearBody(); VN`2bp>5I  
c9f~^}jNb  
try{ 0v',+-  
pD`7N<F 3  
Statement stmt = connection.createStatement(); 2ht<"  
C=9|K`g5 R  
Result result = stmt.executeQuery(query); X g.\B1d  
T7!a@  
}catch(SQLException e){ mC J/gWDY  
PtmdUHvD  
throw new JspTagException(“queryTag: “ + e.getMessage() ); \zgRzO'N  
dos$d3B4  
return SKIP_BODY; $IB@|n  
+2C:]  
} bO^%#<7  
3- LO  
} w 7=Y_  
WWq)Cw R  
&o:ZOD.  
body-content元素 yUEUIPL  
m6'YFpf)V  
_!w# {5~  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: _|H]X+|  
S/7D}hJ  
<body-content>JSP|tagdependent</body-content> 1Pn!{ bU3@  
G ytI_an8  
n6ud;jN|  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 !BK^5,4?--  
 "FG6R'  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 0jj }jw  
M# S:'WN  
SU H^]4>  
用tags定义脚本变量 SznNvd <  
0]i#1Si~@  
5/neV&VcB  
tag处理类 2R|2yAh  
4my8 p Fk  
EeL~`$f  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 7J0 PO}N  
EY> %#0  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 c3K(mM:  
:@YZ6?hf  
对象的生存周期(scope)如下表: .@1\26<  
z2nDD6N  
对象的生存周期表 t%N#Yh!  
kk^KaD4dA  
名字 Vf O0 z5&  
可访问范围 srg#<oH|{c  
生存周期 .,tf[w 71  
@0Tm>s  
page 7j._3'M=Kc  
当前页面 \kC/)d  
一直有效,除非页面向客户提交响应或重定向到一个新页面 CUY2eQJ{U  
l|5ss{llR  
request 1gCp/m2r7  
当前页面或当前页面重定向到的页面 ]6 }|X#_  
一直有效,除非页面向客户提交响应 |A0kbC.  
C 5)G^  
session 5b|_?Em7  
当前页面或在同一浏览器窗口中的页面 >/evL /  
一直有效,除非关闭当前浏览器、超时、网络故障 wGb{O  
5RZAs63t  
application ><^A4s  
整个web应用程序的所有请求 .X YSO  
一直有效,除非发生网络故障、服务器故障 # Wh"_zpM+  
W\FKA vS  
提供关于脚本变量的信息 "&v?>  
.B>|>W O  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: &ec_jxF  
CDR^xo5 dP  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> N=:yl/M  
>(d+E\!A  
<font color=”red” size=”+2” > Z#^2F8,]  
&S c0l/  
<%= messages.getString(“CartRemoved”) %> .RoO 6:T6  
?Yz.tg  
<strong><jsp:getProperty name=”book” property=”title” /></strong> :'.-*Ew  
`(Ei-$ >U&  
</font> $]Y' [pE@  
\/{qE hP  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: AF **@iG  
:i?Z1x1`  
· 脚本变量名称 =XudL^GF  
)e]:T4*vo  
· 脚本变量所属的类 WMl_$Fd6  
dk;Ed  
· 此脚本变量是否引用了一个新的或已存在的对象 -/7[_,  
#`}g?6VHo  
· 此脚本变量的有效性 5C{X$7u  
I8`.e qV  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 bNIT 1'v  
`4l>%S8y:  
Variable元素 cC WOG d  
bCA3w%,kM  
Variable元素有如下子元素: Cg)#B+  
nef-xxXC^I  
· name-given ?D?D 给出的名字,是一个常量 kZF\V7k  
l m-ubzJN  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 I caIB)  
OJkPlDym  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: 2ZLK`^S  
_v]I6<!5U  
· variable-class?D?D变量的类型,缺省为java.lang.String。 &t p5y}=n  
Tz%l 9aC  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 b*.)m  
6^|bKoN/ f  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: d5sG t#   
g/V C$I!'  
脚本变量的有效范围 lWnV{/q\X  
1\zI#"b ^  
L\hPw{)  
有效性 VVCCPK^<  
方法 X2sK<Qluql  
RAf+%h*  
NESTED SHz& o[u  
在tag标签的开始和结束之间 15nc  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 5dYIL`  
NW!e@;E+i  
AT_BEGIN oJXZ}>>iT  
从tag标签的开始一直到页面结束 yu}4L'e  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 sM~CP zMa  
?6uh^Qal  
AT_END ( B50~it  
从tag标签的结束一直到页面结束 ) e;F@o3  
在doEndTag中调用 4 Ag+  
-pkeEuwv{  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: QHtpCNTVb  
Eb{TKz?  
<tag> eaF5S'k 4$  
KJ'MK~g  
<variable> :5@7z9 >  
mHw1n=B  
<name-from-attribute>id</name-from-attribute> 1 4(?mM3   
|fRajuA;  
<variable-class>database.BookDetails</variable-class> :q6hT<f;  
*%8,G'"r?  
<declare>true</declare> 2hU4g e?6  
D8Ni=.ALL  
<scope>AT_BEGIN</scope> 3OM\R%M  
>E)UmO{S  
</variable> n,xK7icYNQ  
{9C(\i +  
</tag> c}rRNS$F  
hoU&'P8  
额外tag信息类 QuF%m^aE  
i37W^9 R  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: =E |[8 U)  
+.>O%pNj  
· 变量名 BB>7%~3f  
>1joCG~  
· 变量所属类名 ?]paAP;4  
1 u&P,&T  
· 此变量是否引用了一个新对象 eZg31.  
k$I[F<f  
· 此变量的有效范围 #uey1I@"9  
ZE}m\|$  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 h]MSjC.X  
TxxW/f9D  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: *NXwllrci  
5i1>z{  
#!, xjd  
public class DefineTei extends TagExtraInfo b*p,s9k7  
aD 3$z;E  
{ ;q$<]X_S)}  
7Y#b7H  
public VariableInfo[] getVariableInfo(TagData data) RA\H?1;8C  
c/g(=F__[  
{ sPd5f2'  
&Kjqdp  
String type = data.getAttributeString(“type”); JaIj 9KLNX  
Z;%qpsq  
If( type == null) AY! zXJ_$  
[r]USCq  
type = “java.lang.Object”; KTf!Pf?g  
oh:t ex<  
return new VariableInfo[] { 5d L-v&W  
YY]LK%-  
new VariableInfo(data.getAttributeString(“id”), O+'Pq,hn  
3>S.wyMR4  
type, VQ}=7oe%q  
kSI,Q!e\  
true, I7[+:?2  
7Y!^88,f.  
VariableInfo.AT_BEGIN) "CZ`hx1|^  
y ruN5  
}; >,~JQ%1  
/>$)o7U`+  
} if `/LJsa  
'nCBLc8  
} S++}kR);  
`NGCUGQ_7  
"M? (Ax  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: 1F$a My?  
<tei-class> KUly"B  
org.apache.struts.taglib.bean.DefineTagTei ?rv+ydR/q  
</tei-class> !(o)*S  
aV>w($tdd  
f|b|\/.=  
具有协作关系的tag *Qyw _Q  
}Y-f+qX*  
A\:=p  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 ^ qE4:|e  
'x!q*|zF2  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 sA` bPhk  
^K;,,s;0  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 ;APg!5X  
3J [P(G>Q  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 [F6=JZ  
UQTt;RS*zS  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 l+T\DZ  
"5>p]u>  
qkR.{?x  
public class QueryTag extends BodyTagSupport ^@tn+'.  
KH@M & >=^  
{ xXHz)w  
vK$T$SL  
private String connectionId; ~(yh0V  
w|RG  
public int doStartTag() throws JspException 6}|/~n  
x9@%L{*  
{ (zTr/  
(M[Kh ^  
String cid = getConnection(); r_R|.fl<[  
0gt/JI($  
if(cid != null) x.45!8Zb  
OP<@Xz  
{ Q_@ Z.{  
KsHovv-A  
//存在一个connection id,使用它。 &<v# ^2S3  
J.El&Dev  
connection = (Connection) pageContext.getAttribute(cid); )"f>cYF  
G19FSLrtA  
} YDDwvk H  
y0rT=kU  
else ,ZH)[P)5P  
[KCh,'&  
{ \yM[?/<  
JRl8S   
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, SX*os$  
#Dy;x\a  
ConnectionTag.class); *d(wO l5[  
La3f{;|u5M  
if(ancestorTag == null) ~6@~fhu  
Wp >W?'`  
{ u wf3  
2t[inzn=E  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); Tm` QZh3  
EB>laZy>  
} a@m>S$S  
>Z>*Iz,LP  
connection = ancestorTag.getConnection(); ,=K!Y TeVl  
+mAMCM2N  
} :X@;XEol~  
MR8-xO'w  
} n>!E ]  
oYOf<J  
} \Lh,dZ}d  
1!=$3]l0Lj  
6bfk4k  
x\t>|DB  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: 9X=#wh,q  
V ;>{-p  
!%5{jO1  
<tt:connection id=”con01” ...> ... </tt:connection> ~\XB'  
c*6o{x}K  
<tt:query id=”balances” connection=”con01” > 62Jn8DwAT  
}eB\k,7L  
SELECT account, balance FROM acct_table m,=$a\UC  
BPi>SI0  
where customer_num = <%= request.getCustno() %> Zwq uS9  
vy-{BH  
</tt:query> ]kKf4SJZFU  
9>zN 27  
@#o$~'my  
5X~ko>  
r$0=b -  
<tt:connection ...> z<@$$Z=0UF  
<5L!.Ci  
<x:query id=”balances”> f1\x>W4z~\  
Jr1^qY`0+  
SELECT account, balance FROM acct_table :  l]>nF4  
!3T x\a`?/  
where customer_num = <%= request.getCustno() %> G+5G,|}  
+mxsjcq0  
</x:query> MTqbQ69v  
YQ?|Vb U  
</tt:connection> .+B!mmp  
%\- +SeC  
vTB*J,6.  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: 2$3BluK  
Z{ p;J^:  
<tag> iJsw:Nc  
h` n>6I  
... AM Rj N;  
29Gej Lg |  
<attribute> m"v` E7G  
6tnAE':  
<name>connection</name> 8#oF7eE  
)6AOP-M.9  
<required>false</required> *|`'L  
6J=~*&  
</attribute> {0QA+[Yd&!  
Q'\jm=k  
</tag>
描述
快速回复

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