这是我考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语法中这样使用标签库:
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:test="sampleLib.tld"
version="1.2" >
...JSP PAGE...
尽管把所有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.).
所有实际上的映射,就是一个URI和TLD文件的位置之间的映射.要么是包含TLD文件的目录,要么是包含TLD文件的JAR文件.这种映射叫taglib map.
三种方法关联URI和TLD文件位置:
1.容器会读取所有出现在部署描述器中用户定义的映射.这叫显映射(explicit mapping)
2.容器会读取所有出现在JAR文件中的taglib.tld文件.由于每个被打进包的TLD文件包含了关于自身URI的信息,JSP容器会自动为这个URI和当前JAR文件的位置创建一个映射.这叫隐映射(implicit mapping).
3.JSP容器会自动装载容器默认的URI.这些URI叫well-known URI. http://java.sun.com/JSP/Page 就是一个well-known URI.
容器自己在它的标签库中提供了所有这些标签的实现实现.这实际上是隐映射的另一种形式.
显映射:
http://www.manning.com/studyKit
/myLibs/studyKit.tld
http://www.manning.com/sampleLib
yourLibs/sample.jar
当JSP引擎解析JSP文件遇到taglib directive时,他会检查taglib映射,看是否存在taglib directive的URI属性:
1.如果URI属性的值和任何一个
<1.如果
<2.如果
2.如果没有匹配的
<1.如果uri属性是一个绝对路径,在转化时会报告错误.
<2.如果uri属性是一个根目录相对URI,他会被认为是相对于web应用的根目录的相对位置.
<3.如果uri属性是一个非根目录相对URI,他会被认为是相对于当前的JSP页面的.因此,如果JSP文件
考虑一个 没有在部署描述器中映射的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):没有内容体.
含有属性的标签(Tag with attribute):属性可以是表达式.标签库设计者应该在TLD文件中定义:a.一系列有效的属性名. b.属性是否是强制的. c.值的数据类型. d.属性的值被指明是在转化时使用字符串还是在请求时使用的表达式.
含有JSP代码的标签(Tag with JSP code):
含有嵌套的标签(Tag with nested tags):