在JSP规范的1.1版中增加了自定义标签库规范,自定义标签库是一种非常优秀的表现层组件技术。通过使用自定义标签库,可以在简单的标签中封装复杂的功能。Web 开发需要一种可在页面中使用的标签,这种标签具有和HTML 标签类似的语法,但又可以完成JSP 脚本的功能这种标签就是JSP 自定义标签。在JSP 1.1 规范中开发自定义标签库比较复杂, JSP 2 规范简化了标签库的开发。
JSTL
其中uri 属性指定标签库的URI,这个URI 可以确定一个标签库。而prefix 属性指定标签库前缀,即所有使用该前缀的标签将由此标签库处理。
案例
开发自定义标签类
在JSP 2 中开发标签库只需如下几个步骤。
自定义标签类应该继承一个父类: javax.servlet.jsp.tagext.SimpleTagSupport , 除此之外, JSP 自定义标签类还有如下要求。
TLD是Tag Library Definition 的缩写,即标签库定义,文件的后缀是tld ,每个TLD 文件对应一个标签库, 一个标签库中可包含多个标签。TLD 文件也称为标签库定义文件。标签库定义文件的根元素是taglib ,它可以包含多个tag 子元素,每个tag 子元素都定义一个标签。通常可以到Web 容器下复制一个标签库定义文件,并在此基础上进行修改即可。
Tomcat 8.5 ,在webapps\examples\ WEB - INF\jsp2 路径下包含了一个jsp2 - example-taglib.tld 文件,这就是一个TLD 文件的范例。将该文件复制到Web 应用的WEB -INF/路径,或WE B-INF 的任意子路径下,并对该文件进行简单修改。
taglib 元素下可以包含多个tag 元素,每个tag 元素定义一个标签, tag 元素下允许出现
如下常用子元素。
上面使用标签的语法里都包含了设置属性值,前面介绍的HelloWorld Tag 标签没有任何属性,所以使用该标签只需用<mytag :helloWorld/>即可。其中mytag 是taglib 指令为标签库指定的前缀,而helloWorld是标签名。
带属性的标签
带属性标签必须为每个属性提供对应的setter 和getter 方法。带属性标签的配置方法与简单标签也略有差别。该标签输出的内容依然由doTag方法决定,该方法会根据SQL 语句查询数据库,并将查询结果显示在当前页面中。
对于有属性的标签,需要为<tag… ./>元素增加<attribute… ./>子元素, 每个attribute子元素定义一个标签属性。<attribute… ./>子元素通常还需要指定如下几个子元素。
配置完毕后,就可在页面中使用标签了,先导入标签库,然后使用标签。使用标签的JSP 页面片段如下。
带标签体的标签
带标签体的标签,可以在标签内嵌入其他内容(包括静态的HTML 内容和动态的JSP 内容〉,
标签处理类的doTag方法首先从page 范围内获取了指定名称的Collection 对象,然后遍历Collection 对象的元素,每次遍历都调用了getJspBody方法,如程序中粗体宇代码所示,该方法返回该标签所包含的标签体: JspFragment 对象,执行该对象的invoke()方法,即可输出标签体内容。该标签的作用是:遍历指定集合,每遍历一个集合元素,即输出标签体一次。
因为该标签的标签体不为空,配置该标签时指定body-content 为scriptless,指定该标签的标签体可以是静态HTML 内容,也可以是表达式语言,但不允许出现JSP 脚本。
以页面片段作为属性的标签
JSP 2 规范的自定义标签还允许直接将一段“页面片段”作为属性,这种方式给自定义标签提供了更大的灵活性。
该成员变量代表了使用该标签时的“页面片段”,配置该标签与配置普通标签并无任何区别, 增加如下配置片段即可。
由于该标签需要一个Fragment 属性,该属性的类型为JspFragment , 因此使用该标签时需要使用<jsp:attribute … ./>动作指令来设置属性值。
动态属性的标签
前面介绍带属性标签时, 那些标签的属性个数是确定的,属性名也是确定的,绝大部分情况下这种带属性的标签能处理得很好,但在某些特殊情况下,需要传入自定义标签的属性个数是不确定的,属性名也不确定,这就需要借助于动态属性的标签了。动态属性标签比普通标签多了如下两个额外要求。
上面的标签处理类实现了DynaAAttributesTag 接口, 就是动态属性标签处理类必须实现的接口,实现该接口必须实现setDynamicAttribute方法,该方法用于为该标签处理类动态地添加属性名和属性值。配置该标签时需要额外地指定<dynamic-attributes … ./>子元素,表明该标签是带动态属性的标签。
一旦定义了动态属性的标签,接下来在页面中使用该标签时将十分灵活,完全可以为该标签设置任意的属性。
EL表达式
使用表达式语言可以直接获取请求参数值,可以获取页面中JavaBean 的指定属性值,获取请求头及获取page 、request 、session 和application范围的属性值等,这些都得益于表达式语言的内置对象。
表达式语言的自定义函数
表达式语言除了可以使用基本的运算符外,还可以使用自定义函数。
开发函数处理类: 函数处理类就是普通类,这个普通类中包含若干个静态方法,每个静态方法都可定义成一个函数。实际上这个步骤也是可省略的完全可以直接使用JDK 或其他项目提供的类,只要这个类包含静态方法即可。
使用标签库定义函数:定义函数的方法与定义标签的方法大致相似。在<taglib … ./>元素下增加<tag … ./>元素用于定义自定义标签: 增加<function … ./>元素则用于定义自定义函数。每个<function… ./>,只要三个子元素即可。
在JSP 页面的EL 中使用函数: 一样需要先导入标签库,然后再使用函数。
Tag File 是自定义标签的简化用法,使用Tag File 可以无须定义标签处理类和标签库文件,但仍然可以在JSP 页面中使用自定义标签。Tag File 是自定义标签的简化。事实上,就如同JSP 文件会编译成Serviet 一样, Tag File 也会编译成标签处理类,自定义标签的后台依然由标签处理类完成,而这个过程由容器完成。