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

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

级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记! _X|prIOb=  
\(RD5@=!4#  
一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。 O0FUJGuTS  
gyb99c,)  
在这篇文章中,我们主要讨论: F{4v[WP)  
58d[>0Xa[g  
· 什么是自定义tag标签? 1F_$[iIX]  
<F8e?xy  
· 怎么使用tag标签?  l5 ]  
p|(SR~;6  
o 声明要使用的tag库 5DDSo0E  
ap8q`a{j^  
o 找到与之对应的tag处理类 16>D?;2o(  
):_@i  
o tag标签的类型 )Gm9x]SVl  
Mg2e0}{  
· 自定义tag标签 d@ >i=l [  
'$c9S[  
o tag处理类 2e-`V5{)b  
l2kGFgc  
o tag库描述 E#\Oe_eq~N  
qvLh7]sbK:  
o tag标签示例 n\M8>9c  
*`rfD*  
o 带属性的tag  DR{O.TX  
Rpv[rvK'  
o 带body的tag $btu=_|f  
l^d'8n  
o 定义了脚本变量的tag T@=C2 1  
_-lE$ O  
o 具有协作关系的tag 2l O(f+  
s[sv4hq  
· 自定义tag标签 +ZwoA_k{  
- om9 Z0e  
o 一个迭代tag的例子 K2yu}F^}  
^Fh*9[Zf$  
o 一个模板tag库 swxX3GR  
'Y#'ozSQv  
o tag处理类到底是怎样被调用的? aopZ-^  
[gpO?'~  
TIxOMYy  
什么是自定义的tag? ,f2oO?L}  
B ,cFvS  
一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。 $L 8>Ha}  
w;gk=<_  
自定义tag标签有很多特色,诸如: rHTZM,zM=H  
uE41"?GS  
· 可以在JSP页面中自定义tag标签的属性 DtFHh/X  
5h&sdzfG  
· 访问JSP页面中的所有对象 CNefk$/cR  
HWsV_VAw}  
· 可以动态地修改页面输出 Q(]m1\a  
)\#*~73  
· 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。 9e=}P L  
60vmjmXl  
· tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。 t\hnnu`Pq  
HoABo:  
.Pponmy  
使用tag标签 g ns}%\,  
rP3tFvOH  
>jsY'Bm  
本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。 ;ND$4$  
< j:\;mi;  
要使用tag标签,JSP程序员必须做2件事: ?!P0UTe~  
<7VLUk}  
· 声明此tag标签的tag库 /iFn =pk1?  
qC> tni%  
· 实现此tag标签 D{6 y^@/  
(|K+1R  
声明tag标签所在的tag库 ywAvqT,  
oI{.{]  
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明) @01.Pd   
B18BwY  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> {&,p<5o  
<#h,_WP*  
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。 5_aj]"x  
J:N(U0U  
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。 iz#R)EB/g  
fA6IW(_bi  
以下taglib指示符直接引用一个TLD: V|MHDMD=  
K9#kdo1 2  
<%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %> dn#I,xa`  
v:P]o9Oj8  
以下的taglib指示符通过一个逻辑名称间接地引用一个TLD: n?fy@R  
/P*XB%y  
<%@ taglib uri=”/tutorial-template” prefix=”tt” %> [t?tLUg|6  
'z. GAR  
如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素: ._G ,uP$  
8M*+ |  
<taglib> T]De{nHu  
<R7{W"QTA)  
<taglib-uri>/tutorial-template</taglib-uri> =7<JD}G  
`q-+r1u  
<taglib-location> \#HW.5  
;qgo=  
/WEB-INF/tutorial-template.tld GQtNk<?$I  
jsN[Drra  
</taglib-location> BYq80Vk%@  
<Q~N9W  
</taglib> F0<)8{s  
+-j-)WU?,  
@ b!]Jw  
实现此tag标签 VvyRZMR  
,W}:vdC  
61S;M8tNv  
为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。 L+8ar9es  
Zk=,`sBC  
u}iuf_  
tag标签类型 m.K cTM%j  
Vgm'&YT  
M@cFcykK  
自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点): sF {,n0<8  
ZA(u"T~  
<tt:tag> .$&^yp  
qq5X3K2&  
body RsZj  
f;{Q ~  
</tt:tag> +HS]kFH  
<+k&8^:bi  
9hA`I tS  
一个不带body的tag标签如下: 0vv~G\yM  
B]X8KzLu  
<tt:tag /> ^p3 GT6  
t8*Jdd^3Z/  
`dZ|Ko%k  
简单的tag标签 uV5uZ  
~&<#H+O  
一个没有body和属性的tag标签如下: aFTWzz  
h!w::cV  
<tt:simple /> : "85w#r  
sy"}25s  
IbI0".o  
带属性的tag标签 c2P}P* _  
(uC8M,I\  
UY(T>4H+h  
自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。 K0.aU  
u}5CzV`  
你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值: yD3}USw  
OH t)z.  
<loglic:present parameter = “Clear”> "8f4s|@ 3  
 QHNyH  
而另一个标签logic:iterate是用表达式来给属性赋值: L2XhrLK.|  
cw<I L  
<logci:iterate collection=”<%= bookDB.getBooks() %>” XKWq{,Ks  
I8bM-k):9R  
id=”book” type=”database.BookDetails”> PJ5}c!o[  
q94;x|63  
Jq/itsg  
带body的tag标签 Bv<gVt  
Pe _O(  
一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。 Xz^nm\  
k'o[iKlu  
在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息:  @lN\.O  
r9ulTv}X  
<logic:present parameter=”Clear”> R;OPY?EeW  
=.3#l@E!C  
<% cart.clear(); %> =z'(FP5!0  
-pC'C%Q  
<font color=”#ff0000” size=”+2”><strong> \bARp z?a  
O*~,L6# }  
你选择了清除购物车! U`(=iyWP=  
qX@e+&4P0  
</strong></font> 91]|4k93  
Tx.N#,T|  
</logic:present> 9S%5 Z>  
1/97_:M0~F  
 vD#U+  
到底是用属性还是用body来传递信息? 6|eqQ+(A  
!y d B,S  
如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。 v5M4Rs&t  
YmC}q20;  
 t;o\"H  
定义脚本变量的tag标签 <wS J K  
NW[K/`-CTH  
所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等: Vgj#-7bdyi  
JR] 2Ray  
<tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” /> uMQI Aapb  
:+"4_f0  
<% tx.begin(); %> &Sd5]r@+  
^{}G4BEY  
... W:i Q& [f  
hju^x8 ,=m  
p7|I>8ur.  
具有协作关系的tag标签 n#P>E( K  
6BV 6<PHJ  
自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。 t<v.rb  
.) Ej#mk  
<tt:tag1 attr1=”obj1” value1=”value” /> )E.AY  
A]bQUWt2  
<tt:tag2 attr1=”obj1” /> D)-LZbPa  
{]dxFhe)  
在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。 tNY;wl:wp  
2PQBUq  
<tt:outerTag> 7z;2J;u`n  
`Q*`\-8J  
<tt:innerTag /> zx$YNjeV  
+v B}E  
</tt:outerTag> NMkP#s7.y  
6(QfD](2}  
Ir JSU_  
Tag处理类 ;{I9S'  
g@'XmT="_  
ZjxF@`H  
Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。 XCI  
2 ,nhs,FZ  
当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。 =aVvv+T  
#2^0z`-\_z  
下表说明不同类型的tag所需要不同的处理过程: I">">  
WHC/'kvF  
Tag处理类的方法 +<\LY(o  
Tt~4'{Bc  
Tag标签类型 ajycYk9<m  
所调用的方法 q?LOtN? o  
Zz} o  t  
基本标签 {qw'gJmX  
doStartTag, doEndTag, release ^KbR@Ah  
$ #!oejLD  
带属性的标签 ZRjM^ d;  
doStartTag, doEndTag, set/getAttribute1...N, release Uc!k)o#=  
_`SD G5  
带内容的标签 Kz;Ar&^`N  
doStartTag, doEndTag, release }C @xl9S"  
- egTZW-  
带内容的标签,且内容重复循环 eztK`_n  
doStartTag, doAfterBody, doEndTag, release 4(htdn6\  
{e&fBX6;  
带内容的标签,且内容与JSP交互 |r+ x/,2-  
doStartTag, doEndTag, release, doInitBody, doAfterBody, release DQ0S]:tC  
?sHZeWZ(  
一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。 \8#[AD*@s2  
Cj#wY  
如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。 E#P#{_BR^  
{EZR}N  
一般情况都将所有的tag处理类打成了JAR的包,以便于发布。 mZU L}[xf  
|~A*?6:@  
% (h6m${j  
Tag库描述(简称TLD) oJM; CN  
3\Amj}RJ  
-$!r+4|q  
Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。 uyEk1)HC  
y3j$?o M  
TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。 Pac ^=|h<q  
[`tOhL  
一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如: Sck!w 3  
DvhF CA}z  
<?xml version="1.0" encoding="ISO-8859-1" ?> to13&#o  
M"]?'TMfXc  
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> zji9\  
TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表: O4`.ohAZ  
MNU7OX<  
QH><! sa  
<taglib>的子元素 !=30s;-  
ecm+33C  
Element |j"C52Q  
Description 7r,GdP.  
8]&Fu3M^  
tlib-version H`<u2fo|p  
Tag库的版本 ;|T|*0vY[  
I!F&8B+|  
jsp-version R:P),  
Tag库所需要的jsp的版本 !rgXB(  
&T-:`(  
short-name bZSt<cH3  
助记符,tag的一个别名(可选) dw#pObH|`  
h_X'O3r  
uri E>@]"O)=M,  
用于确定一个唯一的tag库 1grcCL q  
 l  
display-name /p;OZf]  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) H^*[TX=#[  
e]1) _;b*  
small-icon [)}`w;#  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) 6k')12~'  
Nba1!5:M  
large-icon GwgY{-|`  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) 6I~M8Lo ;  
Z>`frL  
description Y)8 Py1}  
对tag库的描述(可选) y[f%0*\B  
{2xc/   
listener 0I)eYksh  
参见下面listener元素 ko!]vHB9`  
Yk{4 3yw  
tag ! .Pbbs%  
参见下面tag 元素 |p/[sD+M  
sNG 7fi.|  
Listener元素 }q_Iep  
4D.h~X4  
一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。 iMYJVB=  
/.mx\_$   
Tag元素 L$Xkx03lz>  
$W;r S7b  
每个tag元素在tag库中都要指出它的名字、类名、脚本变量、tag的属性。其中脚本变量的值可以直接在TLD中定义或通过tag附加信息的类来取得。每个属性描述了这个属性是否可以省略,它的值是否可以通过<%= …%>这样的JSP语法来获得,以及属性的类型。 W)2k>cS  
nKwOSGPQt  
每一个tag在TLD中对应一个tag元素,下表是tag元素的子元素: )WkN 34Q  
=?M{B1;H  
Tag元素的子元素 6[Mu3.T  
Fyz1LOH[X  
元素名称 NljcHe}Qy  
描述 o -x=/b  
9$sx+=(  
name I Yr4  
独一无二的元素名 TY+Rol;!  
>U:.5Tch'V  
tag-class /jc; 2  
Tag标签对应的tag处理类 KWVl7Kw#e  
qpB8ujj<V  
tei-class /u'V>=D;f  
javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选) '8^>Z.~V  
CTB qX  
body-content 7?Twhs.O  
Tag标签body的类型 |'k7 ;UW  
St3/mDtH  
display-name Cj)*JZV G  
被可视化工具(诸如Jbuilder)用来显示的名称(可选) 9Kc;]2m  
F{17K$y  
small-icon `g'9)Xf4KT  
被可视化工具(诸如Jbuilder)用来显示的小图标(可选) @vi;P ^1!  
%&$s0=+  
large-icon Vg`32nRN  
被可视化工具(诸如Jbuilder)用来显示的大图标(可选) d?GB#N|+g  
h],l`lT1\  
description 5F5)Bh  
此tag标签的描述 }@A{'q5y  
O=}jg0k  
variable @ ojV8  
提供脚本变量的信息(同tei-class)(可选) {@67'jL  
mm`yu$9gbP  
attribute ftqeiZ 2  
Tag标签的属性名 /s`8=+\9  
tb'O:/  
以下章节介绍对于不同类型的tag,如何具体地实现它们。 J+nUxF;EE  
Z2{G{]EV(  
tc<HA7vpt~  
简单的tag vy5SBiK  
?wj1t!83  
yex0rnQ|  
tag处理类 ^14a[ta/'  
,a@jg&Mb]  
简单的tag处理类必须实现Tag接口的doStartTag和doEndTag方法。当jsp引擎碰到tag标签的开头时,doStartTag被调用,因为简单的tag没有body,所以此方法将返回 SKIP_BODY。当jsp引擎碰到tag标签的结尾时,doEndTag被调用,如果余下的页面还要被计算,那它将返回EVAL_PAGE,否则将会返回SKIP_PAGE。 5l /EZ\q  
|D[4 G6&  
以下是例子:对于标签 <tt:simple /> ,它的tag处理类实现如下: K2oyHw<mk  
a*UxRi8  
FP h1}qS  
public SimpleTag extends TagSupport gY!#=?/S  
A:Kit_A  
{ =7%c*O <  
hT$/B|  
public int doStartTag() throws JspException ood,k{  
5| bc*iqU  
{ KFn[  
UZ 6:vmcT  
try{ J4^aD;j  
]^DNzqu=@h  
pageContext.getOut().print(“Hello.”); ;{K/W.R  
~BD 80s:f  
}catch(Exception e){ 0%GQXiy  
rh 7%<xb>  
throw new JspTagException(“SimpleTag: “ + e.getMessage()); ~"#[<d  
tFYo d#  
} tG(!d$^  
+OX:T) 4h6  
return SKIP_BODY; VF] ~J=>i  
H.]rH,8  
} rIZ^ix-N  
je^=gnq  
public int doEndTag() n0%]dKCB  
vSG$ 2g=  
{ >]S-a-|Bp  
8UN7(J  
return EVAL_PAGE; ya0D5 0m  
M*lCoJ  
} l5esx#([*R  
x72T5.  
} Q"=$.M~  
U%E364;F  
%Y*]eLT>  
注意:如果tag标签没有内容的话,那必须定义body-content元素为空,例如 ,f?+QV\T.  
LP- _i}Kq  
<body-content>empty</body-content> Cp.qL  
2 rx``,7Q  
-"MB(`  
带属性的tag标签
评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

