标准的JSP 标记可以调用JavaBeans组件或者执行客户的请求,这大大降低了JSP开发的复杂度和维护量。JSP技术也允许你自定义taglib,其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。taglib通常定义在tag标签库中,这种标签库存放着你自己定义的tag标签。简而言之,如果使用taglib,那么你可以设计自己的JSP标记!
i3#'*7f%j yL6^\x 一般来说,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库或其它企业级的服务,诸如邮件和目录操作等等。自定义tag标签的使用者一般都是那些对java编程语言非常精通,而且对数据访问和企业级服务访问都非常熟悉的程序员,对于HTML设计者来说,使得他可以不去关注那些较复杂的商业逻辑,而将精力放在网页设计上。同时,它也将库开发者和库使用者进行合理分工,自定义tag标签将那些重复工作进行封装,从而大大提高了生产力,而且可以使得tag库可用于不同的项目中,完美地体现了软件复用的思想。
$.pTB(tO NmJ`?-Z 在这篇文章中,我们主要讨论:
OTj,O77k I,b9t\(6 · 什么是自定义tag标签?
*i^`Dw^~y h4_b!E@ · 怎么使用tag标签?
[)^mBVht GF8 -_X o 声明要使用的tag库
l
_+6=u hoenQ6N^: o 找到与之对应的tag处理类
XVt/qb%)r e+. \pe\ o tag标签的类型
l4rMk^>> ldGojnS · 自定义tag标签
W^es;5 VPt9QL( o tag处理类
`5q
;ssu yEq#Dr o tag库描述
*^]~RhjB Tzzq#z&F o tag标签示例
Ytao"R/ aBhV3Fd[B o 带属性的tag
`9Yn0B. UZGDdP o 带body的tag
S,''>`w 5{d\uE%'p o 定义了脚本变量的tag
%d1draL |t))u`~ o 具有协作关系的tag
*RWm47 /)EY2Y' · 自定义tag标签
EF#QH
_X 87V1#U ^ o 一个迭代tag的例子
\ECu5L4 {hQ6K)s o 一个模板tag库
I9Eu', ye%iDdf o tag处理类到底是怎样被调用的?
; Y"N6% pu+ur=5& d;7uFh|o 什么是自定义的tag?
"0CjP+1k #]E(N~ 一个自定义的tag标签是用户定义的一种JSP标记。当一个含有自定义的tag标签的JSP页面被jsp引擎编译成servlet时,tag标签被转化成了对一个称为tag处理类的对象进行的操作。于是当JSP页面被jsp引擎转化为servlet后,实际上tag标签被转化成为了对tag处理类的操作。
Md,pDWb t{dSX?<nt 自定义tag标签有很多特色,诸如:
cK@jmGj+ &H||&Z[pk · 可以在JSP页面中自定义tag标签的属性
@?kM'*mrZM ,+`HQdq · 访问JSP页面中的所有对象
\(
)#e @F~LW6K · 可以动态地修改页面输出
CSTI?A"P e5?PkFV^a1 · 彼此这间可以相互通信。你可以先创建一个JavaBeans组件,然后在一个tag中调用此JavaBeans组件,同时可以在另一个tag中调用它。
usFfMF X B=Ym x2A9] · tag允许相互嵌套,可以在一个JSP页面中完成一些复杂的交互。
uH@FU60 eq[Et
+ +nL+N 使用tag标签
\.uc06 G8Z 4J7^ ;eL9{eF 本节主要描述怎样在JSP页面中使用tag标签,以及tag标签的不同类型。
dRi5hC$ e@#kRklV& 要使用tag标签,JSP程序员必须做2件事:
lrWQOYf2 IA&L] · 声明此tag标签的tag库
ziE*'p #A7jyg": · 实现此tag标签
j;1 -p>z kc `V4b% 声明tag标签所在的tag库
R\|lt)h n5-)/R[z 如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明)
9BEFr/. '8 Ztj <%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %>
(ll*OVL +pm[f["C. uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。
)D&M2CUw"f v``-F(i$ TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。
U69u'G: fBn"kr; 以下taglib指示符直接引用一个TLD:
/u%h8!"R (-77[+2 <%@ taglib uri=”/WEB-INF/tutorial-template.tld” prefix=”tt” %>
Ny- [9S-< +!IQj0&'Y3 以下的taglib指示符通过一个逻辑名称间接地引用一个TLD:
@Ky> 9m{ '*^yAlgtt <%@ taglib uri=”/tutorial-template” prefix=”tt” %>
/iC;%r1L N==ZtKj F 如果是间接引用TLD的话,那你必须还要在web.xml中定义此逻辑名称与tld文件之间的映射,具体做法是在web.xml中加入一个名为taglib的元素:
/cr}N%HZB Ys+OB*8AE <taglib>
H5CR'Rp $?G"GQ!. <taglib-uri>/tutorial-template</taglib-uri>
g>rp@M l%ayI <taglib-location>
$rF=_D6 )tHaB, /WEB-INF/tutorial-template.tld
LVJI_ O{fH 7hW+T7u? </taglib-location>
._w8J"E5 =L|tp%! </taglib>
J_;N:7'p w%AcG~`j!B KlV:L 4a~ 实现此tag标签
aI(7nJ=R NcOPL\ o%{'UG 为了实现tag标签,你有2种方法来存放tag处理类。一、让tag处理类以.class的方式存放于当前应用的WEB-INF/class子目录下,二、如果tag处理类是以JAR包的形式存在的话,那可以放在当前应用的WEB-INF/lib目录下,如果tag处理类要在多个应用中共享,那么它就应放在jsp服务器上的common/lib目录下,对于tomcat来说,就是tomcat/common/lib目录下。
)n49lr6X :A
%^^F% <ljI;xE tag标签类型
%CwL:.| n% 'tKU\q Pi,QHb`> 自定义的tag标签遵循XML语法。它有一个开始标记和一个结束标记,有的还有body(即文本节点):
2kAx>R S{4z?Ri, ' <tt:tag>
uwf
5!Z:> Hs?e0Z=N body
E!BPE> 7]xm2CHx5 </tt:tag>
]M/9#mD9~ t^]$!H fkSO( C) 一个不带body的tag标签如下:
7cAXd#sI ^D^4
YJz <tt:tag />
-K,-h[o ]<(]u#g_d Y2B&go 简单的tag标签
_lzyMEdr LMi:%i%\ 一个没有body和属性的tag标签如下:
>Rvx[`|O!m g4`Kp;}&' <tt:simple />
UJ-?k&j, IK,|5] *Ar D|Iur W1f 带属性的tag标签
%75xr9yOP }i{sg# dzK{
Z 自定义标签可以有自己的属性。属性一般在开始标记中定义,语法为 attr=”value”。属性的作用相当于自定义标签的一个参数,它影响着tag处理类的行为。你可以在TLD中详细定义它。
`l2O?U -@ ~\x:<) 你可以用一个String常量给一个属性赋值,也可以通过表达式给它赋值,如<%= ...%>。以struts为例,它的logic:present标签就是用的String常量来给属性赋值:
Om{l>24i.\ x!\ONF5$ <loglic:present parameter = “Clear”>
n JPyM/p qE'9QQ>:b 而另一个标签logic:iterate是用表达式来给属性赋值:
7+x? "4 OD']: <logci:iterate collection=”<%= bookDB.getBooks() %>”
3@5=+z~CW G-9iowS/A id=”book” type=”database.BookDetails”>
r kiT1YTY e><5Pr) %| G"-%_E 带body的tag标签
Z3[S]jC zP6.xp3 一个自定义标签可以包含其它自定义标签、脚本变量、HTML标记或其它内容。
Vh}SCUof' -hC,e/+ 在下述例子中,此JSP页面使用了struts的logic:present标签,如果些标签定义了parameter=”Clear”的属性,则将清除购物车的内容,然后打印出一条信息:
Ra*e5 Y>jiXl?&
<logic:present parameter=”Clear”>
<~
J O
s2 WyP W* <% cart.clear(); %>
''\;z<v drsB/ <font color=”#ff0000” size=”+2”><strong>
<b/~.$a' 1-RIN}CSd 你选择了清除购物车!
r\nx= gm9mg*aM </strong></font>
+cU>k} v&Kqq!DE </logic:present>
1Bxmm# AkOO)0 K'#E3={tt 到底是用属性还是用body来传递信息?
;-UmY}MU t4?DpE 如上所述,我们既可以通过属性,也可以通过body来传递信息。但一般来说,比较简单的类型,如字符串或简单表达式最好采用属性来传递信息。
1:Si,d,wh };'\~g,1 XD"_Iq! 定义脚本变量的tag标签
02BuX]_0g {mB0rKVm 所谓脚本变量,是指JSP中可以调用的变量或对象。它可由tag标签产生。以下示例阐述了一个tag标签定义了一个名为tx的由JNDI所定义的事务处理对象。脚本变量可以是ejb对象、事务、数据库连接等等:
B c2p(z4 ah~YeJp <tt:lookup id=”tx” type=”UserTransaction” name=”java:comp/UserTransaction” />
d\|!Hg, ?`J[[", <% tx.begin(); %>
%kgkXc~6|x bTQNb!& ...
JmEj{K<3I G9JAcO1 ExRe:^yU\ 具有协作关系的tag标签
h;3cd0 trE{ FT 自定义tag标签之间可以通过共享对象来实现协作。在下述例子中,标签tag1创建了一个名为obj1的对象,在标签tag2仍可以重复使用obj。
vzmc}y G %u;~kP|S% <tt:tag1 attr1=”obj1” value1=”value” />
r_;9'#&' ^U]UqX` <tt:tag2 attr1=”obj1” />
.KdyJ6o XkyKBg- 在以下这个例子当中,如果外层的tag标签创建了一个对象,那么其内层的所有tag标签都可以使用这个对象。由于这样产生的对象没有一个指定的名字,那么就可以将少重名的冲突。这个例子阐述了一系列协作的嵌套对象。
U!Ek' qTQBt} <tt:outerTag>
"O(9 m.CZ d:yqj: <tt:innerTag />
|g*XK6 kY'T{Sm1^ </tt:outerTag>
M`S0u~#tI "+unS)M;Y I"KN"v^ Tag处理类
jMpD+Mb H<1WbM:w 6S~sVUL9` Tag处理类必须实现Tag接口或BodyTag接口,不过现在一般都流行从TagSupport或BodyTagSupport类中继承,这些类或接口都可以在javax.servlet.jsp.tagext包中找到。
V%Sy"IG VU@9@%TN 当JSP引擎看到自己的JSP页面中包含有tag标签时,它会调用doStartTag方法来处理tag标签的开头,调用doEndTag方法来处理tag标签的结束。
|<O9Sb_ t:fFU1x 下表说明不同类型的tag所需要不同的处理过程:
Q?X>E3=U @$T 9Ll Tag处理类的方法
tr7<]Hm: _2N$LLbg Tag标签类型
D1&A,2wO 所调用的方法
<\;#jF%V o;?/HE%,[ 基本标签
85GKymz$P doStartTag, doEndTag, release
(64yg r7',3V 带属性的标签
p ]d]QMu doStartTag, doEndTag, set/getAttribute1...N, release
~9j%Hm0ht -I=l8m6L 带内容的标签
!>1@HH?I\/ doStartTag, doEndTag, release
<qGu7y" y{N-+10z 带内容的标签,且内容重复循环
q&d~
\{J doStartTag, doAfterBody, doEndTag, release
6&/T@LQYrh RZ+`T+zL 带内容的标签,且内容与JSP交互
P+$:(I doStartTag, doEndTag, release, doInitBody, doAfterBody, release
o*J3C> )wNP(
@$L 一个tag处理类可以通过javax.servlet.jsp.PageContext来与JSP交互,通过javax.servlet.jsp.PageContext类,tag处理类可以访问JSP中的request、session和application对像。
H<3I 5Kgt 9V5-%Iv 如果tag标签是互相嵌套的,那内层的tag处理类可以通过它的parent属性来访问上层的tag处理类。
ooQQ-?"m NC38fiH_N 一般情况都将所有的tag处理类打成了JAR的包,以便于发布。
7.`fJf? db6mfxi 1/"WD?a Tag库描述(简称TLD)
I(XOE$3 h*v8#\b$J_ H*)NLp Tag库是用xml语言描述的,TLD包括了tag库中所有tag标签的描述,它一般用来被jsp服务器用来校验tag的语法正确性,或者被jsp开发者用来开发新的标签。
]9@F~) N ,z6y5Lu TLD的文件扩展名必须为.tld,而且必须放在当前WEB应用的WEB-INF目录或其子目录中。
>vA2A1WhW Jkek-m 一个TLD的内容的开头必须遵守标准的XML开头,用于描述DTD和xml的版本,例如:
gg8Uo G ghRVso( <?xml version="1.0" encoding="ISO-8859-1" ?>
F>rH^F e2A-;4?_ <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "
http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
,2W8=ON TLD必须以<taglib>来作为它的根元素,<taglib>的子元素如下表:
/3{b%0Aa hvaSH69*m 5;HH4?]p <taglib>的子元素
Gy(=706 |vw"[7_aS Element
/gG"v5] Description
)-._FOZ6 =&:Y6XP tlib-version
q*9!,!e Tag库的版本
=y-@AU8 $b mLu=9 jsp-version
,KFapz! Tag库所需要的jsp的版本
% oo2/aF V=*wKuB short-name
n<u
$=H 助记符,tag的一个别名(可选)
ZEx}$<)_ {Ja!~N;3 uri
PAM}*' 用于确定一个唯一的tag库
^RI?ybDd u`RI;KF~F display-name
tw9f%p 被可视化工具(诸如Jbuilder)用来显示的名称(可选)
$A-J,_:T< B]l)++~ small-icon
y9Us n8 被可视化工具(诸如Jbuilder)用来显示的小图标(可选)
_BP&n