JSP自定义标签
2008-05-19 08:27
423 查看
1. 什么是标签?
标签扩展是一个Java类,它是运行一个或两个接口的JavaBean。在JSP规范里,标签具有比JavaBean更丰富的运行时协议,标签可以向JSP页面输出内容,也能访问JSP的一些内建对象,而JavaBean一般不产生动态内容,而只能产生调用的结果。例如:<jsp:include page=”header.jsp” flush=”true”/>就是一个标签。
2. 标签的优点
标签扩展可以让开发人员向JSP页面添加许多新功能,而使用这些新的功能,只要简单的调用这些标签就可以完成,从而使标签具有简单性、可重用性、易维护等优点。
3. 标签的组成
标签要能够使用,则必须有下列元素:
标签实现类:这是最基本的元素,一定要有一个类实现了JspTag接口,来实现自己的业务功能。
标签库描述符:用来描述标签实现类,并且以.tld结尾。在标签描述符里,指定了标签的名字,以及标签实现类所处的包和类的名称,并制定是否有Body。
部署描述:要在web.xml中描述如何引用这个标签,这里只需要指定标签库描述符的路径就可以了,千万要注意的是如果是servlet2.4那么必须使用<jsp-config>将<taglib>包含起来。
JSP页面:最后就是在JSP页面中调用标签,在这里需要使用<%@ taglib uri=”/WEB-INF/sample.tld” prefix=”s” %>将标签引用进来,这样便可以使用标签了。
4. 标签的接口和类的层次结构
JspTag --> SimpleTag
JspTag --> Tag --> ItarationTag --> BodyTagBody --> BodyTagSupport
最后蓝色粗体的是实现的类,前面的都是接口。
5. [b]SimpleTag标签的生命周期[/b]
构造一个SimpleTag的实例,并且这个构造方法没有参数
调用setJspContext()和setParent()方法,只有这个标签嵌套在另一个标签之内时,才调用setParent()方法;
如果标签属性,那么容器就调用这些属性的setter方法自动设置属性;
如果标签存在Body,那么就使用setJspBody()方法来设置这个标签的标签体;
容器调用doTag()方法,这个方法是SimpleTag的最重要的方法,也是标签处理的入口,通常需要重写这个方法,来实现自己的业务。
doTag()方法执行结束,返回后,所有的参数被锁定;
SimpleTag标签和传统标签的主要区别在于其核心的处理方法只有doTag(),可BodyTag()的核心处理方法有doStartTag()、doEndTag()、doAfterBody()之类的标签事件处理方法
6. BodyTag的生命周期
通过setPageContext()来设置标签的页面上下文,容器构造一个新的标签实例后
使用setParent()设置,如果有上一级标签;如果没有则设为null
调用setter方法设置属性,属性是要在.tld文件中定义,如果没有就不调用
调用doStartTag(),这个方法可以返回EVAL_BODY_INCLUDE和SKIP_BODY。如果返回EVAL_BODY_INCLUDE,就计算标签的Body,如果SKIP_BODY,则不计算
调用setBodyContext()来设置当前的BodyContent。
调用doInitBody(),如果在计算BodyContent时需要进行初始化
调用doAfterBody(),在计算完BodyTag后,如果返回EVAL_BODY_TAG,则表示继续计算一次BodyTag,直到返回SKIP_BODY,才执行下一步
调用doEndTag(),这个方法可以返回EVAL_PAGE和SKIP_PAGE。如果返回EVAL_PAGE,容器将在标签结束时继续计算JSP页面的其他部分;如果SKIP_PAGE,则不计算其他部分了
调用release(),释放标签处理程序的占用的任何资源
7. SimpleTag示例
/*标签程序,继承了SimpleTagSupport类*/
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
* 仅以此代码纪念2008年5月12号的四川汶川大地震
* 愿生者顽强,死者安息
* @author liky
*
*/
public class EarthquakeTag extends SimpleTagSupport {
private String name;
public void setName(String name) {
this.name = name;
}
public void doTag() throws JspException, IOException {
super.doTag();
this.getJspContext().getOut().write(name + "同志,请向四川灾区人民奉献您的一份爱心!");
}
}
/*标签库描述符*/
<?xml version="1.0" encoding="ISO-8859-1" ?>
<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">
<description>
A tag extends SimpleTagSupport for instance.
</description>
<tlib-version>1.0</tlib-version>
<short-name>quake</short-name>
<uri>/simple</uri>
<tag>
<description>demo the simple tag</description>
<name>quake</name>
<tag-class>com.taglib.EarthquakeTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
/*web.xml布署配置*/
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 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
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<jsp-config>
<taglib>
<taglib-uri>/WEB-INF/simpleTag.tld</taglib-uri>
<taglib-location>/WEB-INF/simpleTag.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
/*以下JSP代码代码测试调用*/
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/c.tld" prefix="c"%>
<%@ taglib uri="/WEB-INF/earthquake.tld" prefix="e" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>测试重新配置标准标签库</title>
</head>
<body>
<e:quake name="比尔.盖子"/>
</body>
</html>
8. BodyTag的示例
/*一个类继承自BodyTagSupport*/
package com.taglib;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**将标签体内的文字,使用指定的颜色和次数输出,每输出一个都换行*/
public class DedicateTag extends BodyTagSupport {
String color;
int count;
public void setColor(String color) {
this.color = color;
}
public void setCount(int count) {
this.count = count;
}
@Override
public int doAfterBody() throws JspException {
if (count > 1) {
count --;
try {
pageContext.getOut().write("<br>");
} catch (IOException e) {
throw new JspTagException ("IO Error: " + e.getMessage());
}
return EVAL_BODY_AGAIN;
}
else {
return SKIP_BODY;
}
}
@Override
public int doEndTag() throws JspException {
try {
if (bodyContent != null) {
bodyContent.writeOut(bodyContent.getEnclosingWriter());
pageContext.getOut().write("</font><br>");
}
} catch (IOException e) {
throw new JspTagException ("IO Error: " + e.getMessage());
}
return EVAL_PAGE;
}
@Override
public void doInitBody() throws JspException {
super.doInitBody();
}
@Override
public int doStartTag() throws JspException {
if(count > 0) {
try {
pageContext.getOut().write("<font color=" + color + ">");
} catch (Exception e) {
e.printStackTrace();
}
return EVAL_BODY_INCLUDE;
}
else {
return SKIP_BODY;
}
}
}
/*标签库描述符*/
<?xml version="1.0" encoding="ISO-8859-1" ?>
<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">
<description>
A tag extends SimpleTagSupport for instance.
</description>
<tlib-version>1.0</tlib-version>
<short-name>dedicate</short-name>
<uri>/dedicate</uri>
<tag>
<description>demo the body tag</description>
<name>dedicate</name>
<tag-class>com.taglib.DedicateTag</tag-class>
<body-content>jsp</body-content>
<attribute>
<name>color</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>count</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
/*web.xml部署描述*/
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 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
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<jsp-config>
<taglib>
<taglib-uri>/WEB-INF/dedicate.tld</taglib-uri>
<taglib-location>/WEB-INF/dedicate.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
/*测试用的JSP页面*/
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/dedicate.tld" prefix="d"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>测试重新配置标准标签库</title>
</head>
<body>
<d:dedicate color="#AA1234" count="6">2008年5月12号</d:dedicate>
</body>
</html>
标签扩展是一个Java类,它是运行一个或两个接口的JavaBean。在JSP规范里,标签具有比JavaBean更丰富的运行时协议,标签可以向JSP页面输出内容,也能访问JSP的一些内建对象,而JavaBean一般不产生动态内容,而只能产生调用的结果。例如:<jsp:include page=”header.jsp” flush=”true”/>就是一个标签。
2. 标签的优点
标签扩展可以让开发人员向JSP页面添加许多新功能,而使用这些新的功能,只要简单的调用这些标签就可以完成,从而使标签具有简单性、可重用性、易维护等优点。
3. 标签的组成
标签要能够使用,则必须有下列元素:
标签实现类:这是最基本的元素,一定要有一个类实现了JspTag接口,来实现自己的业务功能。
标签库描述符:用来描述标签实现类,并且以.tld结尾。在标签描述符里,指定了标签的名字,以及标签实现类所处的包和类的名称,并制定是否有Body。
部署描述:要在web.xml中描述如何引用这个标签,这里只需要指定标签库描述符的路径就可以了,千万要注意的是如果是servlet2.4那么必须使用<jsp-config>将<taglib>包含起来。
JSP页面:最后就是在JSP页面中调用标签,在这里需要使用<%@ taglib uri=”/WEB-INF/sample.tld” prefix=”s” %>将标签引用进来,这样便可以使用标签了。
4. 标签的接口和类的层次结构
JspTag --> SimpleTag
JspTag --> Tag --> ItarationTag --> BodyTagBody --> BodyTagSupport
最后蓝色粗体的是实现的类,前面的都是接口。
5. [b]SimpleTag标签的生命周期[/b]
构造一个SimpleTag的实例,并且这个构造方法没有参数
调用setJspContext()和setParent()方法,只有这个标签嵌套在另一个标签之内时,才调用setParent()方法;
如果标签属性,那么容器就调用这些属性的setter方法自动设置属性;
如果标签存在Body,那么就使用setJspBody()方法来设置这个标签的标签体;
容器调用doTag()方法,这个方法是SimpleTag的最重要的方法,也是标签处理的入口,通常需要重写这个方法,来实现自己的业务。
doTag()方法执行结束,返回后,所有的参数被锁定;
SimpleTag标签和传统标签的主要区别在于其核心的处理方法只有doTag(),可BodyTag()的核心处理方法有doStartTag()、doEndTag()、doAfterBody()之类的标签事件处理方法
6. BodyTag的生命周期
通过setPageContext()来设置标签的页面上下文,容器构造一个新的标签实例后
使用setParent()设置,如果有上一级标签;如果没有则设为null
调用setter方法设置属性,属性是要在.tld文件中定义,如果没有就不调用
调用doStartTag(),这个方法可以返回EVAL_BODY_INCLUDE和SKIP_BODY。如果返回EVAL_BODY_INCLUDE,就计算标签的Body,如果SKIP_BODY,则不计算
调用setBodyContext()来设置当前的BodyContent。
调用doInitBody(),如果在计算BodyContent时需要进行初始化
调用doAfterBody(),在计算完BodyTag后,如果返回EVAL_BODY_TAG,则表示继续计算一次BodyTag,直到返回SKIP_BODY,才执行下一步
调用doEndTag(),这个方法可以返回EVAL_PAGE和SKIP_PAGE。如果返回EVAL_PAGE,容器将在标签结束时继续计算JSP页面的其他部分;如果SKIP_PAGE,则不计算其他部分了
调用release(),释放标签处理程序的占用的任何资源
7. SimpleTag示例
/*标签程序,继承了SimpleTagSupport类*/
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
* 仅以此代码纪念2008年5月12号的四川汶川大地震
* 愿生者顽强,死者安息
* @author liky
*
*/
public class EarthquakeTag extends SimpleTagSupport {
private String name;
public void setName(String name) {
this.name = name;
}
public void doTag() throws JspException, IOException {
super.doTag();
this.getJspContext().getOut().write(name + "同志,请向四川灾区人民奉献您的一份爱心!");
}
}
/*标签库描述符*/
<?xml version="1.0" encoding="ISO-8859-1" ?>
<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">
<description>
A tag extends SimpleTagSupport for instance.
</description>
<tlib-version>1.0</tlib-version>
<short-name>quake</short-name>
<uri>/simple</uri>
<tag>
<description>demo the simple tag</description>
<name>quake</name>
<tag-class>com.taglib.EarthquakeTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
/*web.xml布署配置*/
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 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
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<jsp-config>
<taglib>
<taglib-uri>/WEB-INF/simpleTag.tld</taglib-uri>
<taglib-location>/WEB-INF/simpleTag.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
/*以下JSP代码代码测试调用*/
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/c.tld" prefix="c"%>
<%@ taglib uri="/WEB-INF/earthquake.tld" prefix="e" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>测试重新配置标准标签库</title>
</head>
<body>
<e:quake name="比尔.盖子"/>
</body>
</html>
8. BodyTag的示例
/*一个类继承自BodyTagSupport*/
package com.taglib;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**将标签体内的文字,使用指定的颜色和次数输出,每输出一个都换行*/
public class DedicateTag extends BodyTagSupport {
String color;
int count;
public void setColor(String color) {
this.color = color;
}
public void setCount(int count) {
this.count = count;
}
@Override
public int doAfterBody() throws JspException {
if (count > 1) {
count --;
try {
pageContext.getOut().write("<br>");
} catch (IOException e) {
throw new JspTagException ("IO Error: " + e.getMessage());
}
return EVAL_BODY_AGAIN;
}
else {
return SKIP_BODY;
}
}
@Override
public int doEndTag() throws JspException {
try {
if (bodyContent != null) {
bodyContent.writeOut(bodyContent.getEnclosingWriter());
pageContext.getOut().write("</font><br>");
}
} catch (IOException e) {
throw new JspTagException ("IO Error: " + e.getMessage());
}
return EVAL_PAGE;
}
@Override
public void doInitBody() throws JspException {
super.doInitBody();
}
@Override
public int doStartTag() throws JspException {
if(count > 0) {
try {
pageContext.getOut().write("<font color=" + color + ">");
} catch (Exception e) {
e.printStackTrace();
}
return EVAL_BODY_INCLUDE;
}
else {
return SKIP_BODY;
}
}
}
/*标签库描述符*/
<?xml version="1.0" encoding="ISO-8859-1" ?>
<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">
<description>
A tag extends SimpleTagSupport for instance.
</description>
<tlib-version>1.0</tlib-version>
<short-name>dedicate</short-name>
<uri>/dedicate</uri>
<tag>
<description>demo the body tag</description>
<name>dedicate</name>
<tag-class>com.taglib.DedicateTag</tag-class>
<body-content>jsp</body-content>
<attribute>
<name>color</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>count</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
/*web.xml部署描述*/
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 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
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<jsp-config>
<taglib>
<taglib-uri>/WEB-INF/dedicate.tld</taglib-uri>
<taglib-location>/WEB-INF/dedicate.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
/*测试用的JSP页面*/
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/dedicate.tld" prefix="d"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>测试重新配置标准标签库</title>
</head>
<body>
<d:dedicate color="#AA1234" count="6">2008年5月12号</d:dedicate>
</body>
</html>