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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! K|=va>   
+3Z+#nGtk  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 IUz`\BO4  
S2>$S^[U  
在这篇文章中,我们主要讨论: HQMug  
/z:1nq  
· 什么是自定义tag标签? o $'K}U  
0S$TLbx  
· 怎么使用tag标签? ?RS4oJz,5g  
_}.WRFIJ@L  
o 声明要使用的tag库 p5l|qs  
C$4{'J-ZH  
o 找到与之对应的tag处理类 H'Jz:6   
3Pvz57z{  
o tag标签的类型 4K*st8+bl-  
~RV"_8`V9  
· 自定义tag标签 &a)d,4e<M  
+'_ peT.8  
o tag处理类 ,\N4tG1\  
MHJRBn{}  
o tag库描述 O+]'*~a  
1C0' Gf)3  
o tag标签示例 XW~a4If  
LMuDda  
o 带属性的tag ]~ !CJ8d  
5F#FC89Kk  
o 带body的tag h.kjJF  
)&l5I4CIf  
o 定义了脚本变量的tag ^fmuBe}d{  
$i1:--~2\  
o 具有协作关系的tag G!o6Y:1!  
I@TH^8(  
· 自定义tag标签 N1"p ;czK  
Wl }J=  
o 一个迭代tag的例子 4'Y a-x x  
0[ (kFe  
o 一个模板tag库 D[)_ f  
N:~4>p44[  
o tag处理类到底是怎样被调用的? a'r1or4  
}KT$J G?  
UhJ!7Ws$  
什么是自定义的tag? 5 9i2*<k  
E6M*o+Y  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 f,ZJFb98  
4*HBCzr7[  
自定义tag标签有很多特色,诸如: + WT?p]  
VCwC$ts  
· 可以在JSP页面中自定义tag标签的属性 Yv0y8Vz@  
BCtKxtbS  
· 访问JSP页面中的所有对象 f?> ?jf  
&.qLE  
· 可以动态地修改页面输出 6C/Pu!Sx?  
oTrit_@3  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 mP's4  
&h_Y?5kK  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 t+\<i8  
}pGjc_:']  
>pe!T aBN  
使用tag标签 n)\(\V7  
EAy@kzY?  
;#mm_*L%@  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 t<`d*M2w  
F{c8{?:  
要使用tag标签,JSP程序员必须做2件事: p,!IPWo  
q_98=fyE6  
· 声明此tag标签的tag库 R<ORw]  
lCTXl5J5  
· 实现此tag标签 Zr=B8wuT  
?FwHqyFVlQ  
声明tag标签所在的tag库 fzOh3FO+  
mA"[x_  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) piqh7u3~  
Y#6LNI   
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> {?"X\5n0  
H)CoByaj  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 '-cayG   
hT`&Xb  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 BzV97'  
?@kz`BY  
以下taglib指示符直接引用一个TLD: I!SIy&=W  
xM@s`s|n  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> y]+[o1]-c  
{fjBa,o #  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: | g1Cs  
#lMC#Ld  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> ,_s.amL3O{  
fjY:u,5V_  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: %LD(S*>7  
[j0jAl  
<taglib> J8ScKMUN2  
%oquHkX%OJ  
<taglib-uri>/tutorial-template</taglib-uri> %UhLCyC/  
sx]{N  
<taglib-location> ;=k{[g 'gv  
-yb7s2o  
/WEB-INF/tutorial-template.tld kD7'BP/#  
<0? r# }  
</taglib-location> *'tGi_2?(  
S9ic4rcd  
</taglib> rBi6AM/  
K\zb+  
2##mVEo.(  
实现此tag标签 'Yh`B8  
yu&muCA  
LC$M_Cpw  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 $!TMS&Wk  
n_k`L(8*  
{47Uu%XT  
tag标签类型 :$gs7<z{rm  
atw*t1)g  
jeJspch+#  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): c;!| =  
h9!4\{V;h  
<tt:tag> qnnRS  
[_(uz,'  
body :UAcS^n7h"  
/>pAZa  
</tt:tag> k\9kOZW  
.o,-a>jL  
2v;&`04V<  
一个不带body的tag标签如下: Bj9FSKiH  
aQf2}kD  
<tt:tag /> lQ4^I^?m  
_MuzD&^qE  
BwGOn)KL  
简单的tag标签 k sOc,4A  
;b. m X  
一个没有body和属性的tag标签如下: `T{CB) ?9  
m1X*I  
<tt:simple /> >[wB|V5  
lj:.}+]r  
w=: c7Y+  
带属性的tag标签 cIC/3g}]  
{'B(S/Z 7  
qh&q <M  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 Z;BEUtR c  
r dtzz#7  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: ~66v.`K!  
g1_z=(i`Z  
<loglic:present parameter = “Clear”> ?^MH:o  
.Cs'@[Ciy  
而另一个标签logic:iterate是用表达式来给属性赋值: .IVKgQ B  
J><hrZ  
<logci:iterate collection=”<%= bookDB.getBooks() %>” x]?V*Jz  
<eP,/H  
id=”book” type=”database.BookDetails”> !0UfX{.  
1zw,;m n  
tFX<"cAvK  
带body的tag标签 =<)/lz] H  
/~7M @`1  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 mG@[~w+  
RlU?F  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: -*hPEgcV9  
|9Yx`_DF  
<logic:present parameter=”Clear”> l-!"   
K K]R@{ r  
<% cart.clear(); %> -nX{&Z3-s  
Pth4_]US  
<font color=”#ff0000” size=”+2”><strong> x1STjI>i  
$}5M`p\&C  
你选择了清除购物车! Z=;=9<vA  
e%4vvPp  
</strong></font> {f*{dSm9b  
|2 =w":2#  
</logic:present> (~! @Uz5  
7;C~>WlU  
_3O*"S=1  
到底是用属性还是用body来传递信息? nD>X?yz2  
:_2:Fh.}3~  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 Dq9f Fe  
HU|qeSyel  
ZtP/|P5@  
定义脚本变量的tag标签 o8IqO'  
H!,V7R  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: RdL5VAD  
!vc 5NKv#n  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> ~k?t  
;05lwP* r]  
<% tx.begin(); %> g2*}XS 3  
$P#+Y,r~\  
... s|Vs#o.P)  
.i*ja*   
NS+uiy  
具有协作关系的tag标签 '%:E4oI  
1rU\ !GfR  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 f,LeJTX=  
AXi4{Q,  
<tt:tag1 attr1=”obj1” value1=”value” /> i.[k"(  
m7XN6zX  
<tt:tag2 attr1=”obj1” /> %u<r_^w5  
jGJf[:M&Pm  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 'd;aAG  
)cZ KB0*+  
<tt:outerTag> W?.xtQEv  
jv1p'qs4  
<tt:innerTag /> K@!hrye  
Z/v )^VR  
</tt:outerTag> B>z^W+Unyn  
5H 1x-b  
@y0kX<M  
Tag处理类 RC8-6s& ln  
*tkf)[(  
XuZgyt"=r  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 >s,*=a  
Pl#u ,Y  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 L=s8em]7l  
Bxj4rC[  
下表说明不同类型的tag所需要不同的处理过程: ?V_v=X%w  
F^TOLwix  
Tag处理类的方法 5"q{b1  
4K4u]"1  
Tag标签类型 "/UPq6  
所调用的方法 M$f_I +  
C)9-{Yp  
基本标签 gq~`!tW'  
doStartTag, doEndTag, release @:!%Z`  
mt e3k=17  
带属性的标签 ,c;#~y  
doStartTag, doEndTag, set/getAttribute1...N, release o(t`XE['<  
&qa16bz  
带内容的标签 ZC^?ng  
doStartTag, doEndTag, release pH@yE Vf  
_nw\ac#*  
带内容的标签,且内容重复循环 +l7Bu}_?  
doStartTag, doAfterBody, doEndTag, release (.{."  
m5KLi &R  
带内容的标签,且内容与JSP交互 Vt9o8naz  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release mcQ\"9;pY  
6jl{^dI  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 (ueH@A"9;  
}JT&lyO< b  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 pBQ[lPCY/  
*1>Tc,mb  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 _F8-4  
:b#5 cMUe  
$.B}zY{  
Tag库描述(简称TLD) ~ r$I&8  
Ox'K C  
% %2~%FVb  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 u/\Ipk/  
15DlD`QV  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 {>brue*)  
dQ<e}wtg  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: x}reeqn  
' 94HVag  
<?xml version="1.0" encoding="ISO-8859-1" ?> T16B2|C"Y  
H@k$sZ.  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> ^1--7#H  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: 2Paw*"U  
#KtV4)(  
lw4#C`bx  
<taglib>的子元素 6b!1j,\Vx  
|txzIc.#  
Element '_g*I  
Description Yt4v}{+  
,l\D@<F  
tlib-version M49Hm[0(  
Tag库的版本 VC!g,LU|-  
z]O>`50Q  
jsp-version 2Ju,P_<dt  
Tag库所需要的jsp的版本 2TaHWw<A  
hrOp9|!m  
short-name 2L1Azx  
助记符,tag的一个别名(可选) %';DBozZ   
hDEZq>&  
uri ]08~bL1Q  
用于确定一个唯一的tag库 e9B$"_ &2  
!|Y&h0e  
display-name ? 5hwz  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) bHHR^*B  
x1:1Jj:  
small-icon +OUM 4y  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) b55G1w  
q?&JS  
large-icon [3W+h1  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) uRw%`J4H  
j7HOh|q  
description "QY~V{u5  
对tag库的描述(可选) jH4Wu`r;m  
,k/<Nv;  
listener K%vGfQ8Er-  
参见下面listener元素 wtGb 3D"am  
lHPhZ(Z  
tag *P[N.5{  
参见下面tag 元素 i"hn%u$V  
P`M1sON~  
Listener元素 /p@0Q [E  
'}NH$ KA  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 #Cz:l|\ i  
2{#=Ygb0  
Tag元素 7jF2m'(  
2?owXcbx  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 oga0h'  
]^l-k@  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: Xc]Q_70O  
 Qp>Q-+e0  
Tag元素的子元素 PFeK;`[  
O,KlZf_B  
元素名称 =TXc - J  
描述 yAVt[+0  
v y F(k3W  
name UIw6~a3E  
独一无二的元素名 cGjkx3l*  
eD 7Rv<  
tag-class Z?'){\$*  
Tag标签对应的tag处理类 rYr.mX  
cNqw(\rr  
tei-class {eo?vA8SE  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) /?QBMI  
oI%.oP}G  
body-content :~9F/Jx  
Tag标签body的类型 w9a6F  
cV)~%e/  
display-name GD .>u  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) 93#wU})  
iD9hqiX&  
small-icon MMUw+jM4  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) #Y<b'7yJ  
JTB5#S4W  
large-icon }L*cP;m#  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) KHXnB  
:J+GodW  
description K3t^y`z  
此tag标签的描述 r7p>`>_Q\  
.](s\6'  
variable D$c4's `5  
提供脚本变量的信息(同tei-class)(可选) LHP?!rO0  
$rE_rZ+]="  
attribute l,3[hx  
Tag标签的属性名 5bKn6O)K  
Ss7XjWP.}  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 :dzam HbX9  
-n~VMLd?@  
_&m   
简单的tag -vC?bumR%  
}' t*BaU  
Zx]"2U#  
tag处理类 OC[(Eq  
v4Q8RE?  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 {z}OZHJN  
) 4'@=q  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: /1lUFL2D  
g@lAk%V4  
=>6'{32W_  
public SimpleTag extends TagSupport FeFH_  
#VEHyz6P  
{ I2'UC) 0  
[(N<E/m%B  
public int doStartTag() throws JspException %fz!'C_4  
SSF4P&  
{  `#lNur\x  
"L" 6jT  
try{ W7"ks(  
_\LAWQ|M4[  
pageContext.getOut().print(“Hello.”); vH#^|u  
r 6STc,%5  
}catch(Exception e){ +d736lLe%  
Sc*O_c3D  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); Rj=xn(@d  
pJ5Sxgv{;  
} DFt1{qS8@u  
y(8AxsROp  
return SKIP_BODY; mko<J0|4  
qyuU  
} .gWYKZM  
5A6d]  
public int doEndTag() >2~q{e  
K_B-KK(^  
{ y8un&LP  
Y75,{1\l0  
return EVAL_PAGE; RW|3d<Fj  
Y m|zM1qc  
} >%.6n:\rG  
PQ|kE`'  
} }ya9 +?I  
pRj1b^F5y  
D[)g-_3f6<  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 eVDI7W:(Sn  
*eytr#0B-  
<body-content>empty</body-content> $R7n1  
m$:o+IH/  
M O5fu!  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 QBto$!})  
D.Cm&  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, <O$'3 _S"D  
v,>F0ofJ  
<logic:present parameter=”Clear”> aic6,>\!'  
{>FA ~}cX.  
与此相应,此tag处理类应有如下方法和定义: 8zj09T[  
l^`!:BOtR  
k9 *0xukJ  
protected String parameter = null; |r-<t  
=X&h5;x'  
public String getParameter() kq%`9,XE  
6}NvVolr  
{ GWE`'V  
hQGZrZK#  
return this.parameter; P >N\q  
;JL@V}L,  
} ^ioTd  
c<&+[{|  
public void setParameter(String parameter) >4EcV1y  
YSrFHVq  
{ Y_/Kd7,\~  
q=?"0i&V  
this.parameter = parameter; 6C]!>i}U  
TaolX*$5  
} _ux 6SIyp`  
 j Mp{  
b!.# `.  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 G|O"Kv6  
W>@%d`>o5  
Attribute元素 L0&!Qct  
V$v;lvt^Uq  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 T)C  
Fah}#,  
<attribute> }= <!j5:  
tb=L+WAIw  
<name>attr1</name> coLn};W2  
0>e>G(4(8  
<required>true|false|yes|no</required> P;_dil G  
jB1\L<P  
<rtexprvalue>true|false|yes|no</rtexprvalue> 1~`g fHI4  
] lO$oO  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> A`N;vq,  
;,4J:zvZdQ  
</attribute> |u}sX5/q  
Cn`% *w  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 4x C0Aw  
*E. 2R{  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 b6/:reH{  
fGe{7p6XV*  
<tag> HdnSs0 /  
3p4bOT5  
<name>present</name> >y8Z{ALQ5  
3o^V$N.  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> 57MoO  
\U-5&,fP  
<body-content>JSP</body-content> 7I44BC*R~  
E Fv+[  
… eqf~5/Z  
/gdo~  
<attribute> $OhL 95}7  
<%Rr-,  
<name>parameter</name> uBMNkN8  
cXCczqabv  
<required>false</required> Bpp9I;)c  
QV 'y6m\  
<rtexprvalue>true</rtexprvalue> 2mT+@G  
z`2d(KE?  
</attribute> kt:%]ZZL  
6?iP z?5  
… - 'VT  
:|A db\b  
</tag> e.kt]l  
{r}}X@|5  
v}mmY>M%  
属性元素的校验 K*}j1A  
"nefRz%j+  
ge?ymaU$a  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 R 1b`(  
Z"^@B2v  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 enr mjA&3  
E<4}mSn)  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 .KLuGb 3JJ  
?d0Dfqh_  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: :)yM9^<D  
^KF'/9S  
<attribute> S\rfR N  
{2Ibd i  
<name>attr1</name> ;5l|-&{@*  
[eN{Ft0x  
<required>true</required> ,5?MRqCM  
W!^=)Qs  
<rtexprvalue>true</rtexprvalue> w#$k$T)  
J|q_&MX/  
</attribute> !{XO#e  
iTvCkb48m  
n 3]y$wK  
这个定义说明了attr1能在运行期间被赋值。 Ol@ZH_  
U Oo(7  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 < KA@A}  
Qw-qcG  
Dw[Q,SE   
Public class TwaTEI extends TagExtraInfo  zVa+5\Q  
q<8HG_  
{ Z}C%%2Iz  
aKy|$ {RC  
public boolean isValid(Tagdata data) %G&v@R  
<coCu0  
{ J)-> 7h =  
A~>=l=  
Object o = data.getAttribute(“attr1”); y_&XF>k91  
I$LO0avvH2  
If(o != null && o != TagData.REQUEST_TIME_VALUE) jY.%~Y1y  
e- CW4x  
{ zE/(F;> FV  
J"MJVMo$T  
if( ( (String)o).toLowerCase().equals(“true”) || Uf<vw3  
8(;i~f:bCW  
((String)o).toLowerCase().equals(“false”) ) 9 JtG&^*  
OXB-.<  
return true; A&'%ou  
&O,$l3 P  
else ZB%~>  
T1&H!  
return false; AF}"  
_@;N<$&  
} YLo$n  
M[{:o/]<  
else nSiNSLv  
H%N+V r3O,  
return true; ||HIp9(3  
(I.`bR  
} pAuwSn#i  
5XHkRcESZ  
} (c2\:hvy  
eV0S:mit  
U;@jl?jnG  
带body的tag O2dgdtm  
c,wU?8Nc|$  
/f<(K-o]  
tag处理类 i#=X#_ +El  
&L]*]Xz;  
!y?hn$w0  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 sQs5z~#51*  
zOdKB2_J7  
Tag处理类不与body交互 sD +G+  
|hM)e*"  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 ={ '($t%|T  
u'1=W5$rK  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 a6E"  
qS|VUy4  
Tag处理类与body交互 gj^]}6-P  
NN'<-0~  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 pQ{t< >  
w"iZn  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 uLljM{ I  
5#\p>}[HG  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 u_8 22Z  
NG UGN~p  
doInitBody 方法 AHY)#|/)  
q?4uH;h:^G  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 A5ID I<a  
*XO KH+_u  
doAfterBody方法 MlE~ gCD  
h';v'"DoW`  
此方法在body内容已被计算后进行调用。 e&4u^'+K  
CD[=z)<z{  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 G\ZRNb  
p9WskYpm  
release 方法 vh8Kd' y  
]#.&f]6l  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 &X,)+ b=  
%iC63)(M  
neFno5dj  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 {{%8|+B  
MToQ8qKs  
.G~5F- 8'  
Public class QueryTag extends BodyTagSupport _PXo'*j  
5q`)jd!*)  
{ *+4iBpyiB  
RsfT Ub)<  
public int doAfterBody() throws JspTagException 2{Iz  
z.HNb$;  
{ '|N4fbZd  
IFofF Xv_  
BodyContent bc = getBodyContent(); G3^]Wwu  
rxp9B>~  
//将body的内容以字符串的格式提取出来 &(^u19TKl  
X]"OW  
String query = bc.getString(); 1>x@1Mo+K  
Vzvw/17J  
//清除body g*r;( H>e  
B^~Bv!tHWr  
bc.clearBody(); hg'!  
'OW"*b  
try{ ]u ~Fn2  
 m+{: ^  
Statement stmt = connection.createStatement(); U2lC !j%K  
@M^Qh Hs  
Result result = stmt.executeQuery(query); PVc|y.  
To%*)a  
}catch(SQLException e){ 'N ::MN  
T)tHN#6I  
throw new JspTagException(“queryTag: “ + e.getMessage() ); :gaeb8`t  
s{J!^q  
return SKIP_BODY; qgsE7 ]  
"d>g)rvOc  
} ]m#MwN$  
A""*vqA  
} <L ( =  
y"L`bl A9}  
zRE8299%z  
body-content元素 UA4d|^ev  
4?M3#],'h  
Xb:BIp!e  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: fA0=Y,pzv  
JgKZ;GM:W  
<body-content>JSP|tagdependent</body-content> NV(4wlh)y  
eEGcio}_I9  
T1!Gr!=  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 3=|2Gs?ut  
#33RhJu5,  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 ~'QeN%qadP  
*([)X2A@+  
JP,(4h *  
用tags定义脚本变量 iA{jKk=  
yP9wYF^A\  
}d\Tk(W  
tag处理类 f3>6:(  
v:Z4z6M-  
N?{1'=Om  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 pW--^aHu  
;(0$~O$3u  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 AD%D ,l  
Dzjt|U0ru9  
对象的生存周期(scope)如下表: \j})Kul  
_u|FJTk  
对象的生存周期表 FO>(QLlH  
mS~ ]I$  
名字 UK_aqB  
可访问范围 DcR}pQ(e  
生存周期 5h=TV  
=<zSF\Zr_  
page 3?Eoj95w!  
当前页面 $gl<{{  
一直有效,除非页面向客户提交响应或重定向到一个新页面 $#ju?B~  
SP?U@w%}  
request chMc(.cN0  
当前页面或当前页面重定向到的页面 fDEu%fUYZ  
一直有效,除非页面向客户提交响应 m5em<P!G  
]v\egfW,W  
session j5h 6u,^:  
当前页面或在同一浏览器窗口中的页面 d J%Rk#?;A  
一直有效,除非关闭当前浏览器、超时、网络故障 M$4=q((0  
~z _](HKoS  
application @?7{%j*  
整个web应用程序的所有请求 oSA*~N:  
一直有效,除非发生网络故障、服务器故障 b801O F  
LUDJPIk  
提供关于脚本变量的信息 |~b R.IA  
DMcxa.Sd!  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: [kuVQ$)  
YyJ{  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> 1.95 ^8  
eBC%2TF  
<font color=”red” size=”+2” > ZecvjbnVY  
9+8!xwR:  
<%= messages.getString(“CartRemoved”) %> vuo'"^ =p0  
)x8;.@U  
<strong><jsp:getProperty name=”book” property=”title” /></strong> 7Cd_zZ  
X:``{!~geo  
</font> u|OzW}xb7j  
G>w?9:V}  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: ~'NpM#A  
^2C /!Y<  
· 脚本变量名称 :EmQ_?(^  
KW|\)83$  
· 脚本变量所属的类 2Jo~m_  
G]mWaA  
· 此脚本变量是否引用了一个新的或已存在的对象 >'}=.3\  
ey\m)6A$  
· 此脚本变量的有效性 E R]sDV  
BF@5&>E  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 {s8U7rmML  
V@ _-H gg  
Variable元素 (e8G (  
]Q4PbW  
Variable元素有如下子元素: WfDX"rA  
M,t*nG  
· name-given ?D?D 给出的名字,是一个常量 C3\E.u ?  
"\/^/vn?  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 _))I.c=v  
QOV}5 0  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: '{0[&i*  
 &(1H!  
· variable-class?D?D变量的类型,缺省为java.lang.String。 5K ,#4EOV  
Wyq~:vU.S  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 3xzkZ8]/  
k]Alp;hVd  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: %h"qMs S  
{+"g':><  
脚本变量的有效范围 Jh43)#G-  
zRV!(Y  
值 nJleef9  
有效性 2<'`^AO@  
方法 P1i*u0a  
^}o7*   
NESTED %-# q O  
在tag标签的开始和结束之间 SY'2A)  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 x*h?%egB!p  
[Y$5zeA  
AT_BEGIN -Aa]aDAz68  
从tag标签的开始一直到页面结束 /Fe:h >6  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 e2k4[V  
% Cu.u)/+  
AT_END WGh. ;-  
从tag标签的结束一直到页面结束 wy{\/?~c  
在doEndTag中调用 )d +hZ'  
U!c]_q  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: W}XYmF*_?  
`l>93A  
<tag> -=$% {  
BrJ o!@<  
<variable> 0%s3Mp6H  
L`UG=7r q  
<name-from-attribute>id</name-from-attribute> Q PFeBl  
<t{?7_ 8  
<variable-class>database.BookDetails</variable-class> X"[dQ_o  
k7^R,.c@  
<declare>true</declare> !TP6=ks  
ohrw\<xsu  
<scope>AT_BEGIN</scope> LY-lTr@A^  
}iilzE4oH#  
</variable> "v(G7*2  
a`H\-G  
</tag> FUaI2  
+7Yu^&  
额外tag信息类 hCzjC|EO~  
#(%t*"IY;  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: )n7|?@5U  
|l|_dn  
· 变量名 [J0*+C9P*  
^ <qrM  
· 变量所属类名 CQdBf3q  
tTotPPZf}  
· 此变量是否引用了一个新对象 YP[LQ>  
'nRp}s1^[  
· 此变量的有效范围 J&M1t#UN  
5kcJ  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 iQt!PMF.  
b5A Gk  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: F:%^&%\  
zKLn!b#>  
'#v71,  
public class DefineTei extends TagExtraInfo u]HS(B,ht  
mZwi7s&u  
{ W*k`  
v&xKi>A il  
public VariableInfo[] getVariableInfo(TagData data) U1l0Uke  
fr+@HUOxsl  
{ /b.$jnqL  
Hu[]h]  
String type = data.getAttributeString(“type”); 3bWum  
xE%O:a?S  
If( type == null) OI+E (nA  
I(pb-oY3!I  
type = “java.lang.Object”; jOs H2^  
BBcj=]"_  
return new VariableInfo[] { Bn\l'T  
#wr2imG6  
new VariableInfo(data.getAttributeString(“id”), ,Ij=b  
< CDA"  
type, X E 9)c   
J"-_{)0lD  
true, ``!GI'^  
sTkIR5Z  
VariableInfo.AT_BEGIN) |H 8^  
I~)cYl:|G  
}; &&WDo(r3  
D}w<84qX  
} n12UBvc}%  
a5a1'IVq  
} [B,'=,Hbs  
%swR:Bv  
<s_=-" il  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: 2JVxzj<~`  
<tei-class> :j@8L.<U  
org.apache.struts.taglib.bean.DefineTagTei u, eZ6  
</tei-class> #4><r.v3  
Nsn~@.UuSW  
l4KbTKm7  
具有协作关系的tag H d*}k6  
i}B;+0<drx  
]=x\b^  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 A[`G^ $  
4}i*cB `  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 H-(q#?:  
)Vg2Jix,]  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 gz;&u)  
2U}m RgJu  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 yyP'Z~0  
j$vK<SF  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 zI^Da!r.  
L]I3P|y_  
cD2+hp|9  
public class QueryTag extends BodyTagSupport &Yf",KcL*I  
n_P3\Y|  
{ qaG#;  
'z5h3J  
private String connectionId; \vCGU>UY  
DI,K(_@G  
public int doStartTag() throws JspException XX2h(-  
-f?Ah  
{ ^,TTwLy- t  
XKqK<!F  
String cid = getConnection(); MS*G-C  
Z19m@vMsIP  
if(cid != null) 2+.18"rvi  
"ZT.k5Z  
{ _y vLu j  
OR4!YVVQ  
//存在一个connection id,使用它。 j)by}}  
(#|{%4g@>  
connection = (Connection) pageContext.getAttribute(cid); rk|a5-i  
fxgU~'  
} \G>ZkgU  
iY~rne"l  
else O4L#jBa+  
{U"^UuU]  
{ Qf xH9_  
d"ZU y!a  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this,  )\ZzTS  
7?nJ4x1  
ConnectionTag.class); 3~Qd)j"<  
,O]l~)sr|  
if(ancestorTag == null) 4Po)xo  
 9S1)U$  
{ tHh HrMxO  
c #lPc>0xb  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); -.iNNM&a  
|cDszoT /  
} 0q,pi qjO  
q'G,!];qL  
connection = ancestorTag.getConnection(); \NK-L."[  
}$kQs!#  
} Puh$%;x  
aY)2eY  
} _M t Qi  
g5S?nHS}  
} <G ~>~L.E  
$bsH$N#6T  
{G3i0 r  
E4i0i!<z  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: u6Je@e_!  
--fFpM3EvS  
1J}8sG2`  
<tt:connection id=”con01” ...> ... </tt:connection> y(a!YicA?  
jb[!E^'&>  
<tt:query id=”balances” connection=”con01” > `/nM[  
Y<f_`h^r  
SELECT account, balance FROM acct_table iqwkARG"  
gSt`%  
where customer_num = <%= request.getCustno() %> uD9|.P}  
*7$P]  
</tt:query> 55Gtp\L  
z42F,4Gk  
7&B$HZ  
或 LL*mgTQ  
bAwl:l\`  
<tt:connection ...> q,%:h`t\  
. +  
<x:query id=”balances”> T vtm`Yk\  
{9LWUCpsf  
SELECT account, balance FROM acct_table Bs ;|D  
PdeBDFWD  
where customer_num = <%= request.getCustno() %> Dyg?F )6  
g(ogXA1  
</x:query> v [njdP  
e]Fp=*#  
</tt:connection> Sr_VL:Gg  
 dy>!KO  
bh p5<N  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: ]N{0:Va@D  
Anm=*;*M`  
<tag> %|"g/2sF[G  
k\`S lb1  
... :6{`~=  
)|bC^{kH!l  
<attribute> a W%5~3  
iK()&TNz  
<name>connection</name> >[10H8~bI/  
*|#T8t,}n  
<required>false</required> G?c-79]U  
^W?Z  
</attribute> h 8e757z  
w5=tlb  
</tag>
描述
快速回复

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