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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! CA1Jjm=  
V?Q45t Ae  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 k`o8(zPb  
:_<&LO]Q  
在这篇文章中,我们主要讨论: H | C3{9  
3dz{" hV  
· 什么是自定义tag标签? rb}fP #j  
fWC(L s  
· 怎么使用tag标签? +PnuWK$  
7Vk9{x$z  
o 声明要使用的tag库 UD8e,/  
5t-d+vB  
o 找到与之对应的tag处理类 6ddRFpe  
(-Q~@Q1  
o tag标签的类型 ^I|i9MH  
W[k rq_c-  
· 自定义tag标签 f[vm]1#  
Y}xM&%  
o tag处理类 TQ:h[6v  
0i"2s}^+_  
o tag库描述 {\`y)k 7  
uF|Up]Z G  
o tag标签示例 AFM+`{Cq  
"uP*pR^  
o 带属性的tag -[J4nN&N  
>Tjl?CS  
o 带body的tag :ssj7wl :  
W}N7jPO}  
o 定义了脚本变量的tag #6 ni~d&0  
$IS!GS&:  
o 具有协作关系的tag &^K(9"  
QgKR=GR6  
· 自定义tag标签 (&87 zk  
lxCAZa\  
o 一个迭代tag的例子 FaWDAL=Vhk  
4s~X  
o 一个模板tag库 ; w+  
q6*i/"mN*  
o tag处理类到底是怎样被调用的? $UdBZT-  
Tt9cX}&&  
wd32q7lGo1  
什么是自定义的tag? j^;P=L0=  
GqNOWK2O  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 "+4Jmf9  
00'SceL=`  
自定义tag标签有很多特色,诸如: ~(^pGL3<  
Kxa1F,dZ  
· 可以在JSP页面中自定义tag标签的属性 }Xk_ xQVt{  
Sk"hqF.2  
· 访问JSP页面中的所有对象 tBfmjxv  
"g)bNgGV}  
· 可以动态地修改页面输出 ',!jYh}Uxk  
i-;#FT+ Xc  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 mI{Fs|9h  
M%la@2SK=  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 -9 .lFuI  
5073Q~  
6$:Q]zR#'H  
使用tag标签 h)fsLzn]Tf  
x#&_/oqAk  
jjQDw=6  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 z. X hE \  
M9o/6  
要使用tag标签,JSP程序员必须做2件事: fzw:[z:%  
X`EVjK  
· 声明此tag标签的tag库 bM5V=b_H  
nS h~ mP  
· 实现此tag标签 J_7@d]0R  
[&4+ <Nl'  
声明tag标签所在的tag库 '_V9FWDZ  
lyFlJmi,r  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) ~OsLbz:  
V_ , `?>O  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> iPV-w_HQ  
U^|T{g+O  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 3uxf n=E  
%.u*nM7sos  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 h~]e~u V  
S[q:b .  
以下taglib指示符直接引用一个TLD: @k)J i!7  
z/h]Jos  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> JFO,Q -y\  
j0X^,ot@m  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: !W8=\:D[  
?;htK_E\*  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> -0 <vmU  
l'_]0%o]  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: B|"/bQ  
n"aF#HR?0d  
<taglib> gm,AH85  
ub fh4  
<taglib-uri>/tutorial-template</taglib-uri> ^^7@kh mNl  
mD.6cV  
<taglib-location> 0>BI[x@  
$#+D:W)az  
/WEB-INF/tutorial-template.tld 7g]mrI@  
8x)i{>#i  
</taglib-location> "_LqIW1   
HfhI9f_x  
</taglib> =No#/_  
~GX ]K H  
L~)8Q(f  
实现此tag标签 `Mt|+iT$p  
B+~ /-3  
c1i:m'b_5  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 1$Q[%9  
%i/|}K  
Q:Pp'[ RK  
tag标签类型 *yw!Y{e!9  
-6I*k |%8T  
EV Z1Z  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): "= %"@"<)  
k7rg:P  
<tt:tag> B0gD4MX/  
@iV-pJ-  
body E9I08AODS  
2cQ~$  
</tt:tag> rjWtioZEa  
r,.j^a  
EATVce]T  
一个不带body的tag标签如下: #oa>Z.?_V  
)\:IRr"  
<tt:tag /> r ~UDK]?V  
 )sdHJ  
w.aEc}@(^  
简单的tag标签 DpA)Vdj  
o!~XYEXvUa  
一个没有body和属性的tag标签如下: 4t }wMOR  
t bR  
<tt:simple /> elhP!"G  
aACPyfGQ  
a?nK|Q=e  
带属性的tag标签 YJHb\Cf.  
J;>~PXB  
,D }Ka?  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 k) Lhzr[  
"&f|<g5  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: \xggIW.^0  
|;~2y>E  
<loglic:present parameter = “Clear”> LXxQI(RO  
U`EOun ,  
而另一个标签logic:iterate是用表达式来给属性赋值: dL+yd0 b*  
ZAy/u@qt  
<logci:iterate collection=”<%= bookDB.getBooks() %>” \db=]L=|  
%5zIh[!1$  
id=”book” type=”database.BookDetails”> @w.DN)GPo  
Q <D_QJ  
56c[$ q  
带body的tag标签 5vR])T/S0  
+:ms`Sr>  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 w.J$(o(/  
gy,)% {,G  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: X\H P{$fY_  
Zqe$S +u  
<logic:present parameter=”Clear”> f1'X<VA  
C@:X9NU  
<% cart.clear(); %> FGP^rTP)e  
e4Qjx*[G  
<font color=”#ff0000” size=”+2”><strong> PPySOkmS3  
T6\]*mlr  
你选择了清除购物车! _6c/,a8;*J  
B@ufrQ#Y.  
</strong></font> z a_0-G%C2  
b+ycEs=_  
</logic:present> L"dN $ A  
j} /).O  
CEw%_U@8  
到底是用属性还是用body来传递信息? NrXIaN  
j5:4/vD  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 ~F,Y BX  
D]"W|.6@  
Da8gOZ  
定义脚本变量的tag标签 $G)HU6hF*  
*My9r.F5o  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: d oEuKT  
r_Ou\|jU  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> 4OJD_  
J!~kqNI  
<% tx.begin(); %> 6QT&{|q=  
{Y2 J:x  
... LVdR,'lS  
mejNa(D ^  
~4FzA,,  
具有协作关系的tag标签 wL:7G  
g| 3bM  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 sxRKWM@4  
GJQ>VI2cY  
<tt:tag1 attr1=”obj1” value1=”value” /> fDW:|%{Y,  
]ke9ipj]:  
<tt:tag2 attr1=”obj1” /> /8l@n dZf  
ST[TKL<]  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 S!$S'{f<  
y5aPs z  
<tt:outerTag> pT~3< ,  
&0bq3JGW  
<tt:innerTag /> "HqmS  
P* &0HbJ  
</tt:outerTag> d*6/1vyjT  
uZ3do|um  
z(%tu  
Tag处理类 #7'k'(  
DHeZi3&i  
$n!5JS@40  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 z>,tP  
W(Sni[c{  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 wM7 Iu86  
XMZ$AeF@  
下表说明不同类型的tag所需要不同的处理过程: Vfk"}k/do  
J[Mj8ee#  
Tag处理类的方法 Ev3'EA~`  
C:^ :^y  
Tag标签类型 4t%Lo2v!X%  
所调用的方法 I;wxgWOP  
k}nGgd6XD  
基本标签 x_<#28H!  
doStartTag, doEndTag, release `~VL&o1>  
K$}K2w  
带属性的标签 $?z} yx$  
doStartTag, doEndTag, set/getAttribute1...N, release +'93%/:  
1oiSmW\  
带内容的标签 M,ybj5:6  
doStartTag, doEndTag, release hPG@iX|V  
yN`&oya  
带内容的标签,且内容重复循环 t$VRNZ`dy  
doStartTag, doAfterBody, doEndTag, release "0 %f R"  
8|\ -(:v  
带内容的标签,且内容与JSP交互 VCnf`wZB"  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release Zon7G6s9`  
:a2[d1  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 G~u$BV'  
nr&|  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 wX6-WQR  
~}ifwm'7 a  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 >)*d/^  
^pew'p HQ  
^:ny  
Tag库描述(简称TLD) \/SOpC  
#l-zY}&  
Fz<1xyc(  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 .9z}S=ZK  
1~E4]Ef:W  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 @mg5vt!$`  
Y?K?*`Pkc1  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: .+?]"1>]  
_ Dz*%  
<?xml version="1.0" encoding="ISO-8859-1" ?> Ho(}_Q&  
) Kl@dj  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> .L1[Rv3  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: KI*b We  
seAEv0YWz  
<Pe'&u  
<taglib>的子元素 NW;_4g4qE  
>b0 Bvx-  
Element jjEu  
Description dG~U3\!  
_PC<Td>nm  
tlib-version $}S0LZ_H  
Tag库的版本 $K\e Pfk  
q2`mu4B  
jsp-version Ny`SE\B+/  
Tag库所需要的jsp的版本 3@O/#CP+  
Jc5Y Gj7  
short-name N|@ tP:j  
助记符,tag的一个别名(可选) @sZ' --Y  
}LX!dDuwA  
uri 99'c\[fd'  
用于确定一个唯一的tag库 ~X<$ l+5  
7tJ#0to  
display-name :TKx>~`  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) g%^/^<ei  
NgsEEPu?  
small-icon ,SdxIhL  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) In:V.'D/>t  
E;4dlL`*  
large-icon A4d3hF~l`  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) Wq1OYZ,  
~@<o-|#  
description wpQp1){%Q  
对tag库的描述(可选) 4~oRcO8!Y  
=1!.g"0  
listener wM;=^br  
参见下面listener元素 gwB0/$!4"  
/&@q*L  
tag N(J#<;!yb  
参见下面tag 元素 >OjK0jiPf  
}9z$72;Qdq  
Listener元素 =\i%,YY  
;Tq4!w'rH  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 apM)$  
\7$"i5  
Tag元素 `GY]JVW  
qn{9vr  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 EUgKJ=jw  
Dcs O~mg  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: 4 s9^%K\8{  
Edcv>}PfE  
Tag元素的子元素 |?f~T"|>  
&K=) YpT  
元素名称 ,PKUgL}w  
描述 v-!Spf  
1Zo3K<*J  
name 5OFB[  
独一无二的元素名 D^];6\=.i  
D6yE/QeK4  
tag-class 3a U4Z|f~  
Tag标签对应的tag处理类 !T~uxeZ/;  
md\Vw?PkU  
tei-class D=5%lL  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) c5Kc iTD^  
w'xPKO$bzR  
body-content 1guiuR4  
Tag标签body的类型 ]D2 d=\  
fv* $=m  
display-name HG5E,^1n  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) *|L;&XM&/  
dIQ3snG  
small-icon RR/?"d?&  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) F 6+4Yy+  
l[WX77bp=  
large-icon :8+x&zn  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) A&-2f]L tl  
iM8l,Os]<f  
description }^n"t>Z8  
此tag标签的描述 fP( n3Q  
=gd~rk9  
variable i{HzY[  
提供脚本变量的信息(同tei-class)(可选) *J4 \KU  
Z{F^qwne  
attribute +j8-l-o  
Tag标签的属性名 LiGECqWBa'  
nU2w\(3|  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 ]yFO~4Nu  
] J|#WtS  
!\Xrl) $j{  
简单的tag /kO%aN  
{G|= pM\'  
^O"o-3dte  
tag处理类 { "f} }}l  
mD?={*7%  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 {HVsRpNEf  
|F ~U  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: "p>kiNu  
Te^_gdf  
b'`C<Rk  
public SimpleTag extends TagSupport 4C;"4''L  
rZ RTQ  
{ 7 3ABop  
`w "ooK  
public int doStartTag() throws JspException {~Q}{ha  
bl|)/)6o  
{ PvxU.  
IG:CWPU  
try{ qUQP.4Z95  
'|&?$g(\h  
pageContext.getOut().print(“Hello.”); JY D\VaW  
ZRa~miKyM  
}catch(Exception e){ GgvMd~  
_znn`_N:v  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); i$!K{H1{9  
U[ogtfv`m  
} qvJQbo[.9P  
Y)AHM0;g  
return SKIP_BODY; gm: xtN  
3X`N~_+  
} 2P|j<~JS  
--7@rxv  
public int doEndTag() 'f7s*VKG  
3#`Sk`z<  
{ Te>m9Pav  
sA,2gbW  
return EVAL_PAGE; PiNf;b^9  
_+0c<'  
} `;s#/`c|/  
o4B%TW  
} CL!s #w1I\  
0y;1D k!  
AASS'H@  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 {-)I2GJav  
FJ|JXH*  
<body-content>empty</body-content> CG!9{&F  
@@6c{r^P  
|q\Rvt$d  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 }FkF1?C  
@u-CR8^  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, gt(!I^LHYc  
Gmmh&Uj  
<logic:present parameter=”Clear”> [5MV$)"!j  
[85tZr]  
与此相应,此tag处理类应有如下方法和定义: %?O$xQ.<  
{jEEAH)  
&f/"ir[8i  
protected String parameter = null; U1=\ `)u;  
 |u^~Z-.  
public String getParameter()  :LTjV"f  
#nS crs@  
{ #8B4*gAM  
AaDMX,  
return this.parameter; !<5Wi)*  
4 :M}Vz-  
} TmLfH d  
G;^,T/q47  
public void setParameter(String parameter) N9PEn[t@  
yO J|t#  
{ j =PM]  
6LzN#g  
this.parameter = parameter; g_(O7  
w+{ o^ O  
} C ?aa)H  
"bvob G  
kOv37c'  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 +)*oPSQ5  
o? wEX%  
Attribute元素 7,R ~2ss5z  
na] 9-~4  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 =O~Y6|  
<e$%m(]  
<attribute> S 0mt8/ M  
f/^T:F6  
<name>attr1</name> ,egbU (:l  
~PedR=Y0n  
<required>true|false|yes|no</required> n wO5<b;  
TA!6|)BUW  
<rtexprvalue>true|false|yes|no</rtexprvalue>  e3%dNa  
/wJocx]vQ  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> c/-PEsk_TP  
l\{r-F N  
</attribute> BVxk}#d  
cbv%1DT3  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 }?,Eb~q  
X GDJCN  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 <-=g)3_  
tjcG^m} _  
<tag> {[r}gS%  
,TQ;DxB}=E  
<name>present</name> g"X!&$ &  
O7zj8  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> gq&jNj7V  
}_9yemP  
<body-content>JSP</body-content> vH>s2\V"  
'],G!U(  
;b0;66C8|  
)bK3%>H#  
<attribute> }ykc AK3U  
Y?JB%%WWI  
<name>parameter</name> ST[E$XL6  
p!+bn,?G  
<required>false</required> W$Z8AZ{E  
~.J{yrJ&  
<rtexprvalue>true</rtexprvalue> \&^U9=uq  
Ew&|!d  
</attribute> @eN,m {b  
J?qikE&  
!'kr:r}gg  
kwrM3nq  
</tag> *~8g:;u  
Kd7Lpw1u]  
\!Ap<  
属性元素的校验 *4[P$k$7  
V_jGL<X|  
SnG XEQ  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 <O~ieJim  
saVX2j6Y  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 O\}w&BE:h  
C$`^(?iO/  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 NdM \RD_R  
zl)r3#6hW  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: w,;ox2  
]nm(V  
<attribute> lrK?&a9AB  
7O'u5 N  
<name>attr1</name> 9K=K,6 b  
F[~~fm_  
<required>true</required> k3&/Ei5  
/=:F w}vt  
<rtexprvalue>true</rtexprvalue> Ej$oRo{ IG  
Nq[-.}Z6  
</attribute> \N)!]jq  
]N6UY  
fq !CB]C  
这个定义说明了attr1能在运行期间被赋值。 ]t_ Wl1*|  
` 6pz9j]  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 Ba9"IXKH  
}C5Fvy6uz  
/_tN&[  
Public class TwaTEI extends TagExtraInfo 6Bn}W ?  
Dx.hM[  
{ DN|+d{^lN  
1A N)%  
public boolean isValid(Tagdata data) NX?6 (lO,  
'F7UnkKO|  
{ E{[>j'dwc  
`i6q\-12n  
Object o = data.getAttribute(“attr1”); 7E R!>l+  
j.KV :zJU  
If(o != null && o != TagData.REQUEST_TIME_VALUE) ^[1Xl7)`  
\d QRQL{LL  
{ qmq#(%Z <W  
BXUd i&'O  
if( ( (String)o).toLowerCase().equals(“true”) || ?)e6:T(  
'o1lJ?~kH  
((String)o).toLowerCase().equals(“false”) ) Q,R|VI6Co  
M&0U@ r-  
return true; [m9=e-KS$Q  
4&H&zST//m  
else |i- S}M  
1N+ju"2R  
return false; fP{IW`t}]  
._`?ZJ  
} ]v0=jm5A  
3OJGBiDAr  
else 1b8}TG2  
10m`LG  
return true; &}FWpo!  
dSbz$Fct  
} sUpSXG-W/@  
6x@4gP y[  
} ~oeX0l>F  
jgT *=/GH2  
K#]FUUnj=  
带body的tag Wfh+D[^  
mxTuwx   
6#kK  
tag处理类 D^A#C<Gs  
C40W@*6S2  
T,v5cc:nO  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 G[Jz(/yNH  
TGI`}#  
Tag处理类不与body交互 j15t8du&O  
36yIfC,  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 FK;2u $:  
OdtS5:L  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 HLl"=m1/>  
/(Ryh6M  
Tag处理类与body交互 FyRr/0C>  
]!cLFXa  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 8 %^W<.Y  
r& nE M6  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 Z%7X"w  
-m Sf`1l0  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 [.>g.p,;  
KwhATYWQb  
doInitBody 方法 iLf* m~Q  
1K[y)q  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 -7A2@g  
laaoIL^  
doAfterBody方法 &u~%5;  
-_BjzA|  
此方法在body内容已被计算后进行调用。 XF99h&;9  
UsdUMt!u  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 l"9$lF}  
g715+5z[  
release 方法 49dN~k=  
It5n;,n  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 5} 1qo7;  
5>~q4t)6z}  
>;k~B  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。  q #X[oVq  
N-}|!pqb  
Q=#!wWVP  
Public class QueryTag extends BodyTagSupport jQpG7H  
k]yv#Pa  
{ _sIr'sR~  
Ir3|PehB  
public int doAfterBody() throws JspTagException \,yg@ R  
9a{9|p>L  
{ (h% xqXs  
tMr$N[@r  
BodyContent bc = getBodyContent(); 2G }@s.iE  
?,FL"ye  
//将body的内容以字符串的格式提取出来 }Z% j=c"d  
wW0m}L  
String query = bc.getString(); >TS=tK  
|=EwZ mj-c  
//清除body 1Ewg_/R  
420cbD3a  
bc.clearBody(); 4j~WrdI*  
n2&M?MGX  
try{  A}n7A   
?f=7F %  
Statement stmt = connection.createStatement(); XC\'8hL:  
~JohcU}d  
Result result = stmt.executeQuery(query); LH>h]OTQF  
*|)O  
}catch(SQLException e){ 'd9cCQ}  
d x"9jFn  
throw new JspTagException(“queryTag: “ + e.getMessage() ); !4mAZF b  
|@*   
return SKIP_BODY; GlaZZ,   
#oEq)Vq>g|  
} (eO_]<wmky  
@v n%  
} e[t1V/ah  
EtA,ow  
u|\K kk  
body-content元素 @1)C3(=A  
7kQ,D,c'  
-|_io,eL;  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: Fo&ecWhw  
kud2O>>  
<body-content>JSP|tagdependent</body-content> rvBKJ!b0  
/V!gF+L  
zl["}I(*n  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 ]8EkZC  
6>- Gi  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 +g8uV hC  
8'Q1'yc  
-/J2;AkGH  
用tags定义脚本变量 *uMtl'  
4I3)eS%2  
[300F=R  
tag处理类 vmT6^G  
2Jn?'76`  
f'B#h;`  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 K yp(dp>  
`;#I_R_K  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 kl9<l*  
'pl){aL`@u  
对象的生存周期(scope)如下表: g<N3 L [  
&}vc^io  
对象的生存周期表 B~/ejC!  
&3'zG)  
名字 ?1lx8+  
可访问范围 N;XJMk_ H  
生存周期 |NaEXzo|qY  
+/2:  
page &6@e9ff0  
当前页面 vKNxL^x  
一直有效,除非页面向客户提交响应或重定向到一个新页面 ?iNihE  
Pna2IB+  
request DqlspT  
当前页面或当前页面重定向到的页面 yy$7{9!  
一直有效,除非页面向客户提交响应 ekO*(vQ~  
vA, tW,  
session "AMsBvzgo  
当前页面或在同一浏览器窗口中的页面 bL18G(5  
一直有效,除非关闭当前浏览器、超时、网络故障 &?B\(?*  
)J!=X`b  
application / S)&dN`  
整个web应用程序的所有请求 T|lyjX$Q]9  
一直有效,除非发生网络故障、服务器故障 zd#/zUPI  
h OF>Dj  
提供关于脚本变量的信息 Y%]&h#F  
Cr%6c3aQ  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: Nyo,6 AA  
&1,qC,:!  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> AJ-~F>gn  
<D{_q.`vA  
<font color=”red” size=”+2” > 3 Ho<4_I,  
t!}?nw%$  
<%= messages.getString(“CartRemoved”) %> Y4n; [nHQ(  
ppo\cy;  
<strong><jsp:getProperty name=”book” property=”title” /></strong> B=J/HiwV)  
U2VnACCUZs  
</font> ^LJ?GJ$g  
J0"<}"  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: ?$FvE4!n  
B|n<{g[-cM  
· 脚本变量名称 'Z(4Wuwb  
zhFk84  
· 脚本变量所属的类 BFyVq  
$2\k| @)s  
· 此脚本变量是否引用了一个新的或已存在的对象 YC0FXNV  
*FEY"W+bY  
· 此脚本变量的有效性 9Fm><,0'u  
'HDbU#vD  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 .]W A/}  
Uw5`zl  
Variable元素 _w>9Z>PR  
cYMlc wS  
Variable元素有如下子元素: :N([s(}!$2  
7A[`%.!F6  
· name-given ?D?D 给出的名字,是一个常量 &-1;3+#w  
y1:#0  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 <sq@[\l}a  
7lz"^  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: jNA^ (|:  
d>qxaX;  
· variable-class?D?D变量的类型,缺省为java.lang.String。 |);-{=.OdQ  
<xeo9'k6&  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 y*5bF 0  
y-c2tF@'v  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: sS|N.2*  
\aG:l.IM0  
脚本变量的有效范围 4l*4w x""v  
W8 m*co  
;{Kx$Yt+  
有效性 i%)Nn^a;T  
方法 ?5L.]Isa5  
[1*3 kt*h  
NESTED -dn\*n5  
在tag标签的开始和结束之间 h .Iscr^~  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 =a .avOZ  
^J=l]  l  
AT_BEGIN YSE6PG   
从tag标签的开始一直到页面结束 7!E?(3$#"  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 9}2E+  
Qm X(s  
AT_END =pP0d vn  
从tag标签的结束一直到页面结束 /)` kYD6  
在doEndTag中调用 q0hg0 DC[;  
)} H46  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: c{u~=24;%#  
4F+n`{~  
<tag> DEw_dOJ(  
kt;| $  
<variable> R)w|bpW  
OxraaN`  
<name-from-attribute>id</name-from-attribute> Bld$<uU  
*X K9-%3  
<variable-class>database.BookDetails</variable-class> MMfcY 3#%  
bNG;`VZ%  
<declare>true</declare> -B-nTS`  
cR1dGNcp/@  
<scope>AT_BEGIN</scope> yw%5W=<  
JL4\%  
</variable> lll]FJ1  
H0 YxPk)  
</tag> kgvB80$4  
N'nqVYTU  
额外tag信息类 -/.Xf<y58  
ji[O?  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: {<HL}m@kQ  
6"Km E}  
· 变量名 _ s]=g  
0NB6S&lI^k  
· 变量所属类名 <z*SO a  
DVNGV   
· 此变量是否引用了一个新对象 # Pulbk8  
@]#0jiS  
· 此变量的有效范围 PL#8~e;'  
\1[I(u  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 Xp=Y<`dX  
:A,V<Es}I"  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: ? 5qo>W<7  
-k p~p e*T  
e4V4%Qw  
public class DefineTei extends TagExtraInfo AT:T%a:G?  
d))(hk:  
{ $SQ8,Y,  
6s833Tmb&r  
public VariableInfo[] getVariableInfo(TagData data) 6ZBg/_m  
,R1`/aRy  
{ fa#]G^f  
Vs~^r>  
String type = data.getAttributeString(“type”); x7X"'1U  
0(|BQ'4~H  
If( type == null) .(,4a<I?%N  
R<gC,eV<=  
type = “java.lang.Object”; iAX\F`  
j w)Lofn  
return new VariableInfo[] { ~a[]4\ m;  
oQC*d}_E}  
new VariableInfo(data.getAttributeString(“id”), l[O!_bH  
2roPZj  
type, x+vNA J  
~ySmN}3~'  
true, r3l}I 6  
_dj< xPO  
VariableInfo.AT_BEGIN) jGzs; bE  
*J!oV0#1  
}; \`#;J?Y|`F  
,epKt(vl  
} {}?s0U$5  
Q/6T?{\U7  
} FDaHsiI:  
C+Wb_  
"aN<3b  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: GdavCwJ  
<tei-class> jK#y7E  
org.apache.struts.taglib.bean.DefineTagTei . *>LD  
</tei-class> $jb0/  
N:!XtYA<  
BJk:h-m [  
具有协作关系的tag J p.Sow  
jMUE&/k  
Z&=K+P  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 BBw`8!  
L`YnrDZK  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 =iRi 9r'l  
^Ois]#py  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 4@|K^nT`  
(| Am  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 Z9ciS";L  
v@;:aN  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 FyYQ4ov0&o  
[kzcsJ'/e  
$nQ; ++  
public class QueryTag extends BodyTagSupport StWDNAf)  
%4cUa| =?  
{ )$yqJ6y5  
qFW- ~T  
private String connectionId; ^aDos9SyV  
c6s*u%+},  
public int doStartTag() throws JspException "uCx.Q9 ef  
T1;yw1/m5\  
{ ]y$D@/L@  
.G1NY1\  
String cid = getConnection(); $Vbgfp~U-  
673v  
if(cid != null) _%!C;`3Y  
F8Y D:   
{ q|om^:n.  
~R/7J{Sg  
//存在一个connection id,使用它。 gE JmMh  
m:/@DZ  
connection = (Connection) pageContext.getAttribute(cid); "j3Yu4_ks  
|Wj)kr !|  
} SxC$EQ gL  
$I-$X?  
else ExI?UGT  
3j0/&ON  
{ @g[p>t> *  
&529.>  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, VZF/2d84&w  
*D F5sY  
ConnectionTag.class); ('W#r"  
KU3lAjzN  
if(ancestorTag == null) RX>kOp29  
M{zzXE[@  
{ A) p}AEBc  
\,[Qg#W$u  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); ~.AUy%$_g+  
1[J&^@t[h6  
} -hL8z$}  
TxwZA  
connection = ancestorTag.getConnection(); 6<NaME  
'/b,3:  
} dnNC = siY  
ag14omM-  
} G?e,Q$  
q+dY&4&u  
} 6,uW{l8L  
s[h'W~  
-n!.PsGO>  
I o7pp(  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: 9fvy)kX;s  
;38DBo  
h(]O;a-  
<tt:connection id=”con01” ...> ... </tt:connection> nWbe=z&y8[  
~m[^|w  
<tt:query id=”balances” connection=”con01” > W$B>O  
VGM8&J{o'  
SELECT account, balance FROM acct_table KI-E=<zt  
z >vzXM  
where customer_num = <%= request.getCustno() %> Ws4aCH1  
r3hj GcpaX  
</tt:query> c _O| ?1  
QgEG%YqB  
bL!NT}y`  
f'aUo|^?  
"2 ma]Ps  
<tt:connection ...> R"!.|fH6  
:Py/d6KK  
<x:query id=”balances”> L/<^uO1  
{08UBnR  
SELECT account, balance FROM acct_table iF{eGi  
)1lR;fD  
where customer_num = <%= request.getCustno() %> c3P  
-#Yg B5  
</x:query> 9O?.0L  
8Y sn8  
</tt:connection> Vg\EAs>f  
M=x/PrY"R  
pJVzT,poh  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: :"3WCB  
Bg"b,&/^u  
<tag> @YU}0&  
4kT|/ bp  
... 2hw3+ o6  
%$Wt"~WE"O  
<attribute> Y@TZReb  
,78 QLh9:  
<name>connection</name> _V1O =iu-  
m!|u{<,R  
<required>false</required> 6t *pV [  
-/B}XN W  
</attribute> CP|N2rb  
Z%N{Y x(  
</tag>
描述
快速回复

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