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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! ~#V1Gunq  
iMXK_O%  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 >W?7a:#,  
9Qhk~^ngg  
在这篇文章中,我们主要讨论: /S\y-M9  
8WRxM%gsH  
· 什么是自定义tag标签? NzuH&o][  
:h)A/k_  
· 怎么使用tag标签? @AAkEWo)_  
1PdxoRa4=  
o 声明要使用的tag库 o;M-M(EZQ6  
f+D a W  
o 找到与之对应的tag处理类 8et.A  
}t9A#GOz  
o tag标签的类型 9G=ZB^  
ky98Bz%  
· 自定义tag标签 {;j@-=pV  
_=68iDXm  
o tag处理类 L}5IX)#gH  
QW1d&Gb.(  
o tag库描述 b=j]tb,  
O.~@V(7ah  
o tag标签示例 d*TpHLm  
SK_i 3?  
o 带属性的tag +i.b&PF'H  
>!|(n @  
o 带body的tag Hxzdxwz%$  
hg=BXe4:  
o 定义了脚本变量的tag a?QDf5C q  
6 w:@i_2^  
o 具有协作关系的tag jt8% L[  
*,=WaODO%  
· 自定义tag标签 MX#MDA-4  
Nd.Tda!Kg  
o 一个迭代tag的例子 1WMwTBHy+  
s(Tgv  
o 一个模板tag库 4yu ^cix(  
Q8 r 7  
o tag处理类到底是怎样被调用的? |xQq+e}l<  
M`kR2NCi  
,"!P{c  
什么是自定义的tag? Q&Ox\*sMK  
*|DIG{  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 :g[G&Ds8  
 zOnQ656  
自定义tag标签有很多特色,诸如: Ug|o ($CY  
C5jR||  
· 可以在JSP页面中自定义tag标签的属性 _Ak?i\  
T c{]w?V  
· 访问JSP页面中的所有对象 =2=n   
MJ:>ZRXC E  
· 可以动态地修改页面输出 :,^pLAt  
q$=EUB"C  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 h.W;Dmf6]  
);.q:"  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 ;qF#!Kb5  
6hs2B5)+  
j!H\hj/]  
使用tag标签 `y!6(xI  
 _,2P4  
Nl^{w'X0h  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。  T8i9  
ZP& "[_  
要使用tag标签,JSP程序员必须做2件事: "wPFQXU  
kFG>Km(y}  
· 声明此tag标签的tag库 hp E?  
vZns,K#4H\  
· 实现此tag标签 uUczD 8y  
Q(2X$7iRq  
声明tag标签所在的tag库 &)p/cOiV  
Y+#e| x  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) 7gV"pa  
`[;b#.  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> 6_wf $(im  
$MmCh&V  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 .qioEqK8!y  
ReCmv/AE  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 d&p]O  
aO]0|<2 j  
以下taglib指示符直接引用一个TLD: kxg]sr"  
'`Smg3T!~S  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> {t$ vsR  
Odr@9MJ  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: Upr:sB  
`1NxS35u  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> :I5]|pt  
 OT9\K_  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: {q1&4U~'>O  
S4]xxc  
<taglib> nr>g0_%m  
]8q5k5~  
<taglib-uri>/tutorial-template</taglib-uri> b-{\manH  
,0#5kc*X  
<taglib-location> 26E"Ui5q  
.d5|Fs~B  
/WEB-INF/tutorial-template.tld FV/X&u8~  
N2VF_[l  
</taglib-location> <)zh2UI  
KZL5>E  
</taglib> @$~ BU;kR  
X?b]5?K;r  
& CiUU  
实现此tag标签 Hm+-gI3*  
'A,&9E{%1  
~$f+]7  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 (9BjZ&ej  
?J+[|*'yK  
~u&3Ki*x  
tag标签类型 Oah}7!a)  
S zOB{  
OxqbHe  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): :YB:)wV,P  
ML0o :8Bd\  
<tt:tag> Etj*3/n|  
A^JeB<, 5a  
body B7TA:K  
2C %{A  
</tt:tag> Y$EqBN  
RC8{QgaI  
*&B*/HAN  
一个不带body的tag标签如下: :x97^.eW~  
,SJB 3if  
<tt:tag /> .bvB8VOrW  
$6:j3ZTXrt  
~fs{Ff'  
简单的tag标签 f3-=?Z  
9c806>]U^  
一个没有body和属性的tag标签如下: '=x   
pCA(>(  
<tt:simple /> V5K!u8T  
A5Yfm.Jy  
2"nd(+ QH  
带属性的tag标签 ]?^m;~MQZ  
(]>c8;o#b  
KS'? DO  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 4D[W;4/p  
Mno4z/4{A  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: xrO:Y!C?  
_U$d.B'*)z  
<loglic:present parameter = “Clear”> pq>"GEN  
anA>'63  
而另一个标签logic:iterate是用表达式来给属性赋值: -zHJ#  
GS~jNZx  
<logci:iterate collection=”<%= bookDB.getBooks() %>” %Md;=,a:6  
Cdiu*#f  
id=”book” type=”database.BookDetails”> m$A|Sx&sG$  
f6^H Q1SSt  
Hw<t>z k  
带body的tag标签 br<,?  
? YX2CJ6N  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 g!D?Yj4  
Bfaj4i ;_  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: zp"sM z]  
"sf8~P9qy  
<logic:present parameter=”Clear”> rO 6oVz#x  
;04doub  
<% cart.clear(); %> sxl29y^*  
`#2}[D   
<font color=”#ff0000” size=”+2”><strong> +|Xx=1_?BK  
%`HAg MgP  
你选择了清除购物车! }9>W41  
9pStArF?F0  
</strong></font> =4/lJm``  
I9ubVcV8  
</logic:present> 2@1A,  
&K)c*' l  
{Rjj  
到底是用属性还是用body来传递信息? s{KwO+UW  
6I72;e ^!  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 4'?kyTO~  
Fc7mAV=  
@xB"9s  
定义脚本变量的tag标签 e!ar:>T  
vz,l{0 v  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: .'p_j(uv  
+l2{EiQw  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> 1>4'YMdZi  
S!2M?}LU  
<% tx.begin(); %> *xM4nUu<~  
yu<sd}@  
... %ztCcgu*  
JpD<2Mz_|V  
lz faW-nu  
具有协作关系的tag标签 zOCru2/  
}X)mZyM[  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 i=.zkIjSh  
Cz+>S3v M  
<tt:tag1 attr1=”obj1” value1=”value” /> 7:R8QS9  
yiSv#wD9  
<tt:tag2 attr1=”obj1” /> :u`  
\$V~kgQ0  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 z(aei(U=  
y0M^oLx  
<tt:outerTag> b(I-0<  
(m\PcF  
<tt:innerTag /> &$qqF&  
QK% {\qu  
</tt:outerTag> OCa74)(  
/^ i7^  
!BP/#  
Tag处理类 :7<spd(%"  
D^]7/w:$-  
{2}O\A  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 7pMrYIP  
V?t^ J7{'  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 YbND2 i  
gb|C592R5C  
下表说明不同类型的tag所需要不同的处理过程: w{UVo1r:  
C!]hu)E  
Tag处理类的方法 \&`S~cV9  
H.hF`n  
Tag标签类型 >>Z.]  
所调用的方法 PR|F-/o  
"b8<C>wY  
基本标签 z^T/kK3I  
doStartTag, doEndTag, release :&HrOdz  
_)yn6M'Dt  
带属性的标签 vXAO#'4tm%  
doStartTag, doEndTag, set/getAttribute1...N, release 6UG7lH!M  
7MZBU~,r  
带内容的标签 [DC8X P5 <  
doStartTag, doEndTag, release ?V4?r2$c  
(q59cAw~X  
带内容的标签,且内容重复循环 f6j;Y<}' g  
doStartTag, doAfterBody, doEndTag, release >_jT.d  
JZNRMxu  
带内容的标签,且内容与JSP交互 7$b!-I+ a2  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release BRPvBs?Q,{  
s% 2w&Us*  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 IKMkpX!]  
R7r` (c!  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 HJo&snT3  
:$~)i?ge<5  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 Jajo!X*Wai  
}KEyJj3"DA  
b lP@Cn2  
Tag库描述(简称TLD) |,c QJ  
X+z!?W*a  
P hs4]!  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 s3>,%8O6  
] +<[D2f  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 R?b3G4~  
1N{}G$'Go  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: 5 >S #ew  
=&;orP  
<?xml version="1.0" encoding="ISO-8859-1" ?> ]B/Gz  
zRd^Uks  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> 0?8O9i  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: <^c?M[ j  
y[:\kI  
:hr% 6K7  
<taglib>的子元素 l=ehoyER  
~[l6;bn  
Element u9ObFm$7  
Description 6c,]N@,Zw  
0+L:+S  
tlib-version D1rXTI$$  
Tag库的版本 ;gLHSHEA  
ecDni>W  
jsp-version IL;JdIa  
Tag库所需要的jsp的版本 kU{+@MA;  
@E;'Ffo  
short-name XP'<\  
助记符,tag的一个别名(可选) gBp,p\ Xc  
D[32 t0  
uri |ZZl3l=]  
用于确定一个唯一的tag库 _&)^a)Nu  
NF8'O  
display-name }'L7<_  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) E}LuWFZ&  
;rXkU9  
small-icon R?MRRq  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) VPW@y  
7DZxr Vw  
large-icon .< 7M4Z  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) @SeInew;`l  
oS6dcJHf  
description B( r~Nvc  
对tag库的描述(可选) go >*n\  
b* k=  
listener _/(DEF+G  
参见下面listener元素 ,' VT75  
1Tl^mS~k  
tag PxfWO1S(  
参见下面tag 元素 VBnD:w"z  
(#I$4Px{  
Listener元素 KmS$CFsGL  
[rk*4b^s  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 011 N  
DQ%bcXs  
Tag元素 [hzw..?g  
`W>cA64 o  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 zntvKOIh  
m}Xb#NAF8  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: Q^13KWvuV  
*Z}^T:3iw}  
Tag元素的子元素 %87D(h!.I4  
RN:VsopL  
元素名称 "/H B#  
描述 )gF>nNE  
h,-2+}  
name 8xf]zM"Q  
独一无二的元素名 YX*NjXL  
2L!s'^m-  
tag-class Ao?y2 [sE  
Tag标签对应的tag处理类 QFekj@  
XBx&&  
tei-class  -c%#Hd  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) ,~8&0p  
03N|@Tu  
body-content C_> WU   
Tag标签body的类型 m q#8 [D  
*<r\:g  
display-name P+ ejyl,  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) hA=.${uIO  
WO;2=[#O;  
small-icon lU?8<X  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) /Ne;Kdp  
$ljzw@k  
large-icon Nm {|  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) [A jY ~  
b'AA*v,b  
description &#/UWv}f 0  
此tag标签的描述 5>r2&72=  
`L~gERW#  
variable lZ,w#sqbY  
提供脚本变量的信息(同tei-class)(可选) 7QSr C/e  
,:[\h\5m  
attribute 0G; b+  
Tag标签的属性名 gvzBV +3'  
B1^9mV'O  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 r4MPs-}oF  
>o/+z18x  
B`<a~V  
简单的tag ]mzghH:E  
Mo'6<"x  
M{GT$Q  
tag处理类 ]g] ]\hS  
}BYs.$7  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 . E8Gj'yO  
DXF>#2E^+  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: My6a.Kl  
.gQYN2#zb  
aU\R!Y$/"  
public SimpleTag extends TagSupport f]sc[_n]  
\wR;N/tg  
{ '@6O3z_{  
S =5br  
public int doStartTag() throws JspException 3g79/ w  
m=[3"X3W1V  
{ "J(T?|t  
hQb3 8W[  
try{ Mq~g+` '  
U{C& R&z  
pageContext.getOut().print(“Hello.”); }Y~<|vZ  
<nvzNXql  
}catch(Exception e){ D4OJin^}  
2 xE+"?0  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); 'Lu d=u{  
f|+aa6hN  
} E !EENg  
1[] 9EJ  
return SKIP_BODY; QnJd}(yN  
#fVk;]u`[3  
} Hb&C;lk  
%\f<N1~*  
public int doEndTag() n@=D,'cn  
XpH d"(*  
{ dBm!`;r4  
vu@@!cT6e  
return EVAL_PAGE; [,yYr  
@1vpkB~ w  
} )+ (GE  
Bo +Yu(|cL  
} Je*hyi7  
}PUY~ u  
a7U`/*  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 bZ SaL^^(  
ugV/#v O  
<body-content>empty</body-content> 1v~1?+a\2  
.Lm0$o*`  
){<qp  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 K''2Jfm  
QB5,Vfoux  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, @bIZ0tr4  
bLSUF`-z  
<logic:present parameter=”Clear”> g[L}puN  
P$v9  
与此相应,此tag处理类应有如下方法和定义: y=&^=Z h[  
ne|N!!Dmk  
\Lg{GN.  
protected String parameter = null; c[+uwO~  
\C kb:  
public String getParameter() M@=VIrX,m  
_/z3QG{Ea^  
{ CHckmCgf4  
AOM@~qyc   
return this.parameter; 3S"kw  
av"dJm  
} |t6:4']  
z7!@^!r  
public void setParameter(String parameter) Gt$PBlq0  
L2IY$+=M  
{ p5Wz.n.<'  
b *Ca*!  
this.parameter = parameter; f {j`d&|  
]D<3y IGS  
} J'C%  
#k t+ )>  
bScW<DZJ-  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 /s Bs eI  
Zvkb=  
Attribute元素 !@T5](zV  
LMaY}m>  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 :Izdj*HL;A  
GhR%fxe  
<attribute> AP9>_0=  
1T 8|>2m 3  
<name>attr1</name> " +A8w  
om{aws;  
<required>true|false|yes|no</required> o&RNpP*  
9'0v]ar  
<rtexprvalue>true|false|yes|no</rtexprvalue> !'(QF9%Q  
-eFq^KP2  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> ebiOR1)sN  
E`#/m@:|-  
</attribute> @n;$Edza/  
yk/BQ|G  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 e=Q{CsP  
~\UAxB=  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 $ S]l%  
B *otqu z  
<tag> _ykT(`.#  
do DpTwvh  
<name>present</name> j>)yV@g/  
r2=4Wx4(  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> JgMYy,q8t  
P;K <P  
<body-content>JSP</body-content> jg3T1ROL  
IzlmcP3  
&+")~2 +  
H'?dsc  
<attribute> !Q=xIS  
^oDSU7j5,  
<name>parameter</name> UF;iw  
zXGi  
<required>false</required> A Eo  
 %Krf,H  
<rtexprvalue>true</rtexprvalue> bG/[mZpRT  
]O0:0Z\  
</attribute> ;oWak`]f  
LfX[(FP  
#T08H,W/  
QBLha']'%  
</tag> c=<5DC&p  
|g!3f  
,IRy. qy  
属性元素的校验 )26_7.|  
kz^?!l)X0  
6XI$ o,{  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 B8NMo5a  
:y^%I xs{1  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 ?dY|,_O  
-GT&46hX  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 sW0<f& 3  
'\R/-.  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: i| CAN,'  
o,_R;'\E[a  
<attribute> f vr|<3ojo  
sJ7ZE-v]h  
<name>attr1</name> CDT3&N1'R  
en-HX3'  
<required>true</required> gJ?Vk<hp  
M"E7= J  
<rtexprvalue>true</rtexprvalue> oNp(GQ@0  
Z?)=4|  
</attribute> CYZ0F5+t  
n0opb [?  
0l2@3}e  
这个定义说明了attr1能在运行期间被赋值。 fu{.Ir  
~c${?uf   
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 {J]x81}*;  
7(B"3qF8|  
N.?)s.D(  
Public class TwaTEI extends TagExtraInfo hi^t zpy  
jn+BH3e  
{ Bb*P);#.K  
-}9>#<v  
public boolean isValid(Tagdata data) ~ }?*v}  
X^)v ZL?  
{ YxWA] yL  
@]@6(To  
Object o = data.getAttribute(“attr1”); A3Oe=rB  
~JG\b?s  
If(o != null && o != TagData.REQUEST_TIME_VALUE) |yVveJ  
?+?`Js o(  
{ TyN]Pa  
R 3@luT]  
if( ( (String)o).toLowerCase().equals(“true”) || VTJxVYE  
Q$8K-5U%  
((String)o).toLowerCase().equals(“false”) ) hv#|dI=kZR  
HB, k}Q  
return true; G$-[(eu -  
;CLOZ{  
else @aUQy;  
E{xcu9  
return false; /eY}0q%  
:bu]gj4e  
} ><H*T{ Pg  
UflS`  
else 1XJLGMW,  
6 B*,Mu4A  
return true; mH /9J  
Z^O_7I<5E  
} wOF";0EN  
rLp (}^  
} F-PQ`@ZNW  
`w EAU7m:  
69$gPY'3  
带body的tag =p>IP"HJ  
9_xJT^10  
h Nx#x  
tag处理类 1s6L]&B  
XxLauJP K  
Y|~+bKa  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 D"8?4+  
.A apO}{  
Tag处理类不与body交互 [(m+Ejzi%  
][1 iKT  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 #b94S?dq  
n 'E:uXv"  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 +MyXIWmD  
ZiaHLpk  
Tag处理类与body交互 0YO/G1O&  
Sd+bnq%  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 ~zhP[qA})  
AI#.G7'O  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 !z2KQ 4C  
~TYpq;rq  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 _m*FHi  
D8f4X w}=  
doInitBody 方法 ,racmxnv  
S,vh  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 bPVQ-  
q#\4/Dt  
doAfterBody方法 .> 5[;  
/Suh&qw>  
此方法在body内容已被计算后进行调用。 GS+Z(,J>=  
85qD~o?O  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 SGP)A(,k9  
Wgb L9'}B  
release 方法 V,&A? Y  
/@Ec[4^=!.  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 .O6(QI*  
1.I58(0~+  
nd~O*-uYg  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 c]68$;Z7  
IsiBn(1Z  
r<5i  
Public class QueryTag extends BodyTagSupport Mb=j'H<N@  
c\OLf_Uf  
{ "Z)zKg  
vP'#x  
public int doAfterBody() throws JspTagException '$5Qdaj  
3|PV.  
{ sFw;P`  
5Kl;(0B9  
BodyContent bc = getBodyContent(); wL[{6wL  
 =@! s[  
//将body的内容以字符串的格式提取出来 T 3 <2ds  
?*&5`Xh  
String query = bc.getString(); `\yQn7 Oq  
I ;F\'P)e  
//清除body uZa)N-=b2  
M\9+?  
bc.clearBody(); ;%Kh~  
upiYo(sN.  
try{ UB w*}p  
ny1Dg$u i2  
Statement stmt = connection.createStatement(); O% 8>siU  
Lum5Va%0  
Result result = stmt.executeQuery(query); ` 5SQ4  
u1`JvfLrL  
}catch(SQLException e){ ]/7#[  
> 1=].  
throw new JspTagException(“queryTag: “ + e.getMessage() ); t'[`"pp=  
=-]NAj\  
return SKIP_BODY; aSIoq}c(  
S|]\q-qA&  
} gP`CQ0t  
d "25e"(~F  
} S5[}kfe  
7A^L$TY  
ZhFlR*EQ  
body-content元素 X'p%K/-m  
NUh+ &M  
^*b11 /7  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: 5=Il2  
7`tJ/xtMy;  
<body-content>JSP|tagdependent</body-content> >cH}sNHy  
7 lu_E.Bv  
4wPP/`  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 fvRqt)Ks  
]v l?J  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 a1z*Z/!5  
hVh,\d&2t  
krRnE7\m  
用tags定义脚本变量 ,8o Y(h  
IU\h,Ug  
wZt2%+$6m  
tag处理类 \hP.Q;"MtO  
2FQTu*p&B  
>aT~ G!y  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 JZ/T:Hsh4  
p21li}Iu  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 ~7:Q+ 0,,  
Qp+M5_  
对象的生存周期(scope)如下表: u<EPK*O*  
x5b .^75p$  
对象的生存周期表 ))I[@D1b  
ak zKX}  
名字 c]NZG n*  
可访问范围 1cD  
生存周期 JtxitF2  
ucFfxar"  
page =lL)g"x X  
当前页面 Tr, zV  
一直有效,除非页面向客户提交响应或重定向到一个新页面 3[<D"0#},  
pzb`M'Z?C  
request aVp-Ps|r  
当前页面或当前页面重定向到的页面 | CPyCM$  
一直有效,除非页面向客户提交响应 :A5h<=[  
.@psW0T%  
session NtkZ\3  
当前页面或在同一浏览器窗口中的页面 S}6xkX  
一直有效,除非关闭当前浏览器、超时、网络故障 T }Wse{  
9JO1O:W  
application TPmb]j  
整个web应用程序的所有请求 3g5D[>J'  
一直有效,除非发生网络故障、服务器故障 >^D5D%"  
FY pspv?4  
提供关于脚本变量的信息 V^_U=Ed@M  
#lF 2q w  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: WTu!/J<\  
0B"_St}3D  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> w!OYH1ds]_  
uCc5)  
<font color=”red” size=”+2” > Dlz1"|SF  
}j{Z &(K  
<%= messages.getString(“CartRemoved”) %> "p[3^<~uQ  
Y)7\h:LIg  
<strong><jsp:getProperty name=”book” property=”title” /></strong> fzUG1|$e  
Nb)Mh  
</font> ( ; _AP.  
ie7P^:T|+  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: fYlqaO4[  
+@~e9ZG%a  
· 脚本变量名称 dw%g9DT  
@#yl_r%  
· 脚本变量所属的类 ;WG%)^e  
2yVQqwQ m  
· 此脚本变量是否引用了一个新的或已存在的对象 (V0KmNCW`  
t:n$9WB)  
· 此脚本变量的有效性 ,fvhP $n  
s1p<F,  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 on 4 $n7  
6E9o*YSk  
Variable元素 a0 's6C  
4)Ew rU  
Variable元素有如下子元素: q oEZ>  
z pg512\y  
· name-given ?D?D 给出的名字,是一个常量 {FR+a**  
9Dd`x7$ a  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 =]o2{d  
~Xc1y!"9*  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: j|@8VxZ  
6O"y  
· variable-class?D?D变量的类型,缺省为java.lang.String。 : :928y  
(&M,rW~Qxs  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 er<_;"`1  
YTg8Zg-Z  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: A-u!{F  
g\H~Y@'{  
脚本变量的有效范围 2Hk21y\  
G`f|#-}  
7A{Z1[7  
有效性 EjP)e;  
方法 .2y @@g  
9H2mA$2jnE  
NESTED K6,d{n  
在tag标签的开始和结束之间 !8tqYY?>@\  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 VUD9ZyPw  
" s/ws  
AT_BEGIN _~;K]  
从tag标签的开始一直到页面结束 -i]2 b  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 ? 8)k6:  
uM9Gj@_  
AT_END [K1z/ea)V  
从tag标签的结束一直到页面结束 /a s+ TU`A  
在doEndTag中调用 Rb0{W]opt+  
**c"}S6:mC  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: dJ~Occ1~r  
\"d\b><R  
<tag> uCgJ F@  
be [E^%  
<variable> i]& >+R<6  
I p|[  
<name-from-attribute>id</name-from-attribute> 4^!%>V"d/  
|#Q0UM|'Q  
<variable-class>database.BookDetails</variable-class> DHuUEv<  
h]}DMVV]  
<declare>true</declare> dwb^z+   
T*k}E  
<scope>AT_BEGIN</scope> VRg y  
$<L@B|}F)  
</variable> Gsy'':u  
^~s!*T)\  
</tag> H-eHX3c7  
NleMZ  
额外tag信息类 9 $^b^It  
eL [.;_  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: $)6x3&]P  
7_J0[C!G  
· 变量名 }/jWa |)f  
gI/(hp3ob  
· 变量所属类名 {uxTgX  
I(j$^DA.  
· 此变量是否引用了一个新对象 >|mZu)HIY;  
hb1eEn  
· 此变量的有效范围 !1l~'/r  
I(b]V!mj:  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 >b8-v~o{  
]$U A5/a  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: K*M1$@5  
%0'7J@W  
{D8yqO A}  
public class DefineTei extends TagExtraInfo Ged} qXn  
#Fkp6`Q$x  
{ <&tdyAT?&  
y s[z[  
public VariableInfo[] getVariableInfo(TagData data) znAo]F9=J"  
9}+X#ma.Nc  
{ 27MwZz  
bnH:|-?q  
String type = data.getAttributeString(“type”); |<%v`*  
D#[<N  
If( type == null) lkJe7 +s  
5=1Ml50  
type = “java.lang.Object”; V?~!Dp  
|Z8Eu0RSb  
return new VariableInfo[] { 8YQ7XB  
`chD*@76I  
new VariableInfo(data.getAttributeString(“id”), =&m;5R  
[EK@f,iM  
type, 83VFBY2q  
@Thrizh  
true, Q'YakEv >=  
hfg ^z5  
VariableInfo.AT_BEGIN)  u5Mg  
uvi&! )x  
}; g"\J iBb5  
)!;20Po  
} N|/gwcKe  
%eGI]!vf  
} *77Y$X##k  
q9c-UQB(!  
\uZ1Sl  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: 2SlI5+u  
<tei-class> t+M'05-U2  
org.apache.struts.taglib.bean.DefineTagTei @?gRWH;Pq  
</tei-class> b"Jr_24t3v  
QQD7NN>  
x:c'ek  
具有协作关系的tag )5u#'5I>  
Iu^I?c[  
|W}D_2  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 0 c ]]  
  `#l1  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 YD0j&@.  
OyG2Ks"H  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。  )|W6Z  
uH#X:Vne  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 V{X/yN.u  
=Z..&H5i  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 x@D> JG  
"BIhd*K[~  
g+Y &rz  
public class QueryTag extends BodyTagSupport a6?t?: ~|  
{ T<[-"h  
{ {U4{v=,!I  
|hX\ep   
private String connectionId; R7c42L\QA  
D`U,T& @  
public int doStartTag() throws JspException qC q?`0&#  
n*Hx"2XF  
{ @VyF' ?}  
QHd|cg  
String cid = getConnection(); ,rOh*ebF  
:d~mlyFI6P  
if(cid != null) @\+UTkl8  
%BQ?DTtb7'  
{ W,:j >v g  
09i7 7  
//存在一个connection id,使用它。 j$4lyDfD  
*%%n9T  
connection = (Connection) pageContext.getAttribute(cid); yM7FR);  
"]q0|ZdOwH  
} z?GtC{L9  
'a$/ !~X  
else 99n;%W>  
M0hR]4T  
{ g!i45]6[Nw  
Z% ]LZ/O8  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, w^:@g~  
}H/94]~tH  
ConnectionTag.class); e0IGx]5i  
QBA{*@ A-  
if(ancestorTag == null) Z{2QDjAI;  
,+x\NY2d  
{ hl2|Ec  
@KJmNM1]V  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); 3wQ\L=  
;CuL1N#I  
} G]dHYxG  
e~nh95  
connection = ancestorTag.getConnection(); I<" UQ\)  
iZ0(a   
} '1d0 *5+6k  
Hi U/fi`  
} #v4^,$k>  
fT<3~Z>m  
} To-$)GQ@W  
#IeG/t(  
\*pS 4vy5x  
ClufP6'  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: ^c"\%!w"O  
Psm9hP :m  
rLbFaLeQ  
<tt:connection id=”con01” ...> ... </tt:connection> AP9\]qZ(7  
m"o=R\C  
<tt:query id=”balances” connection=”con01” > Mb97S]878I  
Ifq|MZ\  
SELECT account, balance FROM acct_table ~se ;L  
mA #^Pv*  
where customer_num = <%= request.getCustno() %> jU}  
(1'sBm7F  
</tt:query> r^Soqom3  
) }k"7"  
@[1,i~H  
9QkssI  
*48LQzc  
<tt:connection ...> 1+l[P9?R[  
GT3}'`f B  
<x:query id=”balances”> m-q O yt  
L>N)[;|  
SELECT account, balance FROM acct_table v'Up& /(  
<!X]$kvG  
where customer_num = <%= request.getCustno() %> V3axwg_  
@Q:?,  
</x:query> #Zn+-Ih  
.SBN^fq  
</tt:connection> dhuIVBp!!e  
T<RWz  
Iapzhy2l  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: >_X(rar0  
wHQYBYKcd  
<tag> 7K!n'dAi6  
HBw0 N?  
... /#}%c'  
7/\SN04l  
<attribute> / $'M  
])WIw'L!  
<name>connection</name> RC!T1o~L  
6X$\:>  
<required>false</required> XLm@, A[  
" j:15m5  
</attribute> 5jTA6s9zA  
[U7r>&  
</tag>
描述
快速回复

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