目录
本章我们将深入讲解JSP中Tag文件的各个知识点,包括Tag文件的结构、Tag标记和Tag文件的使用、常用指令等。
3.1 Tag文件的结构
Tag文件是一种自定义标签的文件,它可以在JSP页面中使用,实现一些复杂或重复的功能。Tag文件的结构类似于HTML文件,它由一个标签声明、一个可选的指令部分和一个标签体组成。
3.1.1 Tag文件的结构
一个Tag文件的基本结构如下:
<%@ tag ... %> <!-- 标签声明,指定标签的属性和元数据 -->
<%@ directive ... %> <!-- 指令部分,可以包含多个指令,用于导入资源或定义变量等 -->
<tag-body> <!-- 标签体,可以包含静态内容或动态表达式,也可以包含其他标签 -->
</tag-body>
3.1.2 Tag文件的保存
Tag文件通常保存在WEB-INF目录下的一个子目录中,这个子目录的名称可以自定义,但是必须在web.xml文件中进行配置,例如:
<taglib>
<taglib-uri>http://www.example.com/tags</taglib-uri> <!-- 定义标签库的URI -->
<taglib-location>/WEB-INF/tags</taglib-location> <!-- 定义标签库的位置 -->
</taglib>
这样,在JSP页面中就可以使用taglib指令来引用这个标签库,并使用自定义标签了,例如:
<%@ taglib uri="http://www.example.com/tags" prefix="my" %> <!-- 引用标签库,并指定前缀 -->
<my:hello name="Bing" /> <!-- 使用自定义标签 -->
3.2 Tag标记
Tag标记是一种特殊的XML元素,它可以在JSP页面中使用自定义标签。Tag标记由一个开始标记、一个可选的结束标记和一个可选的属性列表组成。
3.2.1 Tag标记和Tag文件
Tag标记和Tag文件之间有一个对应关系,每个Tag标记都对应一个Tag文件。Tag标记的名称就是Tag文件的名称(不包括后缀),而Tag标记的属性就是Tag文件中定义的属性。例如,如果有一个名为hello.tag的Tag文件,它定义了一个name属性,那么对应的Tag标记就是:
<hello name="value" />
3.2.2 Tag标记的使用
Tag标记可以在JSP页面中像普通的HTML元素一样使用,只要引用了相应的标签库,并指定了前缀。例如:
<%@ taglib uri="http://www.example.com/tags" prefix="my" %> <!-- 引用标签库,并指定前缀 -->
<my:hello name="Bing" /> <!-- 使用自定义标签 -->
这样,在运行时,JSP引擎会将Tag标记替换为对应Tag文件中定义的内容,并执行其中的代码。
3.2.3 Tag标记的运行原理
Tag标记的运行原理是基于JSP技术和Java类库(javax.servlet.jsp.tagext)提供的接口和类。当JSP引擎遇到一个Tag标记时,它会根据web.xml中配置的信息找到对应的Tag文件,并将其转换为一个Java类(称为Tag处理器),然后创建一个该类的实例,并调用其生命周期方法来执行其中的代码。这些生命周期方法包括:
- doStartTag():当遇到开始标记时调用,返回SKIP_BODY或EVAL_BODY_INCLUDE。
- doEndTag():当遇到结束标记时调用,返回SKIP_PAGE或EVAL_PAGE。
- doAfterBody():当遇到结束标记且返回值为EVAL_BODY_INCLUDE时调用,返回SKIP_BODY或EVAL_BODY_AGAIN。
- release():当结束执行时调用,用于释放资源。
3.3 Tag文件中的常用指令
在Tag文件中,除了tag指令外,还有一些其他常用的指令,它们可以用来导入资源、定义变量、设置属性等。
3.3.1 tag指令
tag指令是必须出现在Tag文件中第一行的指令,它用来声明该文件是一个自定义标签,并指定一些属性和元数据。tag指令有以下常用属性:
- display-name:指定该自定义标签在图形化工具中显示的名称。
- body-content:指定该自定义标签是否允许有内容体,并且内容体是什么类型。取值有empty(无内容体)、scriptless(无脚本内容体)、tagdependent(依赖于具体实现)和jsp(JSP内容体)。
- dynamic-attributes:指定该自定义标签是否允许有动态属性,并且动态属性存储在哪个变量中。
- example:指定该自定义标签使用时候的示例代码。
- description:指定该自定义标签功能和用法等方面的描述信息。
例如:
<%@ tag display-name="Hello" body-content="empty" dynamic-attributes="attrs" example="<hello name='Bing' />" description="A simple tag to say hello." %>
3.3.2 include指令
include指令用来在当前Tag文件中导入其他资源(如HTML、JSP、JS等),并将其作为静态内容插入到当前位置。include指令有以下常用属性:
- file:指定要导入资源相对于当前目录或WEB-INF目录下tags目录下子目录下相对路径。
- flush:指定是否在导入资源之前清空输出缓冲区,默认为false。
例如:
<%@ include file="/header.html" %>
3.3.3 attribute指令
attribute指令用来在当前Tag文件中声明一个属性,并设置其名称、类型、默认值等信息。attribute指令有以下常用属性:
- name:指定属性名称。
- required:指定属性是否必须提供,默认为false。
- type:指定属性类型,默认为java.lang.String。
- rtexprvalue:指定属性值是否可以是运行时表达式,默认为true。
- fragment:指定属性值是否可以是JSP片段,默认为false。
- description:指定属性功能和用法等方面描述信息。
例如:
<%@ attribute name="name" required="true" type="java.lang.String" description="The name to say hello." %>
3.3.4 variable指令
variable指令用来在当前Tag文件中声明一个变量,并设置其名称、类型、作用域等信息。variable指令有以下常用属性:
- name-given:直接给出变量名称。
- name-from-attribute:从某个属性值获取变量名称。
- alias:给某个变量起别名。
- variable-class:指定变量类型,默认为java.lang.String。
- declare:指定是否声明变量,默认为true。
- scope:指定变量作用域,默认为NESTED。
例如:
<%@ variable name-given="attrs" variable-class="java.util.Map" scope="AT_BEGIN" %>
3.3.5 taglib指令
taglib 指令用于引入 Tag 库。以下是 taglib 指令的参数:
- uri:Tag 库的命名空间 URL
- prefix:Tag 库的前缀
以下是 taglib 指令的一个具体实现:
<%@taglib uri="/WEB-INF/tags/mytags.tld" prefix="mytags"%>
在上面的例子中,我们引入了一个名为“mytags”的 Tag 库,它的命名空间 URL 为“/WEB-INF/tags/mytags.tld”,前缀为“mytags”。
总结
本章主要介绍了Tag文件和Tag标记的概念、结构、用法和原理,以及Tag文件中常用的指令。