Java Server Pages(JSP)——9. 标签文件

写在前面

之前介绍了自定义标签, 通过写无脚本的JSP文件, 可以促进分工, 页面设计者可以和后台逻辑编码者同时进行工作。 不过, 编写自定义标签是一件冗长琐碎的事, 你需要编写并编译一个标签处理类,还需要在标签库描述文件中定义标签。

从JSP 2.0开始, 通过tag file的方式, 无须编写标签处理类和标签库描述文件, 也能够自定义标签了。 tagfile在使用之前无须编译, 并且不需要标签库定义文件。

tag file简介

tag file从两个方面简化了自定义标签的开发。 首先, tag file无须提前编译, 直到第一次被调用才会编译。 除此之外, 仅仅使用JSP语法就可以完成标签的扩展定义, 这意味着不懂Java的人也能够进行标签自定义了。

其次, 标签库描述文件也不再需要了。 原先需要在标签库描述文件里定义标签元素的名字, 以及它所对应的action。 使用tag file的方式, tag file名和action相同,因此不再需要标签库描述文件了。

JSP容器提供多种方式将tag file编译成Java的标签处理类。 例如Tomcat将tag file翻译成继承于javax.servlet.jsp.tagext.SimpleTag接口的标签处理类。

一个tag file和JSP页面一样, 它拥有指令、 脚本、EL表达式、 动作元素以及自定义的标签。 一个tag file以tag和tagx为后缀, 它们可以包含其他资源文件。 一个被其他文件包含的tag file应该以tagf为后缀。

tag文件必须放在应用路径的WEB-INF/tags目录下才能生效。 和标签处理类一样, tag 文件可以被打到jar包里。

tag file中也有一些隐藏对象, 通过脚本或者EL表达式可以访问这些隐藏对象。 如下所示:

对象 类型
request javax.servlet.http.HttpServletRequest
response javax.servlet.http.HttpServletResponse
out javax.servlet.jsp.JspWriter
session javax.servlet.http.HttpSession
application javax.servlet.ServletContext
config javax.servlet.ServletConfig
jspContext javax.servlet.jsp.JspContext

tag file指令

和JSP页面一样, tag file可以使用指令来指挥JSP容器如何编译这个tag file。 tag file的指令语法和JSP是一样的:

//*号表示可以重复0次或多次
<%@ directive (attribute="value")* %>

//或者如下:
<%@ directive attribute1="value1" attribute2="value2" ... %>

属性必须被单引号或者双引号包裹, <%@ 之后和 %>之前的空格加不加都不影响正确性, 但是为了可读性, 建议加上空格。

除了page指令, 其他所有的JSP指令都可以用于tag file。 在tag file中, 可以使用tag指令代替page指令。 另外, 你还可以使用两个新指令:attribute 和variable。 其他所有可以在tag file文件中使用指令如下所示:

指令 描述
tag 作用与JSP页面中的page指令类似
include 用于将其他资源导入tag file中
taglib 用于将自定义标签库导入tag file中
attribute 设定tag file中标签的属性
variable 用于将自定义标签库导入tag file中

1.tag指令

tag指令和JSP页面中的page指令类似。 以下是它的使用语法:

<%@ tag (attribute="value")* %>

//或者如下
<%@ tag attribute1="value1" attribute2="value2" ... %>

tag指令的全部属性如下所示, 所有属性都不是必须的:

属性 描述
display-name 在XML工具中显示的名称。 默认值是不包含后缀的tag file名
body-content 指定标签body的类型, body-content属性值有empty、tagdependent、scriptless, 默认值是scriptless
dynamicattributes 指定tag file动态属性的名称。 当dynamicattributes值被设定时, 会产生一个Map来存放这些动态属性的名称和对应的值
small-icon 指定一个图片路径, 用于在XML工具上显示小图标。 一般不会用到
large-icon 指定一个图片路径, 用于在XML工具上显示大图标。 一般也不会用到
description 标签的描述信息
example 标签使用实例的描述
language tag file中使用的脚本语言类型。 当前版本的JSP中, 该值必须设为“java”
import 用于导入一个java类型, 和JSP页面中的import相同
pageEncoding 指定tag file使用的编码格式, 可以使用“CHARSET”中的值。 和JSP页面中的pageEncoding相同

除了import属性, 其他所有的属性在一个tag指令或一个tag file中都只能出现一次。

2.include指令
tag file中的include指令和JSP页面中的include指令是一样的。 可以使用这个指令来将外部文件导入到tagfile中。 当你有一个公共资源文件有可能用在多个tagfile中时, include指令将能够发挥它的作用。 这个公共资源文件可以是静态文件(例如HTML文件) , 也可以是动态文件(例如其他tag file) 。

