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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! tAE(`ow/Ur  
Y0.'u{J*  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 d!w3LwZ  
5RvE ),  
在这篇文章中,我们主要讨论: :_y!p  
'da 'WZG  
· 什么是自定义tag标签? xL1Li]fM!'  
=Q{?!  
· 怎么使用tag标签? e@qH!.g)  
]/kpEx  
o 声明要使用的tag库 x&*f5Y9hCi  
zBlv?JwG  
o 找到与之对应的tag处理类 nj0sh"~+  
(ix.  
o tag标签的类型 |ZE^'e*k  
oz>2P.7  
· 自定义tag标签 -&sY*(:n_  
BGBHA"5fz  
o tag处理类 zxx\jpBBk  
CxeW5qc  
o tag库描述 qx b]UV,R  
;<N:!$p  
o tag标签示例 ? "r=08  
C6[W/,eS  
o 带属性的tag :u./"[G  
BaW4 s4u  
o 带body的tag 6IG?t  
MNWI%*0LO  
o 定义了脚本变量的tag Nwz?*~1  
+ x=)Kp>  
o 具有协作关系的tag ] re=8s6  
S@qR~_>a  
· 自定义tag标签 u30D`sky  
q6)fP4MQ]  
o 一个迭代tag的例子 gr SF}y!3  
X0u,QSt' O  
o 一个模板tag库 /V:9*C  
&K\80wGK  
o tag处理类到底是怎样被调用的? dv>n38&mDQ  
=&}_bd/]  
|g)C `k  
什么是自定义的tag? @wgd 3BU  
Si>38vCJ*  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 U_(>eVi7F  
Ha`N  
自定义tag标签有很多特色,诸如: yl~_~<s6  
^iMr't\b  
· 可以在JSP页面中自定义tag标签的属性 IibrZ/n6  
80*hi)ux[  
· 访问JSP页面中的所有对象 O`9c!_lis  
CpO_p%P  
· 可以动态地修改页面输出 Y/kq!)u;%L  
rk W7;!  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 3T)rJEN A  
E7fQ9]  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 i]%f94  
L'e^D|  
yov~'S9  
使用tag标签 >#|%'Us  
+7 H)s  
m!/TJhiQ  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 js<d"m*  
Q?k *3A  
要使用tag标签,JSP程序员必须做2件事: k{SGbC1=VK  
tk%f_"}  
· 声明此tag标签的tag库 'RMUjJ-!  
`N *:,8j  
· 实现此tag标签 z%YNZ ^d  
*8Z2zmZtR^  
声明tag标签所在的tag库 @.e X8~3=  
il5C9ql$  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) #{8I FA  
vFVUdxPOw  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> *p}mn#ru-  
8wsU`40=Q  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 8)X9abC  
:(n<c  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 JN0h3nZ_  
5naFnm7%  
以下taglib指示符直接引用一个TLD: $jN.yNm0  
AHb_BgOU*  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> UX)GA[WI  
>|QH I d8  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: _!03;zrO  
)7>GXZG>=  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> 7ftn gBv?  
>2s4BV[(  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: F^yW3|Sb  
M~:_^B  
<taglib> <~ smBd  
Cr5ND\  
<taglib-uri>/tutorial-template</taglib-uri> ic2 D$`M  
ku]5sd >b  
<taglib-location> ]8p{A#1  
d51lTGH7Z  
/WEB-INF/tutorial-template.tld w]wZJ/U`  
{D4FYr J  
</taglib-location> VE )D4RL  
54_}9_g  
</taglib> +krDmU9(  
|\N))K-2D  
3e1^r_YI  
实现此tag标签 S{UEV7d:n0  
c> ":g~w  
yAu .=Eo7  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 F<(?N!C?@  
h 2C9p2.  
~;I'.TW  
tag标签类型 >uJU25)|  
Im@Yx^gc   
,ZvlK N  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): 9.Yn]O  
0f"la=6  
<tt:tag> iM"L%6*I^  
gk4DoOj#P  
body $aj:\A0f  
/}=cv>S5V  
</tt:tag> >H,PST  
(w?W=guHu  
1_z~<d @?;  
一个不带body的tag标签如下: VX e7b  
J pKCux  
<tt:tag /> o_PQ]1  
:{~TG]4M  
@<B$LJ|jdG  
简单的tag标签 lA,*]Mr~  
=p&uQ6.i+  
一个没有body和属性的tag标签如下: TFtD>q X  
VevDW }4q*  
<tt:simple /> Sxc p [g;  
zOMU&;.\  
"^5%g%  
带属性的tag标签 d? 4-"9Y  
N@R?<a  
-{eI6#z|\A  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 'E%+ O  
DTC OhUIV  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: Ky)*6QOw  
I|)U>bV  
<loglic:present parameter = “Clear”> nrCr9#  
+P;&/z8i*g  
而另一个标签logic:iterate是用表达式来给属性赋值: Z1oUAzpj4  
7aeyddpM  
<logci:iterate collection=”<%= bookDB.getBooks() %>” LRv[,]b  
jC L 1Bj  
id=”book” type=”database.BookDetails”> B-[qS;PY%  
&#<>fT_  
 $ 1v'CT  
带body的tag标签 FuFA/R=x/  
a<v!5\dq!  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 ]McDN[h:  
v)rQ4 wD:  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息: Pe?b# G  
=\i{dj  
<logic:present parameter=”Clear”> ~3qt<"  
ZG Qz@H5  
<% cart.clear(); %> S3> <zGYk  
U t.#h="  
<font color=”#ff0000” size=”+2”><strong> Mt%=z9OLq9  
0v'!(&m  
你选择了清除购物车! YH'j"|{  
5ii:93Hlj  
</strong></font> B"2#}HM  
6Wc'5t3  
</logic:present> CL<m+dW%*  
[M&.'X  
=x} p>#o,J  
到底是用属性还是用body来传递信息? .?*TU~S  
Fle pM*  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 d@>1m:p  
:x36Z4:  
eWTbHF  
定义脚本变量的tag标签 PR~9*#"v..  
T/ TMi&:?.  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: }g_\?z3gt  
p+; La  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> s.XLC43Rs  
~=Q Tv8  
<% tx.begin(); %> n ?+dX^j  
b]Z>P{ j  
... CC.ri3+.  
_ e94  
IHvrx:7  
具有协作关系的tag标签 ?$Ii_.  
Kzrt%DA  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 c,_??8  
.fD%*-  
<tt:tag1 attr1=”obj1” value1=”value” /> d{:0R9  
7V-'><)gI  
<tt:tag2 attr1=”obj1” /> /'Q2TLy=  
_Sn45h@"  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 Bd>a"3fA  
%rq/&#jC  
<tt:outerTag> iuS*Vw  
vw[i.af  
<tt:innerTag /> 3jDAj!_ea  
5;q{9wvqO  
</tt:outerTag> E>Lgf&R#W  
k07pI<a?  
=9L1Z \f  
Tag处理类 'rDai [  
-mY,nMDb  
>S'IrnH'!  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 XWv;l)  
IHcR/\mz  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 1AAOg+Y@U"  
ky=h7#wdv-  
下表说明不同类型的tag所需要不同的处理过程: O8)N`#1>+  
{{@*  
Tag处理类的方法 ,f^ ICM  
@23~)uiZa  
Tag标签类型 XN}^:j_2  
所调用的方法 Z,7VOf6g  
0Ait7`  
基本标签 rceX|i>9n  
doStartTag, doEndTag, release dq^vK  
Aqo90(jffx  
带属性的标签 W(\ ^6S)  
doStartTag, doEndTag, set/getAttribute1...N, release {.o@XP,.  
uS7kkzt-x  
带内容的标签 B/Z-Cpz]  
doStartTag, doEndTag, release =Hx]K8N)  
'; ;X{a  
带内容的标签,且内容重复循环 t4Pi <m:7  
doStartTag, doAfterBody, doEndTag, release 2B"&WKk  
^]MLEr!S  
带内容的标签,且内容与JSP交互 R'Uf#.  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release OTzuOP 8  
+F+M[ef<ws  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 45;ey }8  
t^~Qv  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 uYC1}Y5N  
3<HZ)w^B  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 OJ r~iUr  
uR6 `@F  
`#"xgOSP>  
Tag库描述(简称TLD) nXw98;  
u=t.1eS5  
{r'+icvLX  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 XIn,nCY;  
(dTQ,0  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 @MO/LvD  
 "3/&<0k  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: hkMVA  
?[7KN8$  
<?xml version="1.0" encoding="ISO-8859-1" ?> SG]Sx4fg,Y  
ih-J{1  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> fZrh_^yH  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: 0o!mlaU#  
Whe-()pG{  
l=ZD&uK  
<taglib>的子元素 i` Q&5KL  
\440gH`  
Element pQ>|d H+.  
Description Jj?HOtaM  
DL uaM?7  
tlib-version <w`EU[y_  
Tag库的版本 $ ^@fV=e  
Ft38)T"2R\  
jsp-version h'?v(k!  
Tag库所需要的jsp的版本 &gKDw!al  
d0-4KN2  
short-name }x+6<Rp'E_  
助记符,tag的一个别名(可选) )Xa_ry7  
`jSegG'  
uri `][vaLd`Q  
用于确定一个唯一的tag库 OTl9MwW  
ln+.=U6Tm  
display-name i&?\Pp;5-j  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) (;&}\OX6nm  
JOJuGB-d  
small-icon h8X[*Wme  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) HNCu:$Wr@  
*CPpU|  
large-icon L_aqr?Q  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) 6aOyI ;Ux  
7e\Jg/FU  
description *5 .wwV  
对tag库的描述(可选) 4\5i}MIS0  
W@ &a  
listener j#~~_VA~  
参见下面listener元素 TY'c'u,  
uAqiL>y  
tag 2Z%n "z68  
参见下面tag 元素 $}{[_2  
qxDMDMN  
Listener元素 ox%j_P9@:  
1Y*k"[?dW  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 sOlnc6  
\pfa\, rW  
Tag元素 `FQ]ad Fz  
oKsArZG  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 Y!_{:2H8p  
|Y05 *!\P*  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: %~x?C4L8  
c8YbBdk'  
Tag元素的子元素 A&)2m  
JRw,${W  
元素名称 J@2wPKh?Yp  
描述 D\b$$z]q  
Y(bB7tR  
name Yj1|]i5b  
独一无二的元素名 ,|s*g'u  
38D5vT)n  
tag-class ,'c%S|]U7  
Tag标签对应的tag处理类 7vgRNzZoq  
3SWDPy  
tei-class Jy:@&c  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) ,Z|O y|+'  
%pg)*>P h  
body-content AIl`>ac  
Tag标签body的类型 * g+v*q X  
j\KOKvY)  
display-name }k AE  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) ~C 3 Y/}  
+q2\3REzx  
small-icon hK4ww"-  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) EO'+r[Y  
ST#)Fl  
large-icon zk70D_}L  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) 6R m dt  
uF%N`e^S  
description q:vN3#=^qf  
此tag标签的描述 z1RHdu0;z  
`o_i+?E  
variable jMWTNZ  
提供脚本变量的信息(同tei-class)(可选) cJT_Qfxx  
n>^9+Rx|i  
attribute 9[{q5  
Tag标签的属性名 MAqETjB  
QncjSaEE  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 9%k4Ic%P  
\8Ewl|"N:u  
T}p|_)&y  
简单的tag " d~M \Az  
,9:v2=C_  
%RIu'JXi  
tag处理类 ]w)uo4<^J  
>SZuN"r8`  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 -uAGG?ZER  
Exi#@-  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: MmfshnTN  
{dl@ #T u  
l9 rN!Q|  
public SimpleTag extends TagSupport 00W_XhJ  
$H,9GIivD  
{ ,E(M<n|.  
U$ZbBVa`~  
public int doStartTag() throws JspException yK2>ou  
HRd02tah  
{ )]}68}9  
. }tpEvAw}  
try{ ^^Q> AfTR.  
n u>6UjV  
pageContext.getOut().print(“Hello.”); G#^6H]`[J:  
z\IZ5'  
}catch(Exception e){ t1l4mdp  
kdm@1x  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); 6:TA8w|  
M w+4atO4[  
} na/,1iI<  
tUFXx\p  
return SKIP_BODY; VS<w:{*  
SQ`ec95',  
} u7u1lx>S  
@v\jL+B+m  
public int doEndTag() Uv3Fe%>  
8g 2'[ci$q  
{ Fc"+L+h@W  
62xAS#\K>  
return EVAL_PAGE; +3;[1dpgf  
 -Ly A  
} I#t# %!InH  
^d/,9L\U  
} 9O#?r82  
R 9Y k9v  
af2yng  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 |Q~5TL>b  
u!VY6y7p  
<body-content>empty</body-content> =Cr F(wVO"  
,HO@bCK  
so\8.(7n  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 VN9C@ ;'$  
'xY@ I`x  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, LK[%}2me  
F45UO%/P  
<logic:present parameter=”Clear”> |CFTOe\ q  
GiN\@F!  
与此相应,此tag处理类应有如下方法和定义: 7 V+rQ  
.)eX(2j\  
v(tr:[V  
protected String parameter = null; SNK _  
f}>S"fFI  
public String getParameter() RGim):1e  
pP6pn~ }  
{ &<sN( ;%0R  
aGz <Yip  
return this.parameter; {r!X W  
yXx}'=&!0  
} ;tF7 GjEp  
E|Lv_4lb=  
public void setParameter(String parameter) e/<Og\}P/  
`n!<h,S'2  
{ \;>idbV  
L@{5:#-  
this.parameter = parameter; 'J`%[,@V  
0#mu[O  
} i+V4_`  
FFNv'\)  
H[{ch t h  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 {]}}rx'|P  
Tl!}9/Q5E:  
Attribute元素 Pxj ?W'|  
;ml;{<jI  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 &zF1&J58z  
UEJX0=  
<attribute> '~E&^K5hr  
;q&>cnLDR  
<name>attr1</name> \7}X^]UVx  
GJA3  
<required>true|false|yes|no</required> Pv`^#BX'  
]~z2s;J{/  
<rtexprvalue>true|false|yes|no</rtexprvalue> m.MOn3n]  
C`D5``4  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> xcz1(R  
]OoqU-q  
</attribute> eD*"#O)W  
DiAPs_@  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 MS6^= ["  
Nvs8t%  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 w$7*za2  
_?3bBBy  
<tag> NwmO[pt+  
YXJjqH3  
<name>present</name> ;b$(T5  
+gTnq")wnI  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> +EcN[-~  
D a)[mxJ  
<body-content>JSP</body-content> 6tM CpSJ  
K ^1bR(a  
+GWeu0b(~  
@R?S-*o  
<attribute> ~l-Q0wg  
'?_;s9)  
<name>parameter</name> K.] *:fd  
u(?  
<required>false</required> L '342(  
'1=t{Rw  
<rtexprvalue>true</rtexprvalue> _ 9Tv*@  
=_8  
</attribute> u9e A"\s  
cp2e,%o  
6d,jR[JP  
`w]=x e  
</tag> iD_NpH q  
;|b D@%@  
\no[>L]  
属性元素的校验 by& #g  
H(!)]dO  
wa W2$9O  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 a>Uk<#>2?a  
j|KZ HH%dc  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 &?/h#oF@\  
d$kGYMT"  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 YQiTx)_  
8\`]T%h  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: yEy} PCJ&  
y:D|U!o2V  
<attribute> xRJv_=dT  
zhU)bb[A  
<name>attr1</name> MMD4b}p  
8,#v7ns}#  
<required>true</required> l[l('-f  
2md1GWyP  
<rtexprvalue>true</rtexprvalue> ^/2n[orl5  
N0sf V  
</attribute> P8Fq %k  
"ZNiTND  
UC;_}>  
这个定义说明了attr1能在运行期间被赋值。 S>aN#  
 "C B*  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 ( N~[sf?&  
{ o=4(RC  
=E8lpN'  
Public class TwaTEI extends TagExtraInfo &p^ S6h  
f:GZb?Wyd  
{ (01M0b#  
`)& -;CMY  
public boolean isValid(Tagdata data) <bWhTNOb  
.%h.b6^  
{ bg*4Z?[dd  
@3K)VjY7  
Object o = data.getAttribute(“attr1”); [2gK^o&t  
3aQWzEnh  
If(o != null && o != TagData.REQUEST_TIME_VALUE) M])Y|}wv8  
+#}I^N  
{ KcglpKV`  
'`#2'MXG  
if( ( (String)o).toLowerCase().equals(“true”) ||   _p\  
G,e>dp_cPu  
((String)o).toLowerCase().equals(“false”) ) p[VBeO^%  
znw\Dn?g  
return true; F``$}]9KHD  
8 qt,sU  
else ]vMr@JM-G  
Lo\+T+n  
return false; w7$*J:{  
bX:Y5o49  
} p [4/Nq,c  
Gy hoo'<  
else tI|?k(D  
`$\g8Mo  
return true; a ?/GEfd  
o;.PZi2k  
} Mp^%.m  
-Mx"ox  
} ~0,Utqy  
\/g.`Pe  
.p  NWd  
带body的tag uIvy1h9m  
{O9CYP:  
i[/g&fx  
tag处理类 w$WN` =  
U:ggZ`.  
A9' [x7N  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 l)< '1dqe  
o?$kcI4  
Tag处理类不与body交互 hqIYo .<  
_fx0-S*$  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 "K n JUXpl  
-B-?z?+(O  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 sgp5b$2T.  
R]O!F)_/'  
Tag处理类与body交互 ?piv]Z  
+ntrp='7O7  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 7p%W)=v  
S=H<5*]g  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 g+;)?N*j  
64;F g/t  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。  =+9.X8SP  
Y?W"@awE"\  
doInitBody 方法 k>y68_  
tgXIj5z  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 6X2>zUHR  
D%GB2-j R  
doAfterBody方法 qplz !=  
P=PcO>  
此方法在body内容已被计算后进行调用。 /cHd&i,>  
T&Z%=L_Q  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 SFCKD/8  
BayO+,>K  
release 方法 sk !92mQ  
vH/<!jtI  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 [SGt ~bRJ  
?O(KmDH  
XOgl> 1O  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 $ZX^JWq  
gI8r SmH  
q] g'rO'  
Public class QueryTag extends BodyTagSupport <YX)am'\y  
<Wc98m  
{ k[lYd k  
59K%bz5t  
public int doAfterBody() throws JspTagException b<,Z^Z_  
0sq?;~U  
{ }YUUCq&  
f>.A^?  
BodyContent bc = getBodyContent(); C@+"d3  
_~!*|<A_  
//将body的内容以字符串的格式提取出来 (2J_Y*N~>  
|O0=Q,<m  
String query = bc.getString(); s/[15  
*zoAD|0N  
//清除body iC-WQkQY  
V_Z~$  
bc.clearBody(); ,4dES|)sP  
bg.f';C  
try{ 7oY}=281  
qh}M!p2  
Statement stmt = connection.createStatement(); Co6ghH7T  
^]mwL)I}  
Result result = stmt.executeQuery(query); s@C KZ`  
ERxA79  
}catch(SQLException e){ mq~rD)T  
S"?py=7  
throw new JspTagException(“queryTag: “ + e.getMessage() ); zA+&V7bvy  
0{|ib !  
return SKIP_BODY; z 9mmZqhK\  
\(UEjlo  
} # Sfz^  
Kj[X1X5  
} \ZdV|23  
Y9F78=Q  
:UjHP}s  
body-content元素 @l3L_;6a  
}\5^$[p  
PAF2=  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: 3UeG>5R  
uS :3Yo  
<body-content>JSP|tagdependent</body-content> `5}XmSJ?5  
xR5jy|2JJ  
=IBdnEz:M  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 2YvhzL[um  
:32  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 #W<D~C[I _  
9TGjcZ1S'  
S3nA}1R  
用tags定义脚本变量 -L7Q,"a$  
N*JWd  
[.tqgU  
tag处理类 kE QT[Lo  
ai"Kd=R  
oD_'8G}  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 pKO\tkMJ  
_$/(l4\T[  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 fx|$(D@9  
`WF?87l1  
对象的生存周期(scope)如下表: d |Wpub  
\XwXs 5"G  
对象的生存周期表 -)@DH;[tb  
N3E Qq~lX  
名字 7 ]a6dMh  
可访问范围 &,Dh*)k  
生存周期 K' N`rx.7  
* EOIgQp  
page {>>ozB.  
当前页面 (A`/3Aq+  
一直有效,除非页面向客户提交响应或重定向到一个新页面 Z[KXDQn8  
YhFB*D;  
request k <ds7k1m  
当前页面或当前页面重定向到的页面 hfP}+on%  
一直有效,除非页面向客户提交响应 EL80f>K  
~=(?Z2UDA_  
session esmQ\QQ^1  
当前页面或在同一浏览器窗口中的页面 j['Z|Am"l  
一直有效,除非关闭当前浏览器、超时、网络故障 4\<[y]pv  
: :8UVLX  
application u$x H iD  
整个web应用程序的所有请求 \p1H" A  
一直有效,除非发生网络故障、服务器故障 (.7_`T6QG  
%stZ'IX  
提供关于脚本变量的信息 Y>Q9?>}Q  
ZN5\lon|Y  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: F7UY>z3jL  
K^?yD   
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> 3(%hHM7DM  
K97lP~Hu  
<font color=”red” size=”+2” > 5gZ0a4  
S(mJ;C  
<%= messages.getString(“CartRemoved”) %> h>$,97EU  
Qpiv,n  
<strong><jsp:getProperty name=”book” property=”title” /></strong> :^lyVQ%@  
G+AD &EHV  
</font> `zRgP#  
c`mJrS:  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: J]nb;4w  
4fw>(d(2  
· 脚本变量名称 PTIC2  
d /&aC#'B  
· 脚本变量所属的类 6G7B&"&  
@no]*?Gpa  
· 此脚本变量是否引用了一个新的或已存在的对象 kmNY ;b6Y$  
|~hSK  
· 此脚本变量的有效性 iyU@|^B"Wa  
b* qkox;j  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 8^&)A b  
+cM;d4  
Variable元素 ww nc  
_)p@;vGV  
Variable元素有如下子元素: Y1+4ppZ  
X_+`7yCi"x  
· name-given ?D?D 给出的名字,是一个常量 t*zve,?}  
4O9HoX#-?  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 9z\q_ 0&i  
^v*ajy.>  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: +`u]LOAyP=  
f'TjR#w  
· variable-class?D?D变量的类型,缺省为java.lang.String。 je9[S_Z:Y  
(' /S~  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 X}0NeG^'O  
|;6FhDW+'  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: g$ZgR)q  
%Ub"V\1  
脚本变量的有效范围 +VDwDJ)lG  
<tuh%k  
m@.4Wrv  
有效性 %Gl,V5z&  
方法 44f8Hc1g  
Otj=vGr0  
NESTED {a `kPfP  
在tag标签的开始和结束之间 })T}e7>T  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用  7.CzS  
63UAN0K%  
AT_BEGIN YN n,{Xi  
从tag标签的开始一直到页面结束 )K -@{v^|  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 TGdD7n&Ehh  
Cq !VMl>hP  
AT_END yC =5/wy`  
从tag标签的结束一直到页面结束 vUS$DU F  
在doEndTag中调用 GuQ3$B3j  
0fxA*]h  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: !O@qqg(>  
"}*P9-%  
<tag> j,/OzVm9  
szF[LRb  
<variable> Z7JI4"  
llhJ,wD  
<name-from-attribute>id</name-from-attribute> *1ekw#'  
qdCa]n!d  
<variable-class>database.BookDetails</variable-class> r|fJ~0z  
` R!0uRu  
<declare>true</declare> 2etcSU(y>  
Nj %!N  
<scope>AT_BEGIN</scope> i:&Y{iPQp  
`dMOBYV  
</variable> UN`-;!  
_;yp^^S  
</tag> tU!"CX  
Rr^<Q:#"<|  
额外tag信息类 $T^O38$  
] \4-e2N`\  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: =NSLx2:T  
YCeE?S1gk3  
· 变量名 r*>XkM& M  
rD%(*|Y"c  
· 变量所属类名 cwz %LKh  
{p 9y{$  
· 此变量是否引用了一个新对象 _q)`Y:2  
HOsq _)K  
· 此变量的有效范围 9r)5d&,6  
|%M%j'9  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 Y#N'bvE|%  
)<Yy.Z_:DC  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: 1yKf=LZ^  
:!#-k  
hpw;w}m  
public class DefineTei extends TagExtraInfo SE/@li  
v'iQLUgI  
{ N4D_ 43jz  
}u|0  
public VariableInfo[] getVariableInfo(TagData data) *'`-plS7  
N.2rF  
{ B$lbp03z  
>MhkNy  
String type = data.getAttributeString(“type”); * dNMnZ@Y  
6: M   
If( type == null) %Ajf|Go0/G  
!-7(.i-  
type = “java.lang.Object”; hz/5k%%UX  
L Xx 3  
return new VariableInfo[] { "o TwMU  
j5RM S V  
new VariableInfo(data.getAttributeString(“id”), *k=}g][?  
iE&`F hf?  
type, |e pe;/  
S5uV\Y/A  
true, }SOj3.9{c  
BE m%x 0y  
VariableInfo.AT_BEGIN) lvFHr}W  
_x>u "w  
}; [PU.lRq  
fNlUc  
} }LE/{]A  
$U6)km4  
} gmM79^CEF  
WIb U^WJ0  
3W27R  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: E]e6a^J#  
<tei-class> .vb*|So  
org.apache.struts.taglib.bean.DefineTagTei  k&rl%P  
</tei-class> t<`BaU  
_ Fer-nQ2R  
|fa3;8!96  
具有协作关系的tag _H;ObTiB  
6ZF5f^M^  
$w65/  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 !!P)r1=g  
]6(NeS+  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 =?/J.[)<*  
7.]xcJmt>'  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 Nlo*vu  
UyvFR@  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 w1.KRe{M  
oinF<-(  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 .m4K ]^m  
e98f+,E/  
z_nv|5"  
public class QueryTag extends BodyTagSupport Kg?(Ax4  
N hG?@N  
{ "Tt5cqUQoY  
?V&# nA  
private String connectionId; w>S;}[fM  
)d(F]uV:y  
public int doStartTag() throws JspException lZ gX{  
= j)5kY`  
{ ^1`Mz<  
n4Xh}KtH  
String cid = getConnection(); ^jh c(ZW"  
H. o=4[  
if(cid != null) IX+!+XC"U  
`s8*n(\h  
{ W=G8l%  
1egq:bh  
//存在一个connection id,使用它。 [Z]%jABR  
!1m7^3l7j  
connection = (Connection) pageContext.getAttribute(cid); D*0[7:NSO  
pgUp1goAU  
} >uLWfk+y1  
zy'e|92aO  
else NdxPC~Z+  
w 3kX!%a:  
{ yRAfIB$T}"  
"50 c<sZSB  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, '><I|c}  
)gVz?-u+D  
ConnectionTag.class); utzf7?nIS  
um,G^R   
if(ancestorTag == null) "UYlC0 S\  
QtHK`f>4#n  
{ U%rEW[j  
%p;;aZG  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); W\EvMV"  
X<sM4dwxE  
} <s=i5t My5  
Xk] uXx:TN  
connection = ancestorTag.getConnection(); yz7Fe  
`T,^os#6  
} ~F " w  
AA K}t6  
} ~ym-Szo  
l_ycB%2e^  
} W4=<hB  
HNV"'p;  
BoXGoFn  
EYU3Pl%  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: y_Nn%(j  
PxgLt2dXa  
{pEbi)CF,}  
<tt:connection id=”con01” ...> ... </tt:connection> XLFo"f  
<9Pf] G=  
<tt:query id=”balances” connection=”con01” > /N`E4bKBR  
/-1 F9  
SELECT account, balance FROM acct_table OEs!H]v  
+#g?rCz  
where customer_num = <%= request.getCustno() %> eX9H/&g  
3,{tGNl|  
</tt:query> df!n.&\y!  
AME6Zu3Y  
qGKQrb,K  
.\b# 0w  
{;ur~KE  
<tt:connection ...> %-~T;_.  
&B>YiA  
<x:query id=”balances”> 3}X;WE `  
)6Qk|gIu(  
SELECT account, balance FROM acct_table OcGHMGdn  
4) ~ GHb  
where customer_num = <%= request.getCustno() %> X8=s k  
-( +/u .  
</x:query> KRh95B GU  
cakb.Q  
</tt:connection> 6z80Y*|eJ  
3re|=_ Hy  
c`h/x>fa  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: 7ezf.[{R  
rocG;$[  
<tag> VC@{cVT  
N HL{.8L{  
... f6Io|CZWJ  
!{L`Zd;C>w  
<attribute> y!?l;xMS  
ghd*EXrF H  
<name>connection</name> , *A',  
?Em*yc@WD  
<required>false</required> ?4i:$.A Y  
RxVf:h'l  
</attribute> aPMqJ#fIr  
PME ?{%&  
</tag>
描述
快速回复

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