无聊

灌水
级别: 终身会员
发帖
3743
铜板
8
人品值
493
贡献值
9
交易币
0
好评度
3746
信誉值
0
金币
0
所在楼道
只看该作者 1 发表于: 2007-01-01
tag处理类 -N~eb^3[c  
S<bsrS*$  
对于tag标签的每个属性,你必须依照JavaBeans规范来定义其属性,以及get和set方法。以struts的logic:present 标签为例, %RX}sS  
oQ"J>`',  
<logic:present parameter=”Clear”> IMtfi(Y%F  
1<TB{}b Z  
与此相应,此tag处理类应有如下方法和定义: deVbNg8gs  
)CM3v L {  
LOf)D7T  
protected String parameter = null; [+4/M3J%  
AIX?840V  
public String getParameter() dAkJ5\=*  
N^;rLrm*  
{ dD.;P=AP  
|\k,qVQ  
return this.parameter; t],5{UF  
Ti!<{>  
} 7;x}W-`iF  
nkii0YB!  
public void setParameter(String parameter) 1b4/  
{RPZq2Tpc  
{ j8#xNA  
*j"u~ N F  
this.parameter = parameter; |h(05Kbk  
Vnvfu!>(  
} I5mtr  
5nSi29C  
"-afHXED  
注意:如果你的属性名为id,而且你的tag处理类是从TagSupport类继承的,那你就不需要定义它的属性和set和get方法,因为他们早已在TagSupport被定义过了。 !5zDnv  
tX@G`Mr(  
Attribute元素 6Ud6F t6  
pf[m"t6G~  
对于tag标签的每个属性,你必须定义它是否必须的,它的值是否可以用诸如<%= …%>的表达式来获得,以及它的类型(可选),如果不指定它的类型,那就默认为是java.lang.String类型。如果rtexprvalue元素被定义为true或yes,那么在type元素中就定义了attribute的返回类型。 Oi-= Fp  
PRQEk.C  
<attribute> OuuN~yC  
ILyI%DA&  
<name>attr1</name> SL ) ope  
wJ Qm7n-+  
<required>true|false|yes|no</required> yh:Wg$qx  
QuWW a|g^.  
<rtexprvalue>true|false|yes|no</rtexprvalue> y13Y,cz~B  
o<Y[GW1pg  
<type>attribute的返回类型(只用当rtexprvalue为真是才有效)</type> WkUV)/j  
iPeW;=-2Wk  
</attribute> &V77Wn OY  
+]dh`8*8>1  
如果tag的某个属性不是必须的,那tag处理类会自动提供一个缺省值。 4Mck/i2  
CEHtr90P  
例如,在logic:present这个tag标签中定义了一个属性叫parameter,但它不是必须的,而且它可以被诸如<%= …%>的表达式来赋值。 4157!w'\y  
(N[R`LN  
<tag> -.!+i8d>  
##r9/`A  
<name>present</name> MR3\7D+9y  
4];<` %  
<tag-class>org.apache.struts.taglib.logic.PresentTag</tag-class> zz* *HwRt  
&@[pJ2  
<body-content>JSP</body-content> gUWW}*\ U  
UVlh7wjg  
e]DuV)k&  
] =*G[  
<attribute> 6tZ ak1=V  
dng^#|X)?  
<name>parameter</name> f(UB$^4  
v9 *WM3  
<required>false</required> tTE]j-uT  
U~I y),5  
<rtexprvalue>true</rtexprvalue> W87kE?,  
G<M9 6V  
</attribute> ;FnU[Q`M#L  
>QSlH]M  
k3CHv=U{  
<IO@Qj1*  
</tag> Iq@&?,W  
D5"Xjo*  
rd1EA|T  
属性元素的校验 iiLDl  
V~MyX&`  
?M B Od9  
有关于tag标签的有效值可以从tag库的说明文档中获得,当JSP页面被编译时,jsp引擎会强制性地参照TLD中定义的规则进行检查。 ":!1gC  
6Wk9"?+1  
还有一个方法也可以进行属性元素的校验,就是先继承类TagExtraInfo,然后调用它的isValid方法。这个类同时也起到提供tag中定义的脚本变量信息的作用。 nq qqP  
jp880}  
IsValid方法通过TagData对象来传递属性信息,它包括着tag的所有的属性名-值的信息。由于校验发生在运行时刻,因此这个属性的值将被赋值为TagData.REQUEST_TIME_VALUE。 I_5[-9  
*-X`^R  
例如tag标签<tt:twa attr1=”value1” />在TLD中定义如下: Aaug0X  
K^e4w`F|  
<attribute> 9Ecc~'f  
ok1-`c P  
<name>attr1</name> Vy7 )_D  
oer3DD(  
<required>true</required>  N<~LgH  
)(+q~KA}  
<rtexprvalue>true</rtexprvalue> xV"~?vD  
nhy:5eSK  
</attribute> :"'*1S*  
}CM#jN?(  
KM9H<;A  
这个定义说明了attr1能在运行期间被赋值。 1vinO!  
t1ers> h  
以下的isValid方法检查attr1属性的值是否属于Boolean类型。注意由于attr1能在运行刻被赋值,那么isValid方法必须检查tag用户是否对此tag进行了运行时刻赋值。 "2ZuI; w  
a7sX*5t{R  
} 8[  
Public class TwaTEI extends TagExtraInfo &2r[4  
49=L9:  
{ )Lg~2]'?j  
Q})&c.L  
public boolean isValid(Tagdata data) ',!>9Dj  
Ym?VF{e,  
{ 5a|{ytP   
Uf9L*Z'6il  
Object o = data.getAttribute(“attr1”); afE8Kqa:H  
{7Hc00FM  
If(o != null && o != TagData.REQUEST_TIME_VALUE) D*'sOB(  
5DJ!:QY!  
{  \|C*b<  
 0:$pJtx"  
if( ( (String)o).toLowerCase().equals(“true”) || $!^C|,CS  
3Xm> 3  
((String)o).toLowerCase().equals(“false”) ) Z|xgZG{  
U+[h^M$U  
return true; C(vQR~_  
vs@u*4.Ut<  
else k\Y*tY#2  
Y*sw;2Z;a  
return false; Bh7hF?c Sj  
9W&nAr  
} HGF&'@dn  
Sa@T#%oU  
else Ymf@r?F<  
\f7R^;`_<R  
return true; o%*C7bU  
Zr(eH2}0D  
} vy-q<6T}:p  
bX 6uGu 7  
} lUdk^7:M  
`6(Zc"/ \m  
F`1J&S;C  
带body的tag }*S`1IWMj  
_na/&J 6  
_ jH./ @G  
tag处理类 _{n4jdw%(  
FiSx"o  
53>(2 _/[r  
如果tag标签含有内容,那处理方式会略微有些不同,而且还要视tag处理类是否要与body交互的情况而定。如果要与body交互,那我们认为tag处理类要可能要对body进行操作。 7~);,#[ky  
#Jt1AV  
Tag处理类不与body交互 K"ly\$F  
5n1`$T.WG  
如果tag处理类不与body交互,tag处理类应该实现Tag接口或从TagSupport中派生,如果body要被计算,那么doStartTag方法应返回 EVAL_BODY_INCLUDE,否则应返回SKIP_BODY。 n2|@Hz_  
^Jw=5 ImG  
如果tag处理类要对body反复运算,则它应该实现IterationTag或从TagSupport中派生。如果tag处理类认为body还未计算完的话,那它的doStartTag方法和doAfterBody方法必须返回EVAL_BODY_AGAIN。 v]rbm}uU9  
]x(6^:D5  
Tag处理类与body交互 ^^< C9  
WVz2 bzj  
如果tag处理类与body交互,那tag处理类应实现BodyTag接口或从BodyTagSupport中派生。这种tag处理类一般要实现doInitBody和doAfterBody方法。 [("2=Uz;  
FL4BdJ\  
Body允许一些方法来读写它的内容。Tag处理类可以调用body内容的getString或getReader方法来从body中提取信息,也可用 writeOut(out) 方法来将body的内容写入到out对象中。其中out对象通过tag处理类的getPreviousOut方法来获得。 (?ULp{VPFl  
Z?'?|vM  
如果body的内容需要被计算,那么doStartTag方法必须返回EVAL_BODY_BUFFERED,否则,它将返回 SKIP_BODY。 3!%-O:!  
PPh<9$1\g  
doInitBody 方法 U.h2 (-p  
rjj_]1?K  
此方法在body内容已经设好,但未被计算之前被调用。你可以根据不同的body内容来制定初始化策略。 ;j qF:Wl@  
&[SFl{fx>-  
doAfterBody方法 \.>7w 1p  
lM#,i\8Q  
此方法在body内容已被计算后进行调用。 &%g$Bi,G  
I8c:U2D  
和doStartTag方法一样,doAfterBody方法返回一个指示符指示是否要继续计算body,如果要继续计算,则doAfterBody应返回EVAL_BODY_BUFFERED,否则,它应返回SKIP_BODY。 `jyyRwSoe  
0|C !n+OK  
release 方法 F_I!qcEQ  
lnK  
tag处理类调用此方法将它的状态重置为初始状态,并释放所有的私有资源。 2R,8q0qR:  
]{|lGtK %  
apt$e$g  
以下的例子读取body的内容(其中含有一条sql语句),然后将它传递给一个对象,让它进行查询。由于此处body不须重新计算,所以doAfterBody会返回SKIP_BODY。 u,{R,hTDS  
gXU(0(Gq  
s0:M'wA  
Public class QueryTag extends BodyTagSupport Ep:hObWG)  
[lVfhXc&  
{ y%x:~.  
;?q}98-2  
public int doAfterBody() throws JspTagException FnI}N;"  
8aKS=(Z!j  
{ 7WY~v2SDF  
wLb:FB2  
BodyContent bc = getBodyContent(); |=KzQY|u  
a)c;z@r  
//将body的内容以字符串的格式提取出来 2.=u '  
Ul6|LTY  
String query = bc.getString(); [h !i{QD  
J*Ie# :J]  
//清除body N%ccy?B  
)WW*X6[k  
bc.clearBody(); w w[|| =  
VW*?(,#j{  
try{ sINf/mv+  
uqU&k@  
Statement stmt = connection.createStatement(); OU}eTc(FeC  
>B=s+ }/ME  
Result result = stmt.executeQuery(query); #sBL E  
jSH.e?  
}catch(SQLException e){ gat;Er  
d:>'c=y  
throw new JspTagException(“queryTag: “ + e.getMessage() ); -iY-rzW  
\13Q>iAu  
return SKIP_BODY; >;R`Q9s7  
=wW M\f`=  
} z^jmf_  
IR$d?\O3  
} H V-;? 5  
t'0&n3  
LI25VDZ|iP  
body-content元素 ,4`Vl<6  
'+ZJf&Ox  
4b((,u$  
由于tag可能会有body,你必须用body-content元素来指定body内容的类型: *o\AP([@  
!Ur.b @ke  
<body-content>JSP|tagdependent</body-content> <DPRQhNW]  
&4sz:y4T>  
F?"Gln~;  
如果body的内容是定制的或内部的tag、脚本元素、或HTML广本,则归类为JSP类型。其他的类型,比如上面代码所述的?D?D将sql statement类传给 query tag的这种类型应该标为tagdependent。 r@]`#PL  
o|vL:| 8Q  
注意:实际上body-content的值并不影响tag处理类对body内容的处理,它仅仅是被tag编辑工具用来描述此body的内容。 hkm}oYW+  
= $^90Q,Z;  
!g6=/9  
用tags定义脚本变量 /W-ges  
0^nF : F  
uDkX{<_Xe  
tag处理类 O cPgw/ I  
7FyE?  
9-q> W  
tag处理类负责创建或设置页面中定义的脚本变量,用pageContext.setAttribute(name,value,scope)或pageContext.setAttribute(name,value)方法来实现。一般来说,tag处理类通过脚本变量的名称来获取它,脚本变量的名称一般可用get方法来获得。 reArXmU<u  
?u?mSO/  
如果脚本变量的值依赖于tag处理类中的上下文中某一对象,那它可用pageContext.getAttribute(name,scope)方法来找到那个对象。一般的处理过程是tag处理类先找到脚本变量,再对其进行处理,然后用pageContext.setAttribute(name,object)的方法来设置它的新值。 ]!P8{xmb@  
4)k-gKS*  
对象的生存周期(scope)如下表: :_:)S  
OIpT9  
对象的生存周期表 B8"c+<b  
>o{JG(Rn  
名字 !.q99DB  
可访问范围 |<,0*2  
生存周期 3.hFYA w  
@_$$'XA7  
page ot2zY dWAz  
当前页面 WFV'^-4  
一直有效,除非页面向客户提交响应或重定向到一个新页面 X$1YvYsID  
nK+ke)'Zv=  
request u/S>*E  
当前页面或当前页面重定向到的页面 U{Oo@ztT  
一直有效,除非页面向客户提交响应 dI%ho<zm]  
vY|YqWt  
session Sw"h!\c`  
当前页面或在同一浏览器窗口中的页面 ?E+f<jol  
一直有效,除非关闭当前浏览器、超时、网络故障 Y/I)ECm  
1 hFh F^  
application mIDVN  
整个web应用程序的所有请求 Iy4%,8C]g  
一直有效,除非发生网络故障、服务器故障 tJ6Q7 J;n  
#}@8(>T  
提供关于脚本变量的信息 Cd=$XJ-b  
P7,g^:$  
以下示例定义了一个名为“book”的脚本变量,用来访问程序中关于书的信息: GiM-8y~  
l4r >#n\yj  
<bean:define id=”book” name=”bookDB” property=”bookDetails” type=”database.BookDetails” /> X<Cf y  
SpU|Q1Q/h  
<font color=”red” size=”+2” > rs@,<DV)u  
LB1.N!q1  
<%= messages.getString(“CartRemoved”) %> 9-+6Ed^2  
46'EZ@#s  
<strong><jsp:getProperty name=”book” property=”title” /></strong> p&F=<<C  
47"ERfP  
</font> " [=Ee[/  
V%pdXM5  
当包含此tag的JSP页面被编译时,jsp引擎会自动生成关于此book的同步的代码(同步可以避免几个客户同时访问此book时造成的冲突),要生成同步代码,jsp引擎需要知道此脚本变量的如下信息: G}<q  
%D z|p]49!  
· 脚本变量名称 31|Vb  
{y|y68y0+  
· 脚本变量所属的类 S ~lw5  
7581G$@ym  
· 此脚本变量是否引用了一个新的或已存在的对象 m=2TzLVv  
/^ v4[]  
· 此脚本变量的有效性 {M]m cRB(  
>Lanuv)O  
有两种办法可以向jsp引擎提供关于脚本变量的信息:在TLD中定义variable子元素,或用tei-class子元素定义一个额外tag信息类。用variable最简单,但可能降低了一些灵活性。 ru)%0Cyx  
&^th KXEC  
Variable元素 EOV<|WF>  
0[0</"K%1m  
Variable元素有如下子元素: ^HKxaW9W  
&adKKYN  
· name-given ?D?D 给出的名字,是一个常量 Gq;0j:?CC  
<;x+ ?j  
· name-from-attribute?D?D 属性名,在编译时给出的属性名 hNFMuv  
(@`+Le  
name-given或name-from-attribute两者必须选一,但以下子元素是可选的: $cH'9W}3K  
8T 6jM+ h  
· variable-class?D?D变量的类型,缺省为java.lang.String。 3}$L4U  
ltHC+8 aZ  
· declare?D?D此脚本变量是否引用了一个新对象,缺省为True。 udg;jR-^  
0;OpT0  
· scope?D?D脚本变量的范围,缺省为NESTED。下表描述了scope的几种类型: f7XmVCz1  
p`{9kH1me  
脚本变量的有效范围 D?]aYCT  
hGF:D#jyT  
lXm]1 *<  
有效性 33couAP#  
方法 }?>30+42:  
}(J6zo9(x  
NESTED 1S\q\kz->D  
在tag标签的开始和结束之间 \u,hS*v0  
如果tag处理类实现BodyTag接口,则在doInitBody和doAfterBody中调用,否则在doStartTag中调用 uZId.+Rk  
eUqsvF}l!  
AT_BEGIN &cDnZ3Q;  
从tag标签的开始一直到页面结束 H"I|dK:  
如果tag处理类实现BodyTag接口,则在doInitBody、doAfterBody和doEndTag中调用,否则在doStartTag和doEndTag中调用 u9m"{KnV  
<H)h+?&~d  
AT_END k$o6~u 2&  
从tag标签的结束一直到页面结束 [m!\ZK  
在doEndTag中调用 kvSSz%R~  
05nG |  
以struts为例,它的bean:define标签的实现遵循JSP1.1规范,此规范要求使用额外tag信息类来定义脚本变量。Variable元素是JSP1.2规范中加入的。以bean:define标签为例,你可以定义如下variable元素: ? _[gs/i}  
GS$OrUA  
<tag> XXmtpM8  
Aye!@RjM8  
<variable> p%J,af  
)R{4"&&2  
<name-from-attribute>id</name-from-attribute> s<z{(a  
4jis\W}%L3  
<variable-class>database.BookDetails</variable-class> if:2sS9r  
u&bo32fc  
<declare>true</declare> 3,tKqR7g  
u-j$4\'  
<scope>AT_BEGIN</scope> tb&{[|O^  
Fg5c;sls  
</variable> ^b;.zhp8;N  
-YHlVz  
</tag> ,/:#=TuYm  
l $d4g?Z  
额外tag信息类 <JYV G9s}  
 ;{BELv-4  
如果要定义一个额外tag信息类,你要继承javax.servlet.jsp.TagExtraInfo类。一个TagExtraInfo类必须实现getVariableInfo方法,此方法返回一个叫VariableInfo的数组类,它包括如下信息: 2={`g/WeE  
u;~/B[  
· 变量名 sEe^:aSN  
<J{VTk ~  
· 变量所属类名 T\8|Q @  
,+,""t  
· 此变量是否引用了一个新对象 49_b)K.tB  
] 2FS=  
· 此变量的有效范围 "]5]"F4]  
hRxR2  
jsp引擎将一个名为data的参数传给getVariableInfo方法,data中包括tag标签中的所有“属性名?D?D属性值”对。它可以用来向VariableInfo对象提供脚本变量的名字和类名。 )"A+T&  
E n{vCN  
以struts为例,它在bean:define标签中定义了一个名为DefineTei的额外tag信息类,用来向脚本变量提供信息。由于脚本变量的名称(book)和类名(database.BookDetails)是通过tag标签的属性来传递的,它们一般定义在VariableInfo的构建代码中,并且可用data.getAttributeString方法来得到这些信息。如果要允许book脚本变量能在从tag开始直到整个JSP页面结束的范围内都可用的话,那它的范围应设为AT_BEGIN。如下所示: eNu `\  
0l^-[jK)  
Sxjwqqv  
public class DefineTei extends TagExtraInfo rt!5Tl+v  
FB6`2E%o  
{ ~+QfP:G  
mWUQF"q8  
public VariableInfo[] getVariableInfo(TagData data) yWF DGk  
M*8Ef^-U`t  
{ /S\P=lcb  
=|pQA~UU#  
String type = data.getAttributeString(“type”); GvF~h0wMt  
J03yFT,dF  
If( type == null) ,V.X-`Y  
y&-j NOKLM  
type = “java.lang.Object”; e<9IwS!/  
#r#UO  
return new VariableInfo[] { +<|6y46  
vUvIZa  
new VariableInfo(data.getAttributeString(“id”), 6*GY%~JbD  
fOdkzD,  
type, c'vxT<8fWW  
wbyY?tH  
true, ZXY5Xvt:v  
"<Dn%r  
VariableInfo.AT_BEGIN) l|/h4BJ'  
B-@6m  
}; Tu?+pz`h  
SWN i@  
} |ITp$  _S  
4askQV &hj  
} " 2Dz5L1v  
<IC=x(T  
S1E =E5  
注意:关于额外tag信息类的类名必须要在TLD中的tag标签下的tei-class子元素中定义。因此,DefineTei的tei-class中的定义看起来如下: kn^RS1m  
<tei-class> +%OINMo.A  
org.apache.struts.taglib.bean.DefineTagTei O={4 >>F  
</tei-class> \3-XXq  
E3X:{h/  
'nz;|6uC  
具有协作关系的tag &BY%<h0c  
V}. uF,>V  
d(3F:dbk  
tag通过共享对象来进行协作,JSP技术支持2种方式的对象共享。 AE={P*g  
8V`NQS$  
第一种方法是使用pageContext对象进行对象的共享(可支持JSP页面和tag处理类之间的共享),如果在一个tag处理类中要调用由另一个tag处理类创建的对象,可调用pageContext.getAttribute(name, scope)方法。 9TIyY`2!  
h3Nwxj~E  
第二各方式的共享是对于tag之间有嵌套关系而言的,外层的tag所创建的对象对于内层的tag来说是可以共用的。这种形式的共享的好处是减少了可能存在的重名冲突。 @{iws@.  
j6%X  
要访问一个嵌套tag创建的对象,tag处理类必须先找到此嵌套tag对象,可用TagSupport的静态方法 TagSupport.findAncestorWithClass(from, class)或TagSupport.getParent方法。前者在当不确定此tag是否为嵌套tag对象时使用。一旦它的父类被找到,它就能访问其所有动态或静态创建的对象。静态创建的对象是父类的成员,而动态创建的对象可能是父类的私有对象。诸如此类的对象可以用tag处理类的setValue方法来保存,用getValue方法来获得。 5bYU(]  
&=Gz[1 L  
下例阐述了以上两种共享对象的方法。在这个例子当中,一个查询tag检查一个名为connection的属性名是否在doStartTag中被设置。如果connection属性被设置,tag处理类从pageContext中得到这个connection对象。否则,此tag处理类先找到它的父tag处理类,然后从它的父tag处理类中找到connection对象。 >XcbNZV  
"o 2p|2c  
GpMKOjVm|  
public class QueryTag extends BodyTagSupport `MA ee8u'  
X/ gIH/  
{ gbsRf&4h  
y>Zvose  
private String connectionId; e6z;;C@'G  
lM86 *g 'l  
public int doStartTag() throws JspException K_{f6c<  
4v_?i @,L  
{ m2E$[g  
F l83 Z>  
String cid = getConnection(); / *RDy!m  
7g[m,48{  
if(cid != null) >6*"g{/  
}zY)H9J~  
{ #s$b\"4  
1P#bR`I >  
//存在一个connection id,使用它。 7F5 t&  
e^&QT  
connection = (Connection) pageContext.getAttribute(cid); 'Y IFHn$!  
M$DJ$G|Z  
} RrSSAoz1  
x%23oPM  
else :y==O4  
]sjYxe  
{ ^m;dEe&@F  
` wuA}v3!  
ConnectionTag ancestorTag = (ConnectionTag)findAncestorWithClass(this, \{AxDk{z#  
M>D 3NY[,  
ConnectionTag.class); |RDmY!9&  
T)&J}^j  
if(ancestorTag == null) 2.u d P  
a% |[m,FvP  
{ '@>FtF[Gu  
Rp `JF}~o  
throw new JspTagException(“一个没有connection属性的查询标签必须被一个connection标记嵌套。”); ?v-IN  
7F;"=DarOE  
} bN$`&fC0  
)67_yHW  
connection = ancestorTag.getConnection(); A ${b]  
*vc=>AEc  
} F`S OF O  
5 WSu  
} /ZqBO*]  
zWoPa,  
} [_hHZMTH  
@qmONQ eb  
TU&6\]yF_  
S8*VjG?T\  
此查询标签在JSP页面中的调用形式可以从以下2种定义中任选一种: ("0@_05OH  
`*cT79  
CB<1]Z  
<tt:connection id=”con01” ...> ... </tt:connection> ZKzXSI4  
:*gYzk8  
<tt:query id=”balances” connection=”con01” > aehGT|  
m(>_C~rGN  
SELECT account, balance FROM acct_table Xt~`EN  
4o8uWS{`  
where customer_num = <%= request.getCustno() %> 5W"nn  
qIcQPJn!}  
</tt:query> i#$9>X  
-FytkM^]6  
+ 5H9mk  
u +q}9  
8:;_MBt  
<tt:connection ...> }$!bD  
mE(EyB<  
<x:query id=”balances”> z"*X/T  
Gc>bli<-  
SELECT account, balance FROM acct_table OLUQjvnU  
?#!Hm`\.  
where customer_num = <%= request.getCustno() %> hO(8v&ns3  
0h-holUf}~  
</x:query> biG=4?Xl  
Tl5K'3  
</tt:connection> sY+U$BYB>  
Kdh(vNB>  
TJ[C,ic=D  
与此同时,在TLD中必须指定connection属性为可选的,定义如下: Y,RED5]t  
v39`ct=e  
<tag> 9+"D8J7  
Q W#]i  
... r?Jxl<  
\s?OvqI:  
<attribute> V2sWcV?  
!Rk1q&U5  
<name>connection</name> y ,isK  
`l@[8H%aw  
<required>false</required> "r @RDw   
r/1:!Vu(  
</attribute> gS4zX>rqe  
fiz2544  
</tag>
描述
快速回复

您目前还是游客,请 登录注册
如果您提交过一次失败了,可以用”恢复数据”来恢复帖子内容
认证码:
验证问题:
10+5=?,请输入中文答案:十五