第十五章 使用定义标签

这是我考WCD的读书笔记,翻译自一个study kit,并没有把所有内容都翻译,但也翻译大部分了,都是一些我觉得比较重要的内容,觉得对理解web开发相当有好处。5月27日就要考了,今天刚好复习到这部分,就先把他放上来。以后章节会陆续上传。

Tag handler: 它是实现了其中一个tag接口的java class.—Tag, IterationTag, BodyTag.

Tag library: 它是一个行为的集合,封装了一些在JSP页中被使用的功能.

Tag library descriptor: 当我们在JSP页面中使用自定义标签的时候,JSP引擎需要知道这些标签的的tag handler class在标签库的位置,以及如何使用他们. 这些meta-information被存储在一个叫做tag library descriptor的文件中.

 

三种URI:

Absolute URI:例如: http://localhost:8080/taglibs !!!!!!这时自定义的一个URI!!!!!!!!

Root Relative URI: ”/”开头,它被解释为web应用的文件目录的根目录的相对位置.例如: /taglib1/helloLib

Non-root Relative URI:不以”/”开头,它被解释为当前JSP页面或WEB-INF的相对位置,依赖于它被使用的位置.例如: taglib2/helloLib

 

如何使用已存在的标签库?

如何实现自定义的标签库?

 

在标准的JSP语法中这样使用标签库:

<%@ taglib prefix="test" uri="sampleLib.tld" %>

XML语法中这样使用标签库:

<jsp:root

xmlns:jsp="http://java.sun.com/JSP/Page"

xmlns:test="sampleLib.tld"

version="1.2" >

...JSP PAGE...

</jsp:root>

 

 

 

尽管把所有JSP页和TLD文件保存在同一目录下是最简单的使用taglib的做法,但是由两个不好的地方:安全和适应性.

首先是安全,访问者可以直接访问你的标签库的内容通过键入http://www.someserver.com/sampleLib.tld

当然,我们可以通过限制访问所有TLD文件的权限,但是,更好的做法是我们把TLD文件放在/WEB-INF目录下,使用/WEB-INF/sampleLib.tld访问他们.然而,我们还有适应性的问题.如果我们想改变标签库的版本,比如是sample_2.tld,我们就不得不手动修改所有受影响的JSP.更甚者,第三方自定义标签库通常被打包成JAR文件。这种情况下,我们怎样才能指定TLD文件的位置呢?

为了避免这个问题,JSP为指明标签库的位置提供了一个清晰的解决方法。JSP容器维护一个我们在taglib directive中使用的URI和实际TLD文件的物理路径之间的映射。取代页面相对路径,我们使用绝对的URI路径:

<%@ taglib prefix="test" uri=http://www.someserver.com/sampleLib

JSP引擎读到上面的URI,他会去它内部的映射寻找对应的TLD文件的位置。

因此,这就解决了安全和适应性的问题。实际上的TLD文件可以存储在WEB-INF目录下或者甚至是JAR文件中,对访问者隐藏。如果有一个新的标签库版本发布,我们需要做的只是更新在URI和实际路径中的映射。

 

在开发标签库的过程中,我们通常是把TLD文件保存在目录下,而不是JAR文件中.这会提高开发和测试的周期.然而,当我们开发完成了,我们会打包handler class 文件和标签库的TLD文件成为一个JAR文件.这个文件被配置到/web-inf/lib目录下.

JSP规范要求,当配置一个JAR文件的时候,TLD文件应该要么直接放在META-INF文件中,要么放在META-IN的子目录下.而且,TLD文件的文件明必须是taglib.tld.因此,JAR文件的结构应该是象这样的:

myPackage/myTagHandler1.class

myPackage/myTagHandler2.class

myPackage/myTagHandler3.class

META-INF/taglib.tld

 

JSP容器会识别两个位置作为TLD文件的路径,一个是目录,一个是JAR文件.这个路径叫做 TLD资源路径(TLD resource path.).

所有实际上的映射,就是一个URITLD文件的位置之间的映射.要么是包含TLD文件的目录,要么是包含TLD文件的JAR文件.这种映射叫taglib map.

 

三种方法关联URITLD文件位置:

1.容器会读取所有出现在部署描述器中用户定义的映射.这叫显映射(explicit mapping)

