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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! m- <y|3  
m#RJRuZ|2V  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 [d[w/@  
2'S&%UyP  
在这篇文章中,我们主要讨论: pPRX#3  
+8//mrL_/  
· 什么是自定义tag标签? %`5 (SC].  
raPOF6-_rH  
· 怎么使用tag标签? a&8K5Z%0  
>t cEx(  
o 声明要使用的tag库 ;Y*K!iFWH  
iXnXZ|M  
o 找到与之对应的tag处理类 ftPps -  
I&La0g_E  
o tag标签的类型 tf6m .  
4}; @QFT*  
· 自定义tag标签 (cLKhn@  
&]n }fq  
o tag处理类 ,6g{-r-2  
%[*-aA  
o tag库描述 0@zJa;z'  
IVSC7SBiT  
o tag标签示例 (?1$  
KZ7B2  
o 带属性的tag ?tjEXg>ny  
z U[pn)pe  
o 带body的tag -@w,tbc$  
:V+rC]0  
o 定义了脚本变量的tag }/1^Lqfnz  
d5gwc5X  
o 具有协作关系的tag NzQvciJ@"  
}?Y -I> w  
· 自定义tag标签 8+oc4~!A@n  
% E1r{`p  
o 一个迭代tag的例子 Ly2,*\7  
PkDt-]G.  
o 一个模板tag库 'W_NRt:  
x&;AY  
o tag处理类到底是怎样被调用的? ~wW]ntZm  
2Cp4aTGv#  
3pWav 1"  
什么是自定义的tag? 8m iJQIq  
^;PjO|mD Z  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 f<bB= 9J  
cwzkA,e@  
自定义tag标签有很多特色,诸如: fKY-@B[|  
7Fo^ :"  
· 可以在JSP页面中自定义tag标签的属性 ?{TWsuP7  
\2y/:  
· 访问JSP页面中的所有对象 ,V9qiu=m   
Jl\xE`-7  
· 可以动态地修改页面输出 X2A k  
Fw&ImRMk  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 wd*B3  
jV*10kM<  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 [IOI&`?D  
LD[\eJ _  
GW>F:<p  
使用tag标签 &qXobJRM  
)b1hF  
QHO n?e  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 t!rrYBSCr  
-r cEG!  
要使用tag标签,JSP程序员必须做2件事: _oc6=Z  
q&@s/k  
· 声明此tag标签的tag库 SzpUCr"  
xFp$JN  
· 实现此tag标签 zy$jTqDH  
m=9b/Nr4  
声明tag标签所在的tag库 RM_%u=jC  
9)t b=  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) ?+hEs =Xs  
|k6+- 1~_  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> N/0aO^"V  
:} =lE"2  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 [x{$f7CEh  
9~~NxWY%x  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 1<m`38'  
L-?ty@-i  
以下taglib指示符直接引用一个TLD: !8UIyw  
+C!GV.q[  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> :(US um  
WZ ?>F  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: }TMO>eB'  
~2rQ80_  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> K9xvog  
F?2UHcs  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: 0a:oC(Ak  
&l2xh~L  
<taglib> ?X|q   
A;rk4)lij  
<taglib-uri>/tutorial-template</taglib-uri> Rf4K Rhi  
c9Et Uv~  
<taglib-location> _$$.5?4  
}w4OCN\1  
/WEB-INF/tutorial-template.tld F,S)P`?  
u=nd7:bv  
</taglib-location> K.QSt  
QD%xmP  
</taglib> 26aDPTP$<  
5 OWyxO3{  
++b[>};  
实现此tag标签 k vZw4Pk  
~ `}),aA  
<MJU:m $3  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 vai w*?jV  
NL:-3W7vf  
npzp/mcIe)  
tag标签类型 {?lndBP<  
z**2-4 z  
(mP{A(kwJ  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): \ejHM}w3,  
9+9g(6  
<tt:tag> yOz6a :r  
V. i{IW  
body &X:;B'   
=M-=94  
</tt:tag> v zs4tkG  
fWJpy#/^*K  
OcV,pJ  
一个不带body的tag标签如下: u_NLgM7*  
&=)O:Jfa  
<tt:tag /> G8vDy1`q6  
\;MP|:{pU  
O'(Us!aq  
简单的tag标签 AHn!>w,  
~.3v\Q  
一个没有body和属性的tag标签如下: RN 4?]8  
s.7=!JQ#]p  
<tt:simple /> %`k [xz  
AR( gI]1  
`l'T/F \  
带属性的tag标签 A{;"e^a-^l  
z<9C-  
Q(-&}cY  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 8>WA5:]v  
5QK%BiDlr  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: J/P[9m30[  
+pG+ xI  
<loglic:present parameter = “Clear”> t[+bZUS$~  
"9'3mmZm=?  
而另一个标签logic:iterate是用表达式来给属性赋值: zx<PX  
db,?b>,EE  
<logci:iterate collection=”<%= bookDB.getBooks() %>” v|~=rvXFC  
T1$p%yQH  
id=”book” type=”database.BookDetails”> (" :Dz_  
?xv."I%  
uz+ WVmb  
带body的tag标签 nxV!mh_  
OEaL2T  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 6oLOA}q   
PP$2s]{  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: AP%R*0]  
+&)/dHbL`]  
<logic:present parameter=”Clear”> #z>I =gl  
Pl/Xh03E  
<% cart.clear(); %> *K_8=TIA*  
0IqGy}+VU  
<font color=”#ff0000” size=”+2”><strong> d6*84'|!  
mW!n%f  
你选择了清除购物车! <eMqg u  
&,<,!j)Jr  
</strong></font> RiAg:  
rfVQX<95=/  
</logic:present> s9"X.-!  
.gfi9J  
)nf%S+KV  
到底是用属性还是用body来传递信息? gmH`XKi\  
|Q)mBvvN  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 *#>(P  
pLe4dz WA  
@2. :fK  
定义脚本变量的tag标签 eE'>kP}  
-4+'(3qr  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: &&l ZUR,`  
*cM=>3ws/  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> uQH]  
mZB:j]T  
<% tx.begin(); %> 7"2BZ  
)/DN>rU  
... 2;T?ry7  
WqefH{PB  
+o4o!;E)  
具有协作关系的tag标签 Wjq9f;  
]Xa]a}[uE  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 LE{@J0r#n  
Sak^J.~G[  
<tt:tag1 attr1=”obj1” value1=”value” /> ;6R9k]5P%  
_Ycz@Jn  
<tt:tag2 attr1=”obj1” /> ;taZixOH  
1@{ov!YB]  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 d+)LK~  
~l:Cj*6x8  
<tt:outerTag> ssQ1u.x9  
3<<wHK;)  
<tt:innerTag /> *:d ``L  
r3?8nQ$  
</tt:outerTag> +|bmUm<2  
`^{G`es  
5'f_~>1Wt  
Tag处理类 H0inU+Ih  
|)To 0Z  
MkFWZ9c3  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 3HXeBW  
Txo{6nd/  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 ZiY2N*,VO  
7Z:3xb&>   
下表说明不同类型的tag所需要不同的处理过程: 9\?&u_ U"  
EsWB|V>  
Tag处理类的方法 2m*ugBO;  
JdI*@b2k[  
Tag标签类型 yn ofDGAf  
所调用的方法 uY)4y0  
7Fpa%N/WL  
基本标签 EwG+' nlE  
doStartTag, doEndTag, release ?MSZO]Q4+  
[V_mF  
带属性的标签 ha|2u(4  
doStartTag, doEndTag, set/getAttribute1...N, release X~m57 b j  
:CM-I_6  
带内容的标签 9$v\D3<Z  
doStartTag, doEndTag, release *-]k([wV  
i| cA)  
带内容的标签,且内容重复循环 :| k!hG  
doStartTag, doAfterBody, doEndTag, release +7OE,RoQ  
l+6@,TY1U  
带内容的标签,且内容与JSP交互 4J,6cOuW4  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release Mfz(%F|<  
<5KoK!H  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 VJK4C8]  
h{-en50tN  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 } %0 w25  
*{5}m(5F  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 `m1stK(PO  
Rq|5%;1  
RgFpc*.T  
Tag库描述(简称TLD) "fNv(> -7s  
jS3@Z?x?*  
o/ \o -kC}  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 6flO;d/v  
B YB9M  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 o(v`  
Z{(Gib~{N  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: !^L}LtqHI  
as 3uz  
<?xml version="1.0" encoding="ISO-8859-1" ?> 9VaSCB  
|:(BI5&S  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> ;QuxTmWp^  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: 6k,@+ @]t.  
0|va}m`<3G  
nq7)0F%e  
<taglib>的子元素 >/.jB/q  
/:A239=+?  
Element D.AiqO<z  
Description wMF1HT<*  
2\$<&]q  
tlib-version }1CO>a<  
Tag库的版本 hHw1<! M  
8_>:0(y  
jsp-version u (r T2  
Tag库所需要的jsp的版本 "OUY^ cM  
Zq1> M'V;  
short-name UBM8l  
助记符,tag的一个别名(可选) .O~rAu*K  
b,HXD~=  
uri &C,]c#-+  
用于确定一个唯一的tag库  H!y@.W{_  
YA8/TFu<_  
display-name Tz& cm =  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) BI#(L={5  
?b^<Tny  
small-icon .*EP$pc  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) (#je0ES  
Q4ii25]*  
large-icon IP !zg|c,  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) IMSm  
QKz2ONV=)  
description Q(8W5Fb?  
对tag库的描述(可选) c$A}mL_  
e!i.u'z  
listener ?1]B(V9nBq  
参见下面listener元素 ,aWfGh#$  
nYRD>S?uz  
tag <N 80MU L|  
参见下面tag 元素 g5Hsz,x  
0\$Lnwp_  
Listener元素 :]C\DUBo  
[MC}zd'/  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 8^-g yx'  
9D%~~~ %b  
Tag元素 !})3Fb  
I$i1o #H  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 Pt;\]?LVrD  
~ C_2D?  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: g=v[@{9Pw  
E\}Q9, Z$  
Tag元素的子元素 C$c.(5/O  
5o(=?dXm4  
元素名称 p|*b] 36  
描述 @qJv  
J _|>rfW  
name |4Q><6"G  
独一无二的元素名 IZ4jFgpR  
8J9o$Se  
tag-class yFP#z5G  
Tag标签对应的tag处理类 .Qj`_q6=  
Sag\wKV8  
tei-class VHws9)  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) ]Otl(\v(h  
LyXABQ]  
body-content 1hp@.Fv  
Tag标签body的类型 @1[LD[<  
9=~jKl%\vJ  
display-name )=D9L  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) 7 ~ Bo*UM  
wY}+d0Ch  
small-icon Ki@8  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) Ix5yQgnB}j  
0MzHr2?'P  
large-icon l}c<eEfOy"  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) `wG&Cy]v  
%n c+VL4  
description g(;ejKSR  
此tag标签的描述 N=L urXv  
7~`6~qg.  
variable B "}GAk}V  
提供脚本变量的信息(同tei-class)(可选) I`KN8ll  
tbk9N( R  
attribute 8@Km@o]?  
Tag标签的属性名 J5rR?[i{  
)'<zC  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 bm7$DKp#  
&q` =xF  
QnOa?0HL/  
简单的tag p|bpE F=U  
~E`A,  
IweQB}d  
tag处理类 qx? lCz a"  
Cw^)}23R  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 EGMcU| yL  
Yc5$915  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: X:g5>is|  
y.oJzU[p%  
I2l'y8)d  
public SimpleTag extends TagSupport a+BA~|u^  
Em.?  
{ `RzM)ILl  
=XS'V*  
public int doStartTag() throws JspException wYawG$@_  
Ia"bP` L  
{ :3Jh f$  
I5"=b}V5  
try{ u})JQ<|  
0UB'6wRVo  
pageContext.getOut().print(“Hello.”); NAocmbfNz  
-jw=Iyv  
}catch(Exception e){ JT-Zo OZ  
Cw2+@7?|  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); ,^,J[F  
aY+>85?g  
} LtvyWc`  
) D`_V.,W  
return SKIP_BODY; BZ T%+s;u9  
wb9zJAsc  
} q.X-2jjpx:  
(6+0U1[Iz  
public int doEndTag() tE>:kx0*3  
J8D-a!  
{ +[7u>RJ  
K^vMIoh  
return EVAL_PAGE; z'I0UB#  
NV;tsuA|  
} \^:f4ZT  
Te13Af~  
} gy[uq m_ T  
\ a<Ye T  
1wM p3  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 1|89-Ii]  
zc(7p;w#p  
<body-content>empty</body-content> xMh&C{q  
cS[`1y,\3  
0nuFWV  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 ~}116K  
lb('r"*.  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, >j?uI6Uw  
M@3H]t?  
<logic:present parameter=”Clear”> zYNJF>^<  
U|QDV16f  
与此相应,此tag处理类应有如下方法和定义: ]9:G3vq  
'37b[~k4  
:[&X*bw[  
protected String parameter = null; "8I4]'  
T_dd7Ym'8  
public String getParameter() \NqC i'&  
(65p/$Vh  
{ {m?x},  
$} Myj'`r  
return this.parameter; Z-?9F`}  
;F Bc^*q  
} H#y"3E<s  
uI[*uAR  
public void setParameter(String parameter) )em.KbsPPF  
Z0=OR^HjA  
{ -iHhpD9"X  
T_-MSXhA  
this.parameter = parameter; KPhqD5, (  
;z>YwRV  
} on\\;V_/Q  
>R<fm  
_<7FR:oBZ  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 #u$z-M !  
`vSsgG  
Attribute元素 ){:aGGtko  
v(O.GhJ@  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 ;=OH=+R l  
=.c"&,c?L  
<attribute> ~e<<aTwN  
v2'J L(=  
<name>attr1</name> &?nF' ;&  
"q .uiz+1:  
<required>true|false|yes|no</required> di 5_5_$`o  
%U 7B0-  
<rtexprvalue>true|false|yes|no</rtexprvalue> hz%IxI9  
ap~Iz  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> _1'Pb/1  
;GS JnV  
</attribute> bph*X{lFK  
\t@`]QzG:  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 UJ[a& b  
cIp h$@  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 i`$rzXcS  
/(aX>_7jg  
<tag> A2d2V**Z  
g OM`I+CwT  
<name>present</name> pS;dvZ  
D.b<I79bX  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> 0 y%R  
MVdx5,t  
<body-content>JSP</body-content> :N}KScS|Wa  
eZi<C}z  
cG:`Zj~4  
d ] ;pG(  
<attribute> )[*O^bPowI  
\irjIXtV  
<name>parameter</name> F948%?a  
{@Ac L:Eit  
<required>false</required> o=QF>\ \  
*lAdS]I  
<rtexprvalue>true</rtexprvalue> <*(R+to^d  
@ `D6F;R  
</attribute> s_!Z+D$K  
~x:] ch|  
. $YF|v[=  
vM/v}6;_K2  
</tag> AtDrQ<>y'  
$lA,{Q  
59J9V3na  
属性元素的校验 UAZ&*{MM^  
hJsC \C,^  
4 G[hU4L  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 ASw |sw  
u0b-JJ7)BQ  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 sEyl\GL  
S45>f(!  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 j:3Hm0W3  
YWrY{6M  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: .`N` M9  
'Y\"^'OU\  
<attribute> @98SC}}u  
%)Dd{|c  
<name>attr1</name> UE w3AO  
cV,Dl`1r  
<required>true</required> Po. BcytM  
\r,. hUp  
<rtexprvalue>true</rtexprvalue> #9VY[<  
%0]b5u  
</attribute> [_b='/8  
}Xv1KX'  
I>Fh*2  
这个定义说明了attr1能在运行期间被赋值。 a&Du5(r;!  
5O ;^Mk|  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 z %E!tB2o  
*%'7~58ObS  
G!%XQ\a!  
Public class TwaTEI extends TagExtraInfo {NgY8w QB  
9mphj)`d;#  
{ _C=[bI@  
>0#q!H,X  
public boolean isValid(Tagdata data) arVf"3a  
_)2TLA n3  
{ >Eg. c  
b2%bgs  
Object o = data.getAttribute(“attr1”); ]},Q`n>$  
J&65B./mD9  
If(o != null && o != TagData.REQUEST_TIME_VALUE) s FYJQ90it  
14!a)Ijl  
{ ?9@Af{b t2  
I} fcFL8  
if( ( (String)o).toLowerCase().equals(“true”) || $'{`i 5XB  
vqz#V=J{  
((String)o).toLowerCase().equals(“false”) ) -01 1U!  
t0d '>  
return true; {}&f\6OI%  
Z;SG<  
else LE80`t>M#  
*1S.9L  
return false; _|wY[YJ[  
x~Ly$A2p  
} Z)T@`B6  
1"B9Z6jf  
else @ZR4%A"X4  
8!Mzr1:  
return true; ,xe@G)a  
^^3va)1{!  
} x][9ptr h  
gdFoTcHgO|  
} NG!cEo:2aa  
&t|V:_?/x  
exEld  
带body的tag G^@Jgx3n  
@j2*.ee  
HT=Am  
tag处理类 mYOdBd  
)LrCoI =|  
9iddanQA  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 +\[![r^P  
`e'o~ oSu  
Tag处理类不与body交互 pMZf!&tM  
$F`<&o  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 )bXx9,VL  
akc"}+-oX  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 h)l&K%4;  
qb&N S4#  
Tag处理类与body交互 eTRx6Fri(  
-WBz]GW4r  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 o7a6 )2JK  
+IO1ipc4cE  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 .Jat^iFj0  
Q()RO*9  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 -1r & s  
Nk7eiQ  
doInitBody 方法 MD ?F1l"}%  
X)iWb(@k"7  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 B 6'%J  
&Bz7fKCo  
doAfterBody方法 uyRA`<&w  
7}tZ?vD  
此方法在body内容已被计算后进行调用。 pg}+lYGP  
-=t3O#  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 "kBqY+:Cn  
Ril21o! j  
release 方法 fov=Yd!  
fzFvfMAU  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 R4~zL!7;  
Wt)SdF=U/  
ZH$sMh<xg  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 ZOrTbik  
)lDIzLp  
L^ #<HQ  
Public class QueryTag extends BodyTagSupport  kulQR>u  
Y:"v=EhB  
{ ]D) 'I`  
o&XMgY~  
public int doAfterBody() throws JspTagException 6`4W,  
Y zBA{FE  
{ /@:up+$  
nc\C 4g  
BodyContent bc = getBodyContent(); kF+}.x%  
>xZhK63C/  
//将body的内容以字符串的格式提取出来 VM]GYz|#]  
APtselC  
String query = bc.getString(); 7tfivIj)e  
!,6v=n[Nz  
//清除body _D2bGZN  
n:bB$Ai2  
bc.clearBody(); [6_Du6\h  
3b?OW7H  
try{ 8pq-nuf|K  
lA.;ZD!  
Statement stmt = connection.createStatement(); ^0s\/qyqm  
J%\~<_2ny  
Result result = stmt.executeQuery(query); x'@32gv  
+i`Q 7+d  
}catch(SQLException e){ -#S)}N En  
8G5) o`  
throw new JspTagException(“queryTag: “ + e.getMessage() ); Nr]8P/[~  
yK&* ,J |  
return SKIP_BODY; ANFg]g.Az  
NO+ 55n  
} {n'qKur xY  
GIRSoRVsh  
} /J[H5uA  
=,AC%S_D~  
iO9nvM<  
body-content元素 r{q}f)  
Q9yGQu  
=~\]3g  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: Xb<DpBrk  
1A?\BJ"  
<body-content>JSP|tagdependent</body-content> 5U)ab3 :  
kh<pLI>$h  
yWv<A^C &  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 MS st  
b@2Cl l#  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 &PRx,G5  
F%PwIB~cy  
0HHui7Yy>  
用tags定义脚本变量 .B 85!lCF  
P>{US1t  
42V,PH6o  
tag处理类 X/E7o92\  
&& DD  
3qAwBVWa  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 m1hW<  
u( 1J=h  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 C@y}*XV[b  
N>A{)_k3  
对象的生存周期(scope)如下表: '9*5-iO  
Q5p+W  
对象的生存周期表 3C rQBIj1  
d1~_?V'r]  
名字 "w*+v  
可访问范围 <2)s<S.;  
生存周期 yHWi [7$  
KMK&[E#r  
page I #M%%5e  
当前页面 "K|)<6J  
一直有效,除非页面向客户提交响应或重定向到一个新页面 @,x_i8  
6%gB E  
request }A4nJ>`tq  
当前页面或当前页面重定向到的页面 i\=z'  
一直有效,除非页面向客户提交响应 o~v_PD[S  
JJ/1daj  
session ,&.W6sW  
当前页面或在同一浏览器窗口中的页面 ;dqk@@O"(  
一直有效,除非关闭当前浏览器、超时、网络故障 JQ) 4}t  
JkSdLj  
application yaH Trh%  
整个web应用程序的所有请求 -ajM5S=d*  
一直有效,除非发生网络故障、服务器故障 G3RrjWtO  
dSOlD/c  
提供关于脚本变量的信息 6X@mPj[/  
10C 2=  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: ;YK!EMM4!h  
Aautih@LX  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> gEZwW]r-  
NXzU0  
<font color=”red” size=”+2” > tmO;:n<N  
)Qh>0T+(  
<%= messages.getString(“CartRemoved”) %> cS<TmS!  
Qw24/DJK  
<strong><jsp:getProperty name=”book” property=”title” /></strong> Z69+yOJI  
N#(jK1` y  
</font> 8{R_6BS  
! jbEm8bt  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: _Kc 1  
Dh2:2Rz=#7  
· 脚本变量名称 2.[_t/T  
"| K f'/r  
· 脚本变量所属的类 s1X]RXX&j  
1s#yWQ   
· 此脚本变量是否引用了一个新的或已存在的对象 n,t6v5>88  
9o-!ecx}  
· 此脚本变量的有效性 kWB, ;7  
Ya}T2VX  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 3g4e' ]t  
`1nRcY  
Variable元素 9<xTu>7J  
BG'6;64kx6  
Variable元素有如下子元素: 8AT;8I<K  
2HcsQ*H] G  
· name-given ?D?D 给出的名字,是一个常量 cyW;,uT)D  
'oleB_B  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 B|cA[  
^9&b+u=X  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: Da"yZ\4  
nIfN"  
· variable-class?D?D变量的类型,缺省为java.lang.String。 'UY[ap  
]EB6+x!G  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 12idM*  
'@'B>7C#  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: 7t'(`A 6t/  
|q3f]T&+>{  
脚本变量的有效范围 mO#I nTO  
]#F q>E  
Mv|vRx^b  
有效性 p1+7 <Y:  
方法 |y.zo cBj  
r=h8oUNEJ*  
NESTED  cp$.,V  
在tag标签的开始和结束之间 :@.C4oq  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 :~yzDk\I"-  
,{?wKXJ}L!  
AT_BEGIN H{ZLk,  
从tag标签的开始一直到页面结束 L >SZgmV+  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 5v"Y\k+1  
_-n Y2)  
AT_END Z;hyi'rPJ  
从tag标签的结束一直到页面结束 d-~vR(tU  
在doEndTag中调用 F&xv z2G  
;t}'X[U  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: z1F9$ ^  
&]w#z=5SXi  
<tag> DL,[k (  
gWkjUz )  
<variable> l{8CISO*  
Sa Cx)8ul0  
<name-from-attribute>id</name-from-attribute> 'f 3HKn<L  
\I;cZ>{u"}  
<variable-class>database.BookDetails</variable-class> h-7A9:  
't7Z] G  
<declare>true</declare> qk&gA}qF  
sH%&+4!3  
<scope>AT_BEGIN</scope> s}wO7Df=+  
:AZp}  
</variable> rsWQHHkO  
) ]73S@P(=  
</tag> iAK/d)bq  
F#su5<d  
额外tag信息类 ~P/]:=  
R;r|cep  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: >rKhlUD  
zhX;6= X2  
· 变量名 X<Z(]`i  
Vb2\/e:k  
· 变量所属类名 ZW>o5x__b  
4Q;<Q"  
· 此变量是否引用了一个新对象 Lx%:t YZ  
HcA[QBh  
· 此变量的有效范围 [<yz)<<  
PB+\jj  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 5C B%=iL{  
g92dw<$>  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: Hq?&Qo  
*<r%aeG$em  
|CwG3&8  
public class DefineTei extends TagExtraInfo N+NK`  
BhLZ7*  
{ ^#;RLSv   
 //<:k8  
public VariableInfo[] getVariableInfo(TagData data) p5-<P?B  
`gI~|A4  
{ &mcR   
"qS!B.rt:  
String type = data.getAttributeString(“type”); jn^fgH ?  
Oxv+1Ub<Dv  
If( type == null) G,]z (%  
bE d?^h  
type = “java.lang.Object”; zks#EzQ  
J?IC~5*2  
return new VariableInfo[] { N!L'W\H,  
Pu..NPl+  
new VariableInfo(data.getAttributeString(“id”), !R74J=#(  
?I[h~vr6.  
type, ^!}F%  
 i S  
true, Ihg~Q4t  
ra]:$XJ5=a  
VariableInfo.AT_BEGIN) %K?iNe  
.fEw k  
}; Ukc'?p,*  
<(YF5Xm6$h  
} FZp<|t  
n' ?4.tb  
} "U{,U`@?  
r1G8]agO  
4 \ F P  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: |'<vrn  
<tei-class> xl8#=qmCD  
org.apache.struts.taglib.bean.DefineTagTei 5mavcle{4r  
</tei-class> sL i*SR  
3u_oRs  
b@ 6:1x  
具有协作关系的tag Fc'[+L--Q  
\5hw9T&[B  
.E$q&7@/j  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 2h )8Fq_"  
BSKEh"f  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 skR,-:"8  
RM,'o[%  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 >rw"Rd'  
nLJBq)i  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 ~C| ,b"  
p+[} Hxx=  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。  eu9w|g  
@6b[GekZ<  
Q>=-ext}q  
public class QueryTag extends BodyTagSupport *H" aOT^{  
y9!:^kDI  
{ M"(6&M=?  
K_#UZA< Y  
private String connectionId; uN bIX:L,  
{y6C0A*  
public int doStartTag() throws JspException 5 `=KyHi:b  
D0ruTS  
{ TsD;Kl1  
v459},!P  
String cid = getConnection(); Q]#Z9H  
76u{!\Jo/{  
if(cid != null) X$V|+lTk  
-~O/NX  
{ V#J"c8n  
J`<f  
//存在一个connection id,使用它。 +"uwV1)b"  
<d"Gg/@a  
connection = (Connection) pageContext.getAttribute(cid); f`|G]da-3o  
8=F%+  
} jDTUXwx7V  
hnzNP\$U]  
else c~+l-GIWm  
{eR9 ;2!  
{ {|6z+vR  
jNc<~{/  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, o&$hYy"<.L  
fHfY}BQS  
ConnectionTag.class); y5u\j{?Te  
)gXTRkmw  
if(ancestorTag == null) _~A~+S}  
J8;Okzb!L  
{ 6Z8l8:r-6  
_z8;lt   
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); 0 d4cE10  
z+/LS5$  
} }OrYpZob  
1[DS'S  
connection = ancestorTag.getConnection(); 0S.?E.-&0  
"={L+di:M  
} v!trsjb  
`?uPn~,e8  
} +< KNY  
"}zda*z8  
} ]XUSqai  
l1<?ONB.#  
GwQn;gkF  
$]*d#`Sy{%  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: ~/|zlu*jpc  
|C D}<r(N  
_M5Xk?e=  
<tt:connection id=”con01” ...> ... </tt:connection> ;|TT(P:d  
K@r*;T  
<tt:query id=”balances” connection=”con01” >  O<GF>  
ce'TYkPM  
SELECT account, balance FROM acct_table 0JXqhc9'  
TpP8=8_Lh  
where customer_num = <%= request.getCustno() %> <AUWby,"  
/s[DI;M$o  
</tt:query> 'ere!:GJD  
^,V[nfQR  
xvDI 4x&  
uvB1VV4  
Y=Hz;Ni  
<tt:connection ...> xR908+>5  
uRQ_'l  
<x:query id=”balances”> o:UXPAj  
`^##b6jH  
SELECT account, balance FROM acct_table >}SRSqJu  
JD~aUB%  
where customer_num = <%= request.getCustno() %> &71e5<(dG  
(F8AL6  
</x:query> {oWsh)[x2  
c_1/W{  
</tt:connection> mP-2s;q  
Y {c5  
<xn;bp[  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: A1A3~9HuK  
5f{|"LG&  
<tag> 8R xc&`_X  
#J$qa Ul  
... M!{'ED  
>5Lexj  
<attribute> n )K6i7]xk  
\!H{Ks{#R.  
<name>connection</name> )i!^]|$   
PayV,8   
<required>false</required> Fe$/t(  
@ls.&BHUP  
</attribute> jO)&KEh  
daX*}Ix  
</tag>
描述
快速回复

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