一、自定义JSP标签的执行过程
当一个含有自定义标签的JSP页面被JSP引擎(Web容器)转译成Servelt时,JSP引擎遇到自定义的标签,会把这个自定标签标识成对一个称为“标签处理类”的调用。当这个JSP页面被执行时,JSP引擎就会调用这个“标签处理类”对象,并执行其内部定义的相应操作方法,从而完成相应的功能。
从这个执行过程来看,自定义标签就是把原来编写在JSP页面的Java代码单独封装到一个Java类中,当调用自定义标签时,其实是映射调用相应的“标签处理类”来完成工作。
二、自定义JSP标签的开发流程
使用Java处理类来开发自定义JSP标签时,主要分为以下几个步骤:
(1) 创建标签的处理类(Tag Handle Class)这个类用来定义标签的行为,并在JSP引擎遇到自定义标签时调用执行。标签处理类是一个Java类,这个类只需要继承了JSP标签API中提供的接口或类就可以很简单地实现自定义JSP标签的具体功能。
(2) 创建标签库描述文件(Tag Library Descriptor File)。这个文件是描述标签库的XML文档,它描述了标签库中每个标签的属性详细信息,向JSP引擎提供有关自定义标签的标签处理程序的信息。
(3) 在web.xml文件中声明TLD的位置。(在使用一些集成框架时,这个步骤不是必须的。 例如在下面的例子中用到了spring,只要在jsp中引入即可使用。)
(4) 在JSP文件中用taglib指令引入标签库,然后使用标签库描述文件中指定的标签名来使用它。
三、JSP标签API
Javax.servlet.jsp.tagext包
JSP 1.1和1.2规范中常用的接口主要有以下3个。
Tag:此接口定义对于所有标签处理类都需要实现的方法。
IterationTag:此接口扩展了Tag接口,增加了控制重复执行标签主体的方法。
BodyTag:此接口扩展了IterationTag接口,并增加了访问和操作标签主体内容的方法。
JSP API针对这3个接口还提供了两个支持类,即TagSuppor和BodyTagSupport,用来简化自定义标签的开发。
四、标签库描述符
标签库描述符文件是一个以“.tld”结尾的标准XML文档,用来记录一个标签库内拥有哪些标签、第个标签包含哪些属性。
<taglib>元素是标签库描述符的根元素,它包含12个子元素,如
1. <description>:标签库的一个文本描述。
2. <tlib-version>:指定标签库的版本。
3. <short-name>:为标签定义简短的名字,在taglib指令中可作为首选的前缀名使用。
4. <uri>:定义一个URL,用于唯一地标识些标签库。
5. <tag>:用于指定自定义标签的相关信息。<tag>元素有12个子元素,这里只对部分元素做介绍,如下:
a) <description>:为自定义标签提供一个文本描述。
b) <display-name>:为标签指定一个简短的名字。
c) <name>:指定标签的名字。
d) <tag-class>:指定标签处理类的完整路径。
e) <body-content>:指定标签体的格式。格式有四种:
² empty:标识标签没有标签体。
² scriptless:表示标签体可以包含EL表达式和JSP的动作元素,但是不能包含JSP的脚本元素。
² JSP:表示标签体可以包含JSP代码。
² tagdependent:表示标签体由标签本身去解析处理。若指定tagdependent,那么在标签体中所写的代码将作为纯文本原封不动地传给处理类,而不是将执行的结果传给标签处理类。
f)<attribute>:该标签用于设置标签的属性。该元素有6个子元素。具体如下:
² <description>:为属性提供一个文本描述
² <name>:指定属性的名字
² <required>:指定该属性是否必须。默认为false
² <rtexprvaalue>:指定属性值是否可以在JSP运行时期动态产生
² <type>:指定属性的类型
² <fragment>:指定属性是否为JspFragment对象,默认false
g)<example>:用于提供一个使用该标签例子的信息描述。
h)<variable>:定义标签处理类提供给JSP页面使用的脚本变量。
i)<dynamic-attributes>:指定标签是否支持动态属性,取值是否支持动态属性,取值为true或者false。
j)<icon>、<tag-extension>、<tei-class>
6、<display-name>:为标签库指定一个简短的别名。
7、<small-icon>:为标签库指定大小为16x16的小图标(gif或jpeg格式),该图标可在图形界面工具中显示。
8、<large-icon>:为标签库指定大小为32x32的小图标(gif或jpeg格式),该图标可在图形界面工具中显示。
9、<validator>:为标签库提供一个验证器。
10、<listener>:为标签库提供一个监听器。
11、<tag-file>:用于描述标签文件。
12、<function>:用于指定在表达式语言中使用的函数。
--------------------------------------------------------------------以上内容为转载------------------------------------------------------------------
实践代码:<这是一个自己写的例子,测试通过>
1、创建标签的处理类(Tag Handle Class)
package org.test.zTest;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
public class TagTest extends TagSupport {
private static final long serialVersionUID = 3095327982159183182L;
// 自定义标签的部分属性
private String name;
private String type;
private String value = null;
private String onclick;
private String show;
private String id;
public String getShow() {
return show;
}
public void setShow(String show) {
this.show = show;
}
public String getName() {
return name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getOnclick() {
return onclick;
}
public void setOnclick(String onclick) {
this.onclick = onclick;
}
@Override
public int doStartTag() throws JspException {
return SKIP_BODY;
}
@Override
public int doEndTag() throws JspException {
StringBuffer bufHtml = new StringBuffer();
if(!(show == null || "".equals(show)) && "label".equals(show)) {
bufHtml.append("<label ");
if (!(id == null || "".equals(id))) {
bufHtml.append("id=\"" + id + "\" ");
}
bufHtml.append(">"+value+"</label>");
}else {
bufHtml.append("<input ");
if (!(name == null || "".equals(name))) {
bufHtml.append("name=\"" + name + "\" ");
}
if (!(type == null || "".equals(type))) {
bufHtml.append("type=\"" + type + "\" ");
}
if (!(value == null || "".equals(value))) {
bufHtml.append("value=\"" + value + "\" ");
}
if (!(onclick == null || "".equals(onclick))) {
bufHtml.append("οnclick=\"" + onclick + "\" ");
}
bufHtml.append("/>");
}
JspWriter out = this.pageContext.getOut();
try {
out.print(bufHtml.toString());
} catch (IOException e) {
e.printStackTrace();
}
return EVAL_PAGE;
}
}
2、创建标签库描述文件(Tag Library Descriptor File)testTag.tld
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN""http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>csdn</short-name>
<uri>http://www.csdn.com</uri>
<description>
<![CDATA[Custom tag library for this application]]>
</description>
<tag>
<name>testTag</name>
<tag-class>org.test.zTest.TagTest </tag-class>
<body-content>jsp</body-content>
<attribute>
<name>show</name>
<required>true</required>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
</attribute>
<attribute>
<name>type</name>
<required>false</required>
</attribute>
<attribute>
<name>value</name>
<required>false</required>
</attribute>
<attribute>
<name>onclick</name>
<required>false</required>
</attribute>
<attribute>
<name>id</name>
<required>false</required>
</attribute>
</tag>
</taglib>
3、在JSP文件中用taglib指令引入标签库
<%@ page language="java"import="java.util.*"pageEncoding="GBK"%>
<%@ taglib uri="/WEB-INF/testTag.tld"prefix="jc"%>
<!DOCTYPEHTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'tagTest.jsp' starting page</title>
<metahttp-equiv="pragma"content="no-cache">
<metahttp-equiv="cache-control"content="no-cache">
<metahttp-equiv="expires"content="0">
<metahttp-equiv="keywords"content="keyword1,keyword2,keyword3">
<metahttp-equiv="description"content="This is my page">
</head>
<scripttype="text/javascript">
function showClick() {
alert("test OK!");
}
</script>
<body>
输入文字:
<jc:testTagshow="input"name="inFont"type="text"/>
<br/>
输入密码:
<jc:testTagshow="label"id="inPsW"value="Test Ok"></jc:input>
<br/>
按钮提交:
<jc:testTag show="input"name="btnSubmit"type="submit"value="提交"/>
<br/>
按钮重置:
<jc:testTag show="input"name="btnReset"type="reset"onclick="clearContent();"value="重置"/>
<br/>
测试按钮:
<jc:testTag show="input"name="btnClick"type="reset"onclick="showClick();"value="按钮"/>
</body>
</html>
<完>