2.容器会读取所有出现在JAR文件中的taglib.tld文件.由于每个被打进包的TLD文件包含了关于自身URI的信息,JSP容器会自动为这个URI和当前JAR文件的位置创建一个映射.这叫隐映射(implicit mapping).

3.JSP容器会自动装载容器默认的URI.这些URIwell-known URI. http://java.sun.com/JSP/Page 就是一个well-known URI.

容器自己在它的标签库中提供了所有这些标签的实现实现.这实际上是隐映射的另一种形式.

 

显映射:

<taglib-uri>这是用户自定义的URI.可以是绝对URI,根相对URI,或是非根相对URI.

<taglib-location>这是TLD资源路径.它的值可以是根相对URI或非根相对URI,它必须指向一个有效的TLD资源路径(注意两个有区别!)

<taglib>

<taglib-uri>

http://www.manning.com/studyKit

</taglib-uri>

<taglib-location>

/myLibs/studyKit.tld

</taglib-location>

</taglib>

<!-- Taglib 2 -->

<taglib>

<taglib-uri>

http://www.manning.com/sampleLib

</taglib-uri>

<taglib-location>

yourLibs/sample.jar

</taglib-location>

</taglib>

 

JSP引擎解析JSP文件遇到taglib directive,他会检查taglib映射,看是否存在taglib directiveURI属性:

1.如果URI属性的值和任何一个<taglib-uir>实体匹配,引擎就会使用对应的<talib-location>的值去定位实际的TLD文件.

<1.如果<tldlib-location>的值是根目录相对URI(root-relative,/开头),JSP引擎就会认为它的URI位置是相对于web应用的文件根目录的(从应用文件根目录开始找).例如会这样找: <doc-root>/myLibs/studyKit.tld

<2.如果<taglib-location>的值是非根目录相对URI(not-root relative,不以/开头),JSP引擎会预先考虑/WEB-INF/下的URI,并认为它的位置是相对于web应用根目录的位置(也就是从WEB-INF开始找).例如:会这样找 <doc-root>/WEB-INF/yourLibs/studyKit.tld

2.如果没有匹配的<taglig-uri>实体,有以下三种可能性:

   <1.如果uri属性是一个绝对路径,在转化时会报告错误.

   <2.如果uri属性是一个根目录相对URI,他会被认为是相对于web应用的根目录的相对位置.

   <3.如果uri属性是一个非根目录相对URI,他会被认为是相对于当前的JSP页面的.因此,如果JSP文件<doc-root>/jsp/test.jsp包含了<%@ taglib prefix="test" uri="sample.tld" %>,引擎就会希望在<doc-root>/jsp/sample.tld查找到sample.tld文件.

 

 

考虑一个 没有在部署描述器中映射的URI:我们在JSP页中使用<%@ taglib uri="www.manning.com/hello.tld" prefix="a" %>会怎样?

---www.manning.com/hello.tld 这个URI没有包含协议(http),因此,它不是绝对URI.它不以/开头,因此它不是一个根目录相对URI.他是一个页面相对URI.当没有找到映射后,引擎就会在相对于当前页面的位置查找hello.tld文件.假设当前的JSP的位置是:C:/tomcat/webapps/test.jsp 那么引擎就会在这个位置中查找hello.tld文件:C:/tomcat/webapps/www.maning.com/hello.tld. 如果还找不到,那就报错.

 

其实,有映射和没有映射是很显然的.有映射的,uri的属性就能是随便什么东西都可以,因为是映射出来的.但是,如果是没有映射的,那么uri的属性就只能是一个tld文件了,因为引擎会真正的从这个uri所指示的位置去寻找tld文件!其中,应该认真区分路径的问题.

 

不能使用的前缀:jsp,jspx,java,javax,servlet,sun,sunw

4种标签的类型:

空标签(Empty tags):没有内容体. <prefix:tagName></prefix:tagName><prefix:tagName/> 相当有用的.

含有属性的标签(Tag with attribute):属性可以是表达式.标签库设计者应该在TLD文件中定义:a.一系列有效的属性名. b.属性是否是强制的. c.值的数据类型. d.属性的值被指明是在转化时使用字符串还是在请求时使用的表达式.

含有JSP代码的标签(Tag with JSP code):

含有嵌套的标签(Tag with nested tags):

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值