3.taglib指令
可以通过taglib指令在tag file中使用自定义标签。taglib指令的语法如下:

<%@ taglib uri="tagLibraryURI" prefix="tagPrefix" %>

其中uri属性用来指定与前缀相关联的标签库描述文件的绝对路径或相对路径。prefix属性用来定义自定义标签的前缀。

使用taglib指令, 你可以像下面那样使用不包含content body的自定义标签:

<prefix:tagName/>

当然, 也可以使用包含content body的自定义标签:

<prefix:tagName>body</prefix:tagName>

tag file中的taglib指令和JSP页面中的taglib指令是一样的。

4.attribute指令
attribute用于设定tag file中标签的属性。 它和标签库描述文件中的attribute元素等效。 下面是该指令的语法:

<%@ attribute (attribute="value")* %>
//也可以用以下更直白的方式表达:
<%@ attribute attribute1="value1" attribute2="value2" ... %>

attribute指令的属性如下所示,只有name属性是必须的。

属性 描述
name 用于设定该属性的名称。 在一个tag file中, 每个属性的名称必须是唯一的
required 用于设定该属性是否是必须的。 值可以取true或false, 默认值:flase
fragment 用于设定该属性是否是fragment。 默认值为false
rtexprvalue 用于设定该属性的值是否在运行时被动态计算。 值可以取true或false, 默认值为true
type 用于设定该属性的类型, 默认值为java.lang.String
description 用于设定该属性的描述信息

5.variable指令

有时候我们需要将tag file中的一些值传递到JSP页面。 这时候通过variable来完成。 tag file中的variable指令和标签库描述文件中的variable元素类似, 它用于定义那些需要传递到JSP页面的变量。

tag file支持多个variable指令, 这意味着可以传递多个值到JSP页面。 相对而言, attribute 指令的作用与variable相反, 它用于将值从JSP页面传递到tag file。

variable指令的语法如下:

<%@ variable (attribute="value")* %>
//也可以用下面这样更直白的表达方式:
<%@ variable attribute1="value1" attribute2="value2" ... %>

variable属性如下所示。

属性 描述
namegiven 变量名。 在JSP页面的脚本和EL表达式中, 可以使用该变量名。 如果指定了name-from-attribute属性, 那么name-given属性就不能出现了, 反之亦然。 name-given的值不能和同一个tag file中的属性名重复
namefromattribute 和name-given属性类似, 由标签属性的值来决定变量的名称。 如果namefrom-attribute和name-given属性同时出现或者都不出现的话会出现错误
alias 设定一个用来接收变量值的局部范围
variableclass 变量的类型。 默认为java.lang.String
declare 设定该变量是否声明。 默认值为false
scope 用于指定该变量的范围。 可取的值为AT_BEGIN、 AT_END、 和 NESTED。 默认值为NESTED
description 用于描述该变量

doBody动作元素

doBody动作元素只能在tag file中使用, 它用来调用一个标签的本体内容。

doBody动作元素也可以有属性。 你可以通过这些属性来指定某个变量来接收主体内容, 如果不使用这些指令, 那么doBody动作元素会把主体内容写到JSP页面的JspWriter上。

doBody属性如下表所示:

属性 描述
var 用于保存标签主体内容的变量值, 主体内容就会以java.lang.String的类型保存这个变量内。 var和varReader属性只能出现一个
varReader 用于保存标签主体内容的变量值, 主体内容就会以java.io.Reader的类型保存这个变量内。 var和varReader属性只能出现一个
scope 变量保存到的作用域

invoke动作元素

invoke动作元素和doBody类似, 在tag file中, 可以使用它来调用一个fragment。

在定义属性的attribute指令中有一个fragment属性, 它的值可以是true或者false。 如果fragment值为true, 那么这个属性就是一个fragment, 这意味着可以从tag file中多次调用。

invoke动作元素也有多个属性, 如下展示了invoke动作元素中的全部属性, 其中fragment属性是必须的。

属性 描述
fragment 要调用的fragment的名称
var 用于保存片段主体内容的变量值, 主体内容就会以java.lang.String的类型保存这个变量内。 var和varReader属性只能出现一个
varReader 用于保存标签主体内容的变量值, 主体内容就会以java.io.Reader的类型保存这个变量内。 var和varReader属性只能出现一个
scope 变量保存到的作用域

写在最后

这一部分简单的介绍了如何使用tag file更简单地进行标签自定义。 通过tag file, 可无须编写标签库描述文件和标签处理类。 同时, 本章还介绍了如何使用invoke和doBody动作元素。将在后面一篇博客介绍本篇博客的实例。结合起来食用风味更佳。

猜你喜欢

转载自blog.csdn.net/zy2317878/article/details/80470741
今日推荐