第十五章 使用定义标签

翻译 2006年05月25日 11:43:00

这是我考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):

算法导论 第二十五章:每对顶点间的最短路径

Floyd-Warshall 算法    设G的顶点为V={1,2,...,n},对于每个k考虑顶点的一个子集{1,2,...,k}。对于任意一对顶点i,j ∈ V,考察 从i到 j 且中间顶点皆属...
  • u010183397
  • u010183397
  • 2015年07月21日 00:49
  • 537

算法导论习题解-第15章动态规划

#a is topological sorted, a[0] is s, a[-1] is t def longest(a): #d[i] is the longest distance fr...
  • groovy2007
  • groovy2007
  • 2014年06月13日 16:11
  • 4221

自定义Spring配置标签

在Sping中,一般使用这样的元素来配置一个bean
  • bingduanlbd
  • bingduanlbd
  • 2014年08月23日 02:36
  • 14825

【自定义标签开发】05-开发带属性的标签

我们之前了解了传统标签开发和简单标签开发,但是我们开发的标签都是没有属性的标签,我们接下来里了解一下带属性的标签的开发。 开发带属性的标签: 自定义标签可以定义一个或多个属性,这样,在JSP页面中应用...
  • u013517797
  • u013517797
  • 2016年04月11日 09:09
  • 813

HTML框架标签的使用-<frameset>

frameset框架的使用-使用frameset框架进行布局
  • HYM1987
  • HYM1987
  • 2014年04月30日 22:27
  • 1456

django-模板标签的使用

{% if %} 标签不允许在同一个标签中同时使用 and 和 or ,因为逻辑上可能模糊的,例如,如下示例是错误的: {% if athlete_list and coach_list o...
  • list_Lee
  • list_Lee
  • 2016年04月18日 09:08
  • 1678

Spring 自定义标签

自定义标签,用来实现定义Bean的作用范围线程独立,每个线程产生自己的实例对象 对象类 public class Model { } 标签处理类 public class ThreadS...
  • difffate
  • difffate
  • 2017年04月07日 02:12
  • 524

关于jsp中的tablib标签的定义与使用

定义taglib: 如果要在taglib标签中使用到长度,需要定义taglib中的fn: 示例: 0}"> 编号 用户名 密码 操作 ...
  • qq_37203683
  • qq_37203683
  • 2017年04月05日 11:13
  • 166

Django 自定义模板标签(template_tags)究竟有什么用?

自定义模板标签,过滤器。英文翻译是Custom template tags and filters。custom filter自定义过滤器今天不在我的记录范围之内,以后用到再看官方文档也不迟。**问题...
  • weixin_36571185
  • weixin_36571185
  • 2017年07月03日 13:22
  • 842

jsp中c标签的详细使用

jsp中c标签的使用 核心标签库    它是JSTL中的核心库,为日常任务提供通用支持,如显示和设置变量、重复使用一组项目、测试条件和其他操作(如导入和重定向Web内容)。Core标签按功能可分为...
  • qq_25843323
  • qq_25843323
  • 2015年12月05日 15:58
  • 861
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:第十五章 使用定义标签
举报原因:
原因补充:

(最多只允许输入30个字)