一:背景
在项目中很多时候需要使用JSTL标签对一个集合进行遍历来输出信息,可以说foreach()方法的确不错,但是很多时候需要对JSTL标签做进一步功能的扩展,那么自定义的JSP标签就会被使用到。
二:JSP自定义标签
2.1:了解JSP标签类的层次结构
首先我们需要大致了解开发自定义标签所涉及到的接口与类的层次结构(其中SimpleTag接口与SimpleTagSupport类是JSP2.0中新引入的)。
在 JSP1.1 规范中开发自定义标签库比较复杂,JSP 2 规范简化了标签库的开发,在 JSP 2 中开发标签库只需如下几个步骤:
1. 开发自定义标签处理类;
2. 建立一个 .tld 文件,每个 .tld 文件对应一个标签库,每个标签库对应多个标签;
3. 在 JSP 文件中使用自定义标签。
2.2:开发自定义标签的处理类
结合使用JSTL标签的源码,JSP页面上的标签的解析都是有标签处理类进行解析,然后向页面输出所谓的HTML代码,从而实现对数据动态的展示。那么首先我们就要编写标签处理类。
自定义标签类都必须继承一个父类:javax.servlet.jsp.tagext.SimpleTagSupport,或者TagSupport除此之外,JSP自定义标签类还有如下要求。
1.如果标签类包含属性,每个属性都有对应的getter和setter方法。
2.重写doTag()或者doStartTag()或doEndTag()方法方法,这个方法负责生成页面内容。
首先,以在页面输出HelloWorld为例,代码如下:
public class HelloWorldTag extends TagSupport {
@Override
public int doEndTag() throws JspException {
try {
pageContext.getOut().write("Hello World !");
return super.doEndTag();
} catch (JspException e) {
e.printStackTrace();
return EVAL_PAGE;
} catch (IOException e) {
e.printStackTrace();
return EVAL_PAGE;
}
}
@Override
public int doStartTag() {
try {
pageContext.getOut().write("Hello World");
return super.doStartTag();
} catch (JspException e) {
e.printStackTrace();
return EVAL_PAGE;
} catch (IOException e) {
e.printStackTrace();
return EVAL_PAGE;
}
}
}
解释:方法 doStartTag() 是解释到开始标签的时候调用的方法,比如<helloworld></helloworld>
,当页面解释执行到<helloworld>
时调用doStartTag() ,当解释到</helloworld>
执行doEndTag()方法。
输出后如何作处,函数会返回几个值之一。EVAL_PAGE 表示tag已处理完毕,返回jsp页面。还有几个值,例如 EVAL_BODY_AGAIN 和EVAL_BODY_INCLUDE等。
2.3:建立TLD文件
TLD文件是标签库定义文件,文件的后缀名是.tld,每个TLD文件对应一个标签库,一个标签库中可包含多个标签。它存在的意义在于提供必要的配置信息,对页面自定义标签和标签处理的类俩者提供一个链接,让页面能够找到这个标签的处理类,从而实现页面显示的效果。
下面还是提供这个HelloWorld标签的例子的TLD文件:
<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>1.0</tlib-version>
<short-name>test</short-name>
<!-- 定义该标签库的URI 必须添加但可以空-->
<uri></uri>
<!-- 定义第一个标签 -->
<tag>
<!-- 定义标签名 -->
<name>helloworld</name>
<!-- 定义标签处理类 -->
<tag-class>org.taglib.HelloWorldTag</tag-class>
<!-- 定义标签体为空 -->
<body-content>empty</body-content>
<!-- 标签的描述信息 -->
<description>This is my first tagilb</description>
</tag>
</taglib>
解释:
<uri>
属性的设置可以为空,但是为空会使页面引入的时候比较麻烦,在页面中我们可能要这样引入<%@taglib prefix="test" uri="/WEB-INF/testfield.tld" %>
,但是如果我们指定了<uri>hello:test</uri>
,那么页面中就只需要<%@taglib prefix="test" uri="hello:test" %>
就可以了。
2.3:在页面中进行调用
调用代码如下:
<%@ page language="java"%>
<%@ taglib uri="/WEB-INF/testfield.tld" prefix="test"%>
<html>
<body>
Test Tag:
<test:helloworld></test:helloworld>
</body>
</html>
调用是否成功呢,可以尝试下(本人也是后面组织的代码,代码仅供参考)