Java for Web学习笔记(三五):自定义tag(3)TLDS和Tag Handler
来源:互联网 发布:华三交换机开启端口 编辑:程序博客网 时间:2024/06/01 08:59
JSTL的TLD
这是JSTL采用的方式。TLD(Tag Library Descriptor)描述tag和function,以及具体执行的java代码tag handler。Tag Handler是javax.servlet.jsp.tagext.Tag或javax.servlet.jsp.tagext.SimpleTag的实现。web容器使用TLD将jsp中的tag映射到执行的java代码。之前,我们一直在学习使用JSTL的tag,我们来看看这些TLD是怎么写的。C tag的TLD可以解开javax.servlet.jsp.jstl的jar包,位于/META-INF/c.tld。
整体描述
<?xml version="1.0" encoding="UTF-8" ?><!-- ... Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. ...--><taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <description>JSTL 1.2 core library</description> <display-name>JSTL core</display-name> <tlib-version>1.2</tlib-version> <short-name>c</short-name> <uri>http://java.sun.com/jsp/jstl/core</uri> ... ...</taglib>
这里是XML的标准声明,其中Schema在web-jsptaglibrary_2_1.xsd中定义,需要注意的是TLD文件是有严格的先后顺序。头五个根元素描述TLD的整体信息:
- <description>和<display-name>是可选的,用于在IDE中的XML工具显示,和真正的TLD内容没什么关系,可有多个,用于不同语言的显示。
- <icon>位于<display-name>之后<tlib-version>之前,也是可选的,实际没什么用途。
- <tlib-version>必须要提供,版本只能是数字,并用.分隔。
- <short-name>必选,给出推荐和缺省的tag前缀,不允许有空格,不允许数字或者下划线开头
- <uri>是可选,但应当给出。如果不提供,则在<jsp-config>(web.xml)中必须加入<taglib>来描述这个tag library,所以最好且应该提供。之前以及提过,这个链接不需要也通常不会真实存在的。
定义Validators和Listeners
接下来,我们看到:
<validator> <description> Provides core validation features for JSTL tags. </description> <validator-class> org.apache.taglibs.standard.tlv.JstlCoreTLV </validator-class> </validator>
在编译的时候使用javax.servlet.jsp.tagext.TagLibraryValidator类来验证,确保正确使用tag lib,如<c:param>的格式正确。validator复杂且很少在自定义tag中使用,略过。
紧接着的是Listeners,如ServletContextListener,HttpSessionListener,但是它的使用极为罕见,同样略过。
定义Tags
如何定义Tags是关键,一个TLD中可以定义多个tag,下面是c tag的第一个。为了方便阅读,我们将解析也放进里面。
<tag> <!-- 和taglib一样有0~n个<description>,<display-name>,<icon>,通常只需要<description> --> <description> Catches any Throwable that occurs in its body and optionally exposes it. </description> <!-- 定义tag名字为<c:catch>,c在之前的<short-name>中定义,catch在这里的<name>定义。 --> <name>catch</name> <!-- 定义这个tag的处理类(Tag或者SimpleTag的继承) --> <tag-class>org.apache.taglibs.standard.tag.common.core.CatchTag</tag-class> <!-- 例子中没有给出可选的<tei-class>,是javax.servlet.jsp.tagext.TagExtraInfo的继承,用于校验tag的属性,确保使用的正确。这个偶尔有定义,但不常见。在C tag中仅<c:import>和<c:forEach>提供了扩展信息类。 --> <!-- body-content支出tag的content内容:--> <!-- 1、empty:无content --> <!-- 2、scriptless:可以是template,EL,JSPtag,但不能是scriptlet或expressions --> <!-- 3、JSP:只要JSP允许的都可以(当然declaration例外) --> <!-- 4、tagdependent:由tag本身,而不是web容器来计算tag的内容,通常是其他语言,如SQL,XML,或者加密数据 --> <body-content>JSP</body-content> <!-- 0~N个<variable>,本例没有,实际上在JSTL TLDs中都没有。这是用来提供tag的结果的各种变量信息。什么是variable?我们通过pageContext.setAttribute/getAttribute设置或获取某个值,这就是变量。不通过variable,我们也可以通过EL来获取。如果提供了variable,我们除了EL外,还可以在java代码中使用这些变量。既然在JSP中,java代码不建议使用,在JSTL TLDs中都没有使用variable,一般而言,我们没必要使用。子参数依次包括:--> <!-- <description> --> <!-- <name-given> 变量的名字 --> <!-- <name-from-attribute> 决定变量名字的属性,这和<name-given>相互冲突,只能二选一。String,不能是EL等在运行时计算。 --> <!-- <variable-class> 变量的类型 --> <!-- <declare> true表示变量是新,需要声明;false表示已存在,只是修改值 --> <!-- <scope> 缺省是NESTED,即在tag内有效;AT_BEGIN表示变量tag内及之后有效;AT_END表示变量只在tag后有效,而tag内无效。 --> <!-- 0~N个<attribute>,定义Tag的属性--> <attribute> <!-- 先是<description>、<name> --> <description> Name of the exported scoped variable for the exception ...(略) </description> <name>var</name> <!-- required缺省是false,表示不强制要求 --> <required>false</required> <!-- rtexprvalue是runtime expression value:true表示允许EL这类运行时计算值,false则不允许,缺省为false。 --> <rtexprvalue>false</rtexprvalue> <!-- <type>表示属性的java类,缺省为Object --> <!-- <deferred-value>表明该属性是一个延迟计算的EL,tag的结果将通过javax.el.ValueExpression返回,通常会返回Object,也可以通过type来精确定义 --> <!-- <deferred-method>表明该属性是一个延迟计算的EL,tag的结果将通过javax.el.MethodExpression返回。一般而言在method()中执行,也可以通过<method-signature>中定义更为精确的signature --> <!-- <fragment>设置true时表示用jsp fragment,容器不进行计算,而是由handler进行计算。缺省值为false。如果使用fragment,可以通过<jsp:attribute>来设置,而非xml的属性,例子如下 --> <!-- <myTags:doSomething> --> <!-- <jsp:attribute name="someAttribute"> --> <!-- Any <b>content</b> <fmt:message key="including.jsp.tags" />. --> <!-- </jsp:attribute> --> <!-- </myTags:doSomething> --> </attribute> <!-- <dynamic-attributes>缺省值为false,如果设置为true,表示允许使用没有定义的属性。这通常在jsg tag的最终输出为html tag的情况,这时handler需要实现javax.servlet.jsp.tagext.DynamicAttributes。Spring的form tag lib就使用动态属性 --> <!-- 0~1个<example>,用于给出tag使用的示范案例 --> <!-- 0~n个<tag-extension>,提供给IDE的,对tag本身没有任何影响。 --></tag>
定义Tag文件
在TLDS中是可以使用0~n个tag文件,定义在tag后面,如下:
<tag-file> <!-- <description>、<display-name>和<icon>,其中description是必选 --> <description>This tag outputs bar.</description> <!-- name就是prefix之后的名字,和tag中一样 --> <name>foo</name> <!-- tag文件路径,web应用中的/WEB-INF/tags或者jar中的/META-INF/tags --> <path>/WEB-INF/tags/foo.tag</path> <!-- 最后是<example>和<tag-extension> --></tag-file>
如果我们将tag文件加入到jar中,就必须在TLD中定义;如果多个tag文件有相同的namespace,也需在TLD中定义。
定义Functions
c tag中没有functions定义的例子,但在fn tag中有,可以打开fn.tld来学习。下面是当中的例子:
<function> <!-- <description>, <display-name>, <icon>, <name>已经是老朋友了。 --> <description> Tests if an input string contains the specified substring. </description> <name>contains</name> <!-- 该function对应的公共类全名 --> <function-class>org.apache.taglibs.standard.functions.Functions</function-class> <!-- 该function在公共类中对应的公共静态方法 --> <function-signature>boolean contains(java.lang.String, java.lang.String)</function-signature> <!-- 接下来的<example>、<function-extension>和tag的<example>和<tag-extension>同义 --> <example> <!-- 这里是个不好的示例,我们应该写成<![CDATA[...]]> --> <c:if test="${fn:contains(name, searchString)}"> </example></function>
定义Tag library Extensions
<taglib-extension>和tag已经function中的extension一样,对tag或者container无实际作用,仅是支持IDE工具,我们不会使用到的。
相关链接: 我的Professional Java for Web Applications相关文章
- Java for Web学习笔记(三五):自定义tag(3)TLDS和Tag Handler
- Java for Web学习笔记(三六):自定义tag(4)自定义Tag文件
- Java for Web学习笔记(三四):自定义tag(2)Tag
- Java for Web学习笔记(三三):自定义tag(1)篇外:Method和Function
- Java for Web学习笔记(三七):自定义tag(5)自定义tld文件
- Java for Web学习笔记(三八):自定义tag(6)一些注意
- Java for Web学习笔记(二七):JSTL(3)Core Tag(中)
- Java for Web学习笔记(二六):JSTL(2)Core Tag(上)
- Java for Web学习笔记(二八):JSTL(4)Core Tag(下)
- Java for Web学习笔记(二九):JSTL(5)FMT Tag(上)
- Java for Web学习笔记(三十):JSTL(6)FMT Tag(下)
- Java for Web学习笔记(十二):JSP(2)Tag:directive,declaration,scriptlet,expression
- Java for Web学习笔记(十四):JSP(4)JSP Tag
- Java for Web学习笔记(三一):JSTL(7)SQL Tag
- Java for Web学习笔记(三二):JSTL(8)XML Tag
- Java for Web学习笔记(六四):Controller替代Servlet(6)Spring Form Tag
- 自定义标签(tag)
- JSP自定义标签(tag)
- 257. Binary Tree Paths
- CC2650DK平台下安装iar7.8及ble_stack_v2.2
- 地图应用之 :获取当前位置的经纬度
- Linux下安装、配置、启动Apache
- 2张图理解resnet核心思想
- Java for Web学习笔记(三五):自定义tag(3)TLDS和Tag Handler
- Mysql各个版本区别及官网下载
- 发送邮件
- eclipse配置tomcat问题
- codeforces 779 E. Bitwise Formula
- 摩拜CEO胡炜炜 一席 演讲中的 点亮北京,深圳骑行动态,地图技术实现
- MongoDB 分片
- 二叉树算法
- 九阳真经 基础心法