什么是定制的标签(Custom Tag)?
自定义标签(tag)是一种用户自定义的JSP语言元素,当容器将JSP转化成servlet时,Tag被转化成对Tag处理器的操作,在项目运行时,容器调用这些tag处理器操作。
自定义标签的特点
- 可以通过调用它的页面传递来的属性进行定制化
- 可以向调用它的页面传回变量
- 可以访问JSP页面可用的所有对象
- 可以互相通信
- 可以嵌套,并通过私有变量通信
创建tag处理器的方法
1)Tag Files
Tag Files用于开发展现为中心的自定义Tag,他的功能十分强大,使得快速开发和维护动态网页比以前更加容易,甚至可供不懂Java的页面编辑人员使用 ,就能开发出全新的动态网页。
2)Simple Tags
只能用于在属性值或tag体中不使用脚本的tag中
3)Classic Tags
只能用于在属性值或tag体中需要使用脚本的tag中
第一种方法通过使用tag文件实现jsp标签,后两者通过使用tld文件实现jsp标签,后面会详细介绍这两种文件。
一、 Tag Files
如何向JSP中动态添加可复用的内容?
可以使用<jsp:include>
和 <c:import>
嵌入文件,还可以通过<jsp:param>
和 <c:param>
在嵌入文件中使用请求参数。
如果只是为了给嵌入的文件一些客户化信息,就创建新的请求参数,会使资源浪费,而且嵌入的内容不易理解,必须要知道嵌入的参数是什么。
接下来介绍一种更利于我们去理解嵌入页面的方式 —— Tag Files。
1.1 使用Tag File
下面通过一个例子来介绍Tag File的使用。
需求:将一个带有logo的头文件嵌入到jsp页面中。
1.将需嵌入的文件扩展名改为.tag。
Header.tag
1 | <img src="img/ogo.png"> <br> |
2.将以上的tag文件放到一个目录下,如WEB-INF/tags
3.在jsp中使用taglib指令,首先需要先导入标签库,再使用标签。
1 | <%@ taglib prefix="myTag" tagdir="/WEB-INF/tags" %> //导入标签库 |
prefix:指定使用时标签前缀。
tagdir:用于指定tag文件存放的位置。
该页面使用 <myTags:Header>,也就是说此处用到了tag处理器,使用的ta
g处理器是放在tagdir目录下的 Header.tag 文件,容器会找到tag文件的位置。
1) 给tag flie传递数据
使用tag的属性可以给tag flie传递数据。例如对上面的需求进行完善。
需求:在jsp页面插入一个头部,这个头部包含一个logo和自定义标题,标题的内容可以在jsp页面指定。
1. header.tag中使用属性指令。
1 | <%@ attribute name="subTilte" required="true" rtextprvalue="true" %> |
- <%@ attribute>代表着一个tag的属性指令。
- name:属性名
- required:属性是否必需
- rtextprvalue=”true”:属性可以是字符串文本或表达式
2.在JSP页面使用tag。
1 | <%@ taglib prefix="myTag" tagdir="/WEB-INF/tags" %> |
二、 使用TLD
使用tag文件的时候,每一个tag处理器就需要编写一个tag文件,现在我们可以使用TLD统一声明tag。
Tag Library Descriptor (TLD),描述了EL函数(EL functions) 和 自定义Tag ,他通过使用EL函数扩展EL的功能 ,并且可以描述了自定义Tag。
2.1 使用 EL函数扩展EL的功能
通过EL表达式调用一个POJO上的静态方法来实现拓展EL函数的功能。通过下面4个步骤完成。
1.写一个具有公共静态方法的Java 类
1 | package foo; |
2.写TLD文件,它实现了定义函数功能的Java类到调用函数 的JSP页面间的映射
1 |
|
3.在JSP中使用taglib指令,使用EL调用该函数.
uri属性将TLD的名字告诉容器, 以便容器知道JSP调用EL函数 时应调用哪个Java方法
1 | <%@ taglib uri="DiceFunctions" prefix="mine"%> //uri对应于TLD中的uri |
2.2 用TLD描述自定义Tag
这是一个TLD的例子。
1 |
|
1) Tag体中的内容
TLD 中<body-content>
元素的定义:
<body-content>empty</body-content>
:Tag不能有tag 体<body-content>scriptless</body-content>
:tag不能有脚本元素 (代码片断、脚本表达式、声明 ), 但是可以是文字、EL和自定义或标准动作.<body-content>tagdependent</body-content>
:tag体被看作纯文本,所以EL, tags和动作将不被求值。<body-content>JSP</body-content>
:tag体可以是JSP中能使用任何东西。
2 ) rtexprvalue
rtexprvalue的全称是 Run-time Expression Value, 它用于表示是否能够利用JSP表白式。总结来说最简单的就是在使用标签时能不能使用表达式来动态指定数据。true是可以,false是不可以。
就上面的例子说: <rtexprvalue>true</rtexprvalue>
说明 在jsp页面中,user这个属性可以使用脚本和EL表达式来获取,如果是false,说明user这个属性是字符串文本。
3)容器怎样找到TLD
Web应用部署时,容器自动在TLD文件和 名字间建立映射。
容器首先查找DD中是否有,如果有则使用它创建 map,如果没有,则在特定位置查找TLD,并为tag库建立map。
容器在四个地方寻找 TLD文件
- 直接在WEB-INF中找
- 在WEB-INF的子目录中找
- 在WEB-INF/lib中的JAR 文件的META-INF目录中找
- 在WEB-INF/lib中的JAR 文件的META-INF的子目 录中找
三、Tag处理器
Tag处理器是执行tag工作的Java类,Tag处理器类可以访问tag属性、tag 体、page context(因此可以获得因此可以获得各个作用域中的属 性及请求和响应)
自定义tag处理器分为Classic tag处理器 和 Simple tag处理器 。接下来主要介绍怎常见一个Simple tag处理器。
3.1 Simple Tag处理器
1)创建一个Simple Tag处理器
需求通过Simple Tag处理器记录用户访问网站的次数,并输出。
1.写一个扩展SimpleTagSupport的类,重载doTag()方法。
1 | public class CounterSimpleTag1 extends SimpleTagSupport { |
2.写TLD文件,为Tag创建TLD: simple.tld,并将TLD放到WEB-INF中。
1 |
|
3.在JSP中使用tag
1 | <%@ taglib uri="SimpleTag" prefix="mytag"%> //uri对应于TLD中的uri |
2)Simple tag的寿命周期
Simple tag的寿命周期如下图所示:

3)在tag体中使用EL
在调用tag的jsp页面
1 | <myTags:simple3> |
其中message是simple处理器中的输出变量。
1 | public class SelectSimpleTag3 extends SimpleTagSupport { |
4) 处理有属性的tag
处理有属性的tag , 需要在TLD中设置属性(2.2节的例子相似) , 在tag处理器中为每个属性提供一个Bean类型的 set方法.
1 | public class SimpleTagTest5 extends SimpleTagSupport { |