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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! 7t/Y5Qf  
Yaz/L)Y;R  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 `$vf9'\+  
#L&/o9|  
在这篇文章中,我们主要讨论: ~6+>2|wIS  
e2L>"/  
· 什么是自定义tag标签? $"?$r  
(U\D7ItMG  
· 怎么使用tag标签? .0MY$0s  
4E+8kz'  
o 声明要使用的tag库 o[q|dhrANh  
8fK/0u^`d  
o 找到与之对应的tag处理类 Qkc 9X0J!  
Q /t_% vb  
o tag标签的类型 }]^/`n  
;jBS:k?  
· 自定义tag标签 -vc ,O77z"  
t[MM=6|Wb  
o tag处理类 imB/P M  
alBnN<UM  
o tag库描述 3Zwhv+CP[  
Q% ^_<u  
o tag标签示例 Hoi~(Vc.  
}'Ph^ %ox  
o 带属性的tag MeAY\V%G=o  
nQ{~D5y,,  
o 带body的tag t. DnF[  
&>G8DvfJ9  
o 定义了脚本变量的tag J|VDZ# c7  
Y' 5X4Ks|  
o 具有协作关系的tag >~tx8aI{  
n'%cO]nSx  
· 自定义tag标签 9mpQusM  
;]rj Kc=  
o 一个迭代tag的例子 9(bbV5}  
G)""^YB-  
o 一个模板tag库 9AD0|,g  
p%OVl[^jp  
o tag处理类到底是怎样被调用的? E>"SC\#7  
~{6}SXp4U  
h@s i)5"  
什么是自定义的tag? 9,}Z1 f\%  
}E)t,T>  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 za8+=?  
M@0S*[O{"  
自定义tag标签有很多特色,诸如: va.Ve# N  
gX* &RsF  
· 可以在JSP页面中自定义tag标签的属性 sr:hR Q27  
1+tPd7U  
· 访问JSP页面中的所有对象 _G)x\K]N  
J/[PA[Rf  
· 可以动态地修改页面输出 BJsN~` =r  
J!'IkC$>  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 ~\c  j  
zXd#kw;  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。  ww\2  
W7IAW7w8U  
ASNo6dP 7  
使用tag标签 v/`#Gu^P  
[,|4%Y  
< -Ax)zE  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 K%/g!t)  
Fk?KR  
要使用tag标签,JSP程序员必须做2件事: wee5Nirw6  
hllb\Y)XL  
· 声明此tag标签的tag库 h0VeXUM;.  
1rh2!4)7  
· 实现此tag标签 @9MrTP  
1w>G8  
声明tag标签所在的tag库 j!a&l  
8sL+ik"  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明)  V#+J4   
o^BX:\}  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> \(1WLP$2U  
]Vf2Mn=]"  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 ` h1>rP  
(HeIO  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 {.UK{nA?sm  
Km0P)Z  
以下taglib指示符直接引用一个TLD: d,t'e?  
SxM5'KQ  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> kgRgHkAH~  
J5\2`U_FZ  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: 6Kd,(DI  
N3Z6o.k  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> SS-7y:6y>  
rVnolA*%  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: et6@);F  
~G~:R  
<taglib> diF2:80o  
'S; l"  
<taglib-uri>/tutorial-template</taglib-uri> Dn;$4Dak(  
rE.z.r"O  
<taglib-location> U6_GEBz~y  
Pv3 e*I((  
/WEB-INF/tutorial-template.tld RSf*[2  
+RD{<~i  
</taglib-location> g U v`G  
0 oHnam  
</taglib> PvS\  
6X GqZ!2  
IZ+ZIR@}ci  
实现此tag标签 }Ym~[S*x  
p87VJ}  
#^< Rx{  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 %ZZW p%uf  
ZDl(q~4?z  
JA^Y:@<{/  
tag标签类型 v iM6q<Ht  
C)0JcM  
1V2"sE  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): wqf^n-Ze  
e/V8lo  
<tt:tag> /9 soUt  
~,P."  
body `n~bDG>  
z8n]6FDiE  
</tt:tag> O8WLulo  
\BxE0GGky  
Ptv=Bwg  
一个不带body的tag标签如下: ,;-55|o\V  
i^u5j\pfY*  
<tt:tag /> %$I@7Es>  
{afR?3GK  
Qxh 1I?h  
简单的tag标签 =lqGt.x  
j`kw2(  
一个没有body和属性的tag标签如下: X{b qG]j  
uE{nnNZy  
<tt:simple /> N6_<[`  
A!j6JY.w  
I^fKZ^]8P  
带属性的tag标签 QBfsdu<@^  
'Ijjk`d&c  
!&OybjQ  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 Z'L}x6  
~T<o?98  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: O(oGRK<xM  
~Fd<d[b?  
<loglic:present parameter = “Clear”> eZ~ZWb,%  
?Wm.'S'to  
而另一个标签logic:iterate是用表达式来给属性赋值: ?-IjaDC}  
'X(G><R9  
<logci:iterate collection=”<%= bookDB.getBooks() %>” geRD2`3;  
.I&]G  
id=”book” type=”database.BookDetails”> _4jRUsvjY  
@I^LmB9*  
<kr%ylhIu  
带body的tag标签 rwUKg[ 1N  
2,O;<9au<  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 Lg[_9 `\  
h tn?iLq  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: ]OKs 65  
vo_m$/O  
<logic:present parameter=”Clear”> P I0[  
+TnRuehtk  
<% cart.clear(); %> %XieKL  
G&/RJLX|w  
<font color=”#ff0000” size=”+2”><strong> l|P(S(ikh  
vg5 ;F[e  
你选择了清除购物车! P}+-))J  
8}kY^"*&X  
</strong></font> I?mU_^no  
{]w @s7E  
</logic:present> sA u ;i  
Vg)]F+E  
RRGCO+)*  
到底是用属性还是用body来传递信息? `_{^&W WS  
3+/{}rv  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 0oFRcU  
x !o>zT\  
vUXas*s4  
定义脚本变量的tag标签 <e 'S'  
j7|r^  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: ;nbUbRb  
yF}l.>7D  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> hC[MYAaF  
aa1^cw 5}  
<% tx.begin(); %> > ^b6\  
gUoTOA,  
... p Rn vd|  
v]tbs)x;h  
C=6Vd  
具有协作关系的tag标签 lxpi   
'K=n}}&:  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 OJUH".o  
=*aun&  
<tt:tag1 attr1=”obj1” value1=”value” />  m%-  
jMvWS71  
<tt:tag2 attr1=”obj1” /> ~97T0{E3  
lth t'|  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 iv*Ft.1t  
sILkTzs w  
<tt:outerTag> S/? KC^JP  
2V0gj /&  
<tt:innerTag /> 4|*H0}HOm  
MH+t`/E0]  
</tt:outerTag> '{:WxGgi  
, wT$L 3  
4%TY` II  
Tag处理类 fCL5Et  
&xlz80%  
*OT6)]|k  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 YH( 54R  
0^Vc,\P?  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 rkdwGqG  
LO,G2]  
下表说明不同类型的tag所需要不同的处理过程: LB|FVNW/S  
p-H q\DP  
Tag处理类的方法 ).0h4oHSj  
XAV|xlfm  
Tag标签类型 $:R"IqDG  
所调用的方法 \Ze"Hv  
`Tx1?]  
基本标签 :bx q%D%|o  
doStartTag, doEndTag, release OQ>r;)/  
Br2ZloJ@+  
带属性的标签 G!J{$0.  
doStartTag, doEndTag, set/getAttribute1...N, release x;,H>!r"i  
]urrAIK  
带内容的标签 ^d!(8vh  
doStartTag, doEndTag, release YPraf$  
+SGM3tY  
带内容的标签,且内容重复循环 85P7I=`*d  
doStartTag, doAfterBody, doEndTag, release G'/36M@  
!A(*?0`  
带内容的标签,且内容与JSP交互 oe$Y=`  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release IiG~l+V~  
^Tbw#x]2  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 lS.*/u*5  
<!#6c :(Q  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 =IH z@CU  
!xm87I  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 $F!)S  
;Jex#+H(:D  
V&x6ru#  
Tag库描述(简称TLD) 2 w2JFdm  
Dz4fP;n  
~ l~ai>/  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 L3^WI( 8m  
Fh u(u  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 t =ErJ  
LEoL6ga  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: N`7) 88>w  
FpjpsD~ Qu  
<?xml version="1.0" encoding="ISO-8859-1" ?> uUXvBA?l  
6mr5`5~w  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> d^"<Tz!  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: 2<jbNnj  
KXEDpr  
~U+SK4SK:o  
<taglib>的子元素 rmj?jBKQU  
(^-i[aJY  
Element lPL>8.j  
Description FWNO/)~t  
c!Gnd*!?-  
tlib-version c0v;r4Jo#j  
Tag库的版本 Jrp{e("9  
oR'8|~U@B  
jsp-version 2)DrZI  
Tag库所需要的jsp的版本 q| p6UL9  
sM)n-Yy#9  
short-name E 9_aNYD  
助记符,tag的一个别名(可选) 9H~3&-8&  
jX5lwP Q|F  
uri 0?3Ztdlb  
用于确定一个唯一的tag库 xy>~ 15  
Zvd^<SP<?  
display-name }~Z1C0 t  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) PaPQ|Pwz  
Np>[mNmga  
small-icon RkVU^N"  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) 1{B^RR.  
"V!y"yQ  
large-icon H"8fnN=xB  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) qy1$(3t$  
Fw!CssW  
description @}:}7R6  
对tag库的描述(可选) nd(O;XBI  
Ay'2! K,I  
listener -=aI!7*"$  
参见下面listener元素 *k:Sg*neVq  
RX.n7Tb  
tag trL:qD+{(  
参见下面tag 元素 ; ]GSVv:  
SsiKuoxk  
Listener元素 =}txcA+  
"Gx(-NH+  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 5#+G7 'k  
g6:S"Em  
Tag元素 G"3)\FEM  
o*7`r~  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 Z)cGe1?q  
gR)T(%W  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: YNCQPN\v`1  
fMaUIJ:Q9  
Tag元素的子元素 ]YcM45xg  
HE0UcP1U  
元素名称 6]#pPk8[Z  
描述 w8M,35b  
.Ua|KKK C  
name xh[De}@  
独一无二的元素名 5 3=zHYQ  
b]s.h8+v;  
tag-class :4]^PB@dl  
Tag标签对应的tag处理类 8 ;oU{  
zmk#gk2H  
tei-class sFaboI  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) <%fcs"Mb  
4J3cQ;z  
body-content X_Vj&{  
Tag标签body的类型 Op^r}7  
$OK}jSH*v)  
display-name %lsk> V  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) a=3?hVpB  
/*DC`,q  
small-icon J{"<Hgb  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) YK Nz[x$|  
Jwzkd"D  
large-icon z>$AZ>t%J$  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) K@u\^6419  
;E0Xn-o_  
description  S^;D\6(r  
此tag标签的描述 A;E7~qOG  
Y@'ug N|[C  
variable l :\DC  
提供脚本变量的信息(同tei-class)(可选) lI HSy  
R1Jj 3k  
attribute )*_4=-8H  
Tag标签的属性名 4$D:<8B  
m{itMZ@  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 0#f;/ c0i  
D^1H(y2zp  
aKdi  
简单的tag V_*TY6  
.\1{>A  
XKqUbi  
tag处理类 o<T_Pjp  
4O Lq  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 QF 2Eg  
l n}2   
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: /I@nPH<y  
@&!HMl  
,<]X0;~oB  
public SimpleTag extends TagSupport {bB;TO<b`  
lTOO`g  
{ S7SD$+fX  
$agd9z,&m  
public int doStartTag() throws JspException noz&4"S.{  
7U_~_yb  
{ G&FA~c  
"Xq.b"N{*  
try{ z Qtg]@S  
48 DC  
pageContext.getOut().print(“Hello.”); >W%tEc  
#SiOx/  
}catch(Exception e){ B=K& +  
bbevy!m  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); {1 fva^O  
qH(3Z^#.|  
} 871taL=  
J{Fu8  
return SKIP_BODY; r|[uR$|Y  
(xnXM}M&2Y  
} e-vwve  
tjw4.L<r  
public int doEndTag() &_cMbFLBP  
\ UCOe  
{ bL>J0LWQ  
k!Y7 Rc{"  
return EVAL_PAGE; D,Ft*(|T  
5x";}Vp>P  
} 0. _)X  
Z>GqLq\`ed  
} /DPD,bA  
+[$d9  
5e^t;  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 0zR4Kj7EE  
EN^C'n  
<body-content>empty</body-content> A*)G . o:  
A8bDg:G1i  
Vo*38c2  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 ,A`.u\f(:  
gWcl@|I;\  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, yEm[C(gZ  
qi!Nv$e  
<logic:present parameter=”Clear”>  [o]^\a y  
mx`C6G5  
与此相应,此tag处理类应有如下方法和定义: 4c"x&x|  
h`X>b/V  
Z]H`s{3  
protected String parameter = null; rp*f)rJ  
C^sHj5\(  
public String getParameter() $GI2rzh  
NY.Y=CF("  
{ 7aAT  
tBSHMz  
return this.parameter; *uJcB|KX  
k"-2OT  
} V-Ebi^gz5W  
|TCHPKN  
public void setParameter(String parameter) 6|q\ M  
-8;@NAUa  
{ r q2]u  
Rlvb@aXgy  
this.parameter = parameter; g8<Ja(J  
.QRa{l_)  
} &%."$rC/0b  
{%Mt-Gm'd  
gJYB)LjH"  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 ;9w: %c1  
B J,U,!  
Attribute元素 2%0J/]n\A"  
j. 1@{H  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 ` drds  
p$r=jF&  
<attribute> ~";GH20  
m0XdIC]s  
<name>attr1</name> fJ \bm  
$]eU'!2)  
<required>true|false|yes|no</required> ^HpUbZpat)  
[ 0? *J<d  
<rtexprvalue>true|false|yes|no</rtexprvalue> <=m@Sg{o  
Kh{C$b  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> G&P[n8Z$  
W( O)J$j  
</attribute> M<'AM4  
fB~BVYi  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 RzPqtN  
*;(wtMg  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 r`? bYoz  
TFrZ+CcWp2  
<tag> (8bo"{zI  
Tk(ciwB  
<name>present</name> ,{{e'S9cy  
sxac( L  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> GEJEhwO;H  
eBw6k09C+  
<body-content>JSP</body-content> 9 gt$z}oU  
][Ne;F6  
lFHj]%Y  
F(j vdq  
<attribute> .Sz<%d7XIQ  
xiv1y4(%  
<name>parameter</name> # tN#_<W  
Q>`|{m  
<required>false</required> 8t{-  
6pyLb3[e  
<rtexprvalue>true</rtexprvalue> Q};g~b3  
u;{,,ct  
</attribute> .<GU2&;!  
sn.Xvk%75  
mGf@J6wGz  
:nk$?5ib  
</tag> u19 d!#g  
Mp8BilH-T  
lO?dI=}]  
属性元素的校验 rlQ4+~  
^pAgo B  
i+`N0!8lY  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 Knd2s~S  
G5JZpB#o  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 {yPJYF_l  
B2}|b^'I  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 5u(B]_r.  
Ni"M.O);t  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: q|Oz   
X?p.U  
<attribute> FQc8j:'  
u ##.t  
<name>attr1</name> [QC|Kd^#  
%XIPPEHU  
<required>true</required> Wnp\yx`  
V/ a!&_ ""  
<rtexprvalue>true</rtexprvalue> irg% n  
e;Iz K]kP  
</attribute> XMt5o&U1  
 3+[R !  
W<W5ih,#  
这个定义说明了attr1能在运行期间被赋值。 #x) lN  
]{mz %\  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 !F@9xG  
5e> <i  
!G`7T  
Public class TwaTEI extends TagExtraInfo e.8(tEqZ1  
]`p*ZTr)\  
{ ^U[c:Rz  
8OYw72&  
public boolean isValid(Tagdata data) 3B{B6w}t&  
V(-=@UW  
{ Fo$kD(  
O!Rw? Y  
Object o = data.getAttribute(“attr1”); (5-4`:1ux  
5Z2tTw'i  
If(o != null && o != TagData.REQUEST_TIME_VALUE) O@$wU9 D<  
Lm-yTMNPn  
{ 9DAk|K  
5*Wo/%#q  
if( ( (String)o).toLowerCase().equals(“true”) || dnZA+Pa  
y.pwj~s  
((String)o).toLowerCase().equals(“false”) ) U6 4WTS@  
hcQky/c\#b  
return true; ,5tW|=0@  
m^6& !`CD  
else -Fl;;jeX  
y@\R$`0J  
return false; 8&gr}r- 5  
#n9:8BKf  
} .BaU}-5  
W,\LdQ  
else QX1rnVzg0  
dIQxU  
return true; , [V#o-Z  
L?W F[nF R  
} G;^},%<  
{$dq7m(  
} H%}ro.u  
A7|CG[wZ  
@raw8w\Zj+  
带body的tag @W{VT7w  
&}YJ"o[I  
"s:eH"_s  
tag处理类 e@Cv')]B  
o~ v   
Jp'XZ]o\  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 +Wr"c  
I U Mt^z  
Tag处理类不与body交互 'dkKBLsx  
ZSB_OS[N  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 X=sC8Edx  
zc}qAy'<  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 \.@fAgv  
7K*\F}2)q  
Tag处理类与body交互 , W w\C  
N2 vA/  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 FEdWe\E  
m!Iax]D{  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 tA*hh"9  
H(MCY3t  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 GT -(r+u  
F(yx/W>Br_  
doInitBody 方法 BdK2I!mm  
?PMF]ah  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 CY"iP,nHl  
dn"&j1@KY  
doAfterBody方法 pl-2O $  
U c6]]Bbc  
此方法在body内容已被计算后进行调用。 "*ot:;I  
}I1A4=d  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 "0,d)L0,"  
>z(AQ  
release 方法 )yHJc$OlMx  
#/UlW  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 APfDy  
^KKU@ab9  
qtqTLl@u  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 )_MIUQ%  
=LFrV9  
Z#2AK63/T  
Public class QueryTag extends BodyTagSupport W7j-siWJ  
-T s8y  
{ &~%( RO  
n@hf{hA[a  
public int doAfterBody() throws JspTagException Fj0a+r,h!  
`]+-z +  
{ H1FD|Q3  
r35'U#VMk?  
BodyContent bc = getBodyContent(); ~miRnW*x  
o(2tRDT\_b  
//将body的内容以字符串的格式提取出来 FXAP]iqo  
BIFuQ?j3  
String query = bc.getString(); -w0U }Te^  
))pp{X2m  
//清除body mt0ZD}E  
:X?bWxOJ  
bc.clearBody(); s+=JT+g  
P,(Tu.EPk  
try{ l$i^e|*  
Ab"mX0n  
Statement stmt = connection.createStatement(); DgJG: D{  
B\/"$"  
Result result = stmt.executeQuery(query); 4\#!Gv-  
|k # ~  
}catch(SQLException e){ A7/ R5p  
CdTyUl  
throw new JspTagException(“queryTag: “ + e.getMessage() ); v Ft]n  
uSAb  
return SKIP_BODY; z3RlD"F1  
_$W</8 <  
} cH5@Jam  
*jBn ^  
} R^fk :3  
AADvk_R  
:4{;^|RgU  
body-content元素 WWO@ULGY  
!A.Kb74  
]h Dy]  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: b),_rr  
F(-1m A&-  
<body-content>JSP|tagdependent</body-content> ?q68{!{bi  
U?MKZL7  
208dr*6U  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 nvJ2V $  
m4U7{sE  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 G)I lkA@  
,O9rL :?  
X j'7nj  
用tags定义脚本变量 -nC 5  
R*C  
E !a5-SrR  
tag处理类 3$R^tY2UU  
HuX{8nl a  
x8]9Xe:_>O  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 D]I]I!2c  
\2rCT~x  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 7R$]BY=  
'' @upZBJ  
对象的生存周期(scope)如下表: Hkc:B/6  
n ..9F$a  
对象的生存周期表 I+) Acy;  
1I#S?RSb  
名字 kUl:Yj=&  
可访问范围 4_`ss+gk  
生存周期 ([-xM%BI6  
)xJo/{?  
page V9v80e {n4  
当前页面 zUw9  
一直有效,除非页面向客户提交响应或重定向到一个新页面 y.zS?vv2g  
$X.X_  
request !wws9   
当前页面或当前页面重定向到的页面 u 1?1x  
一直有效,除非页面向客户提交响应 [*-DtbEk  
oSb,)k@  
session EZm6WvlxSI  
当前页面或在同一浏览器窗口中的页面 i;1EXM  
一直有效,除非关闭当前浏览器、超时、网络故障 P|"U  
T~nmEap  
application 1 :xN)M,s  
整个web应用程序的所有请求 G<1awi  
一直有效,除非发生网络故障、服务器故障 c3\z  
|eEcEu?/b  
提供关于脚本变量的信息 d83K;Ryd  
zc<C %t[~y  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: xh7#\m_U8  
zSYh\g"  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> ZMSP8(V  
0]dL;~0y.  
<font color=”red” size=”+2” > Kvu0Av-7  
kf3yJP/  
<%= messages.getString(“CartRemoved”) %> oGzZ.K3 A  
y;N[#hY#CD  
<strong><jsp:getProperty name=”book” property=”title” /></strong> 0Ey*ci^ue  
z0;+.E!  
</font> KrQ8//Ih  
Rt$Q *`u   
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: C|kZT<,]  
MIcF "fB![  
· 脚本变量名称 e1e2Wk  
wv 7j ES  
· 脚本变量所属的类 C<!%VHs  
OzFA>FK0f;  
· 此脚本变量是否引用了一个新的或已存在的对象 WJG&`PP  
L< MIl[z7  
· 此脚本变量的有效性 EwSE;R -  
c\.8hd=<  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 mdu5aL  
mVYLI!n}0#  
Variable元素 C0\A  
AiXxn'&i  
Variable元素有如下子元素: P^-tGo!  
SwESDo)  
· name-given ?D?D 给出的名字,是一个常量 0K -jF5i$`  
3P1OyB  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 tHhA _  
,q yp2Y7  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: !]tZE%?  
%N!2 _uk5  
· variable-class?D?D变量的类型,缺省为java.lang.String。 wo;`D  
@u./VK  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 `I.Uw$,P  
pTJJ.#$CEF  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: c`&<"Us  
"M.vu}~>  
脚本变量的有效范围 %<8lLRl  
v5GV"qY  
!7-dqw%l  
有效性 7,2bR  
方法 q~=]_PMP  
hIPU%  
NESTED /K9Tn  
在tag标签的开始和结束之间 bgjo_!J+Pp  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 V4 PD]5ZW  
F\Gi;6a  
AT_BEGIN tPHDnh^n]  
从tag标签的开始一直到页面结束 =5jX#Dc5.+  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 s^b2H !~  
w#5^A(NR  
AT_END S]3t{s#JW7  
从tag标签的结束一直到页面结束 y#Ao6Od6  
在doEndTag中调用 /K"koV;  
d[5?P?h')  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: /JfRy%31  
)FkJ=P0  
<tag> w"O^CR)  
V\"x#uB  
<variable> m]$!wp  
 T^ ^o  
<name-from-attribute>id</name-from-attribute> 54w..8'  
Lh6G"f(n  
<variable-class>database.BookDetails</variable-class> ;_GS<[A3  
^xO CT=V  
<declare>true</declare> @""aNKA^r>  
;k<g# She  
<scope>AT_BEGIN</scope> "3A.x1uQ  
DDT)l+:XP  
</variable> $e7dE$eH  
!52]'yub  
</tag> R;gN^Yjk:  
PG8|w[V1"  
额外tag信息类 I_IDrS)O  
9GuG"^08  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: fYR*B0tu  
lz1l1.f8  
· 变量名 `Li3=!V[  
G-[fz  
· 变量所属类名 Lmx95[#@a  
_ a|zvH  
· 此变量是否引用了一个新对象  h+Dp<b  
(7G5y7wI"  
· 此变量的有效范围 i :wTPR  
NZSP*#!B  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 lz?F ,].  
4 e1=b,  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: ^9 gFW $]  
y-gSal  
z!quA7s<]  
public class DefineTei extends TagExtraInfo :[oFe/1K!4  
s88lN=;  
{ UW*[)yw]  
/ov&h;  
public VariableInfo[] getVariableInfo(TagData data) FV>LD% uu  
)pV5l|`  
{ "If]qX(w  
ixZ w;+h  
String type = data.getAttributeString(“type”); rYbb&z!u  
-(4)lw>U  
If( type == null) 445}Yw5;9  
=#||&1U$  
type = “java.lang.Object”; ,lLkAd?q  
8r7~ >p~  
return new VariableInfo[] { K'EGm #I  
)2KQZMtgm]  
new VariableInfo(data.getAttributeString(“id”), | -l)$i@  
%Ji@\|Zkf  
type, 8|uFW7Q  
/l-lkG5  
true, vq|o}6Et  
T> cvV  
VariableInfo.AT_BEGIN) AOhfQ:E 4  
} ~F~hf>s  
}; @ .gPJMA  
}#6xFTH  
} :m K xa  
#-{N Ws\  
} qBYg[K>  
Jt]&;0zn2  
BxdX WO  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: ?ok)>P  
<tei-class> eLV.qLBUs  
org.apache.struts.taglib.bean.DefineTagTei  <B )   
</tei-class> \lEkfcc  
zb:kanb-  
(rcMA>2=  
具有协作关系的tag 2 z7}+lH  
;1`!wG-DD  
=u=Kw R  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 u]M\3V.  
  WK==j1  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 \GL*0NJ  
,?(ciO)  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 % :/_f  
mj2Pk,,SA  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 Nqc p1J"  
#!})3_Qc(y  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 ^=+e?F`:{  
YJ,*(A18  
(.?ZKL  
public class QueryTag extends BodyTagSupport ^m%52Tm h  
w"8V0z  
{ [b/o$zR  
Yw)Fbt^  
private String connectionId; -bS)=L  
&RO7{,`  
public int doStartTag() throws JspException sbnjy"Z%  
}pawIf4V  
{ ()\jCNLT  
9I .^LZ"  
String cid = getConnection(); yMxTfR  
| -+zofx  
if(cid != null) "IFg RaP=  
/t5p-  
{ W~ruN4q.  
4h8*mMghs  
//存在一个connection id,使用它。 bL`eiol6  
? ?[g}>  
connection = (Connection) pageContext.getAttribute(cid); #jA)>z\Q^  
BzN@gQo  
} IQnIaZ  
,T|x)"uA`  
else U~H?4Izl=  
cWa)#:JOV  
{ ;>>C)c4V"  
9v?l  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, Sh&PNJ-*  
aG{$Ic  
ConnectionTag.class); u9Y3?j,oC  
] fwZAU  
if(ancestorTag == null) {( tHk_q  
Ri)uq\E/#  
{ 9Ah[rK*}  
P@0Y./Ds  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); jfp z`zE  
[4Q"#[V&9  
} O!&,5Dy  
F9flSeN  
connection = ancestorTag.getConnection(); wtH~-xSB|  
uQ/h'v  
} W Zn.;  
t ls60h  
} GF$`BGW  
x#H 3=YD*  
} ;\{`Ci\  
X+82[Y,mB.  
:iUF7P1I  
k'3Wt*i  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: 6.c^u5;  
(gXN%rsY  
Vba.uKNjk  
<tt:connection id=”con01” ...> ... </tt:connection> (zcLx;N  
M(Zc^P}N  
<tt:query id=”balances” connection=”con01” > ,wAz^cK|  
$}o b,i^W  
SELECT account, balance FROM acct_table tTanW2C  
'LSz f/w  
where customer_num = <%= request.getCustno() %> SA"8!soY3  
/)L 0`:I#  
</tt:query> rcN 9.1  
(u1m]WYL  
~nY]o"8D  
}q[Bd  
>BVoHt~;  
<tt:connection ...> e'9r"<>i  
}} ZY  
<x:query id=”balances”> rS8 w\`_  
~O6\6$3b5E  
SELECT account, balance FROM acct_table nH-V{=**  
$XnPwOj  
where customer_num = <%= request.getCustno() %> >3.X?  
tJ0NPI56yP  
</x:query> r 2:2,5_  
/)3Lnn{W  
</tt:connection> [1yq{n=  
0<p{BL 8  
v6=-g$FG  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: R[B?C;+(O  
EnVuD 9  
<tag> pY"O9x  
98XVa\|tl  
... >SbK.Q@ei  
2?q(cpsN  
<attribute> "sUyHt-&  
h*i9m o  
<name>connection</name>  C})'\1O%  
Zyf P; &  
<required>false</required> wq!iV |  
E%N2k|%8d_  
</attribute> o4y']JSN  
\}0-^(9zd  
</tag>
描述
快速回复

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