自定义标签在功能上逻辑上与javaBean 类似,都封装Java 代码。自定义标签是可重用的组件代码,并且允许开发人员为复杂的操作提供逻辑名称;其实换句话说,taglib可以看成是对JSP标记的一种扩展,正如xml是对html的一种扩展一样。
为什么要使用自定义标签?
JSTL标签库只提供了简单的输出等功能,没有实现任何的HTML代码封装,并且某些复杂类型转换,或者逻辑处理的时候,JSTL标签库完成不了,需要自定义标签!
一般情况,自定义tag标签主要用于操作隐藏对象、处理html提交表单、访问数据库等操作。
自定义标签语法中两类标签:自定义标签与自定义函数。
自定义标签与普通标签库中的标签用法相同,自定义函数它可以让我们在jsp用直接调用某个方法,根据自定义的方法返回指定的值,兼容jstl标签,省去了在jsp中直接使用<%!%>来定义方法体再调用的繁琐。
编写自定义标签的步骤:
1.编写一个实现Tag接口的Java类【标签处理器类】;
2.在WEB-INF目录下创建tld(Tag Library Descriptor)文件,在tld文件中对标签处理类(实现Tag接口的Java类)进行描述;
自定义标签TLD文件配置属性说明:
taglib子元素说明:
tlib-version:标签库的版本
jsp-version:这个标签库要求的JSP规范版本
short-name:JSP页面编写工具可以用来创建助记名的可选名字
uri:唯一标识该标签库的的URI
display-name:将由工具显示的可选名
description:可选的标签特定信息
listener:一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。
tag子元素说明:
name:独一无二的元素名
tag-class:Tag标签对应的tag处理类
tei-class:javax.servlet.jsp.tagext.TagExtraInfo的子类,用于表达脚本变量(可选)
body-content:Tag标签body的类型
display-name:被可视化工具(诸如Jbuilder)用来显示的名称(可选)
small-icon:被可视化工具(诸如Jbuilder)用来显示的小图标(可选)
large-icon:被可视化工具(诸如Jbuilder)用来显示的大图标(可选)
description:此tag标签的描述
variable:提供脚本变量的信息(同tei-class)(可选)
attribute:Tag标签的属性名
attribute子元素说明:
name:属性名
required:该属性名可不可省略
rtextprvalue: 表示的是属性是否接受scriptlet表达式的计算结果,默认情况下为false,即只能接受静态值
type:标签处理类中相关属性的类型
自定义标签实例:
编写一个实现Tag接口的Java类:
通常我们自定义类继承TagSupport、BodyTagSupport,重写doStartTag(),doAfterBody()和doEndTag()方法,在对应方法中实现我们自己的逻辑:
public class SelectButton extends BodyTagSupport {
private static final long serialVersionUID = 1L;
private String flag;
private JspWriter out;
public void init() {
out = pageContext.getOut();
}
@Override
public int doStartTag() throws JspException {
init();
return super.EVAL_BODY_INCLUDE;
}
//处理方法
@Override
public int doEndTag() throws JspException {
try {
StringBuffer sb=new StringBuffer();
sb.append("<select>");
if(flag=="0") {
sb.append("<option value =\"shanxi\">山西</option>");
sb.append("<option value =\"beijing\">北京</option>");
sb.append("<option value=\"shanghai\">上海</option>");
sb.append("</select>");
}else {
sb.append("<option value =\"shanxi\">山西1</option>");
sb.append("<option value =\"beijing\">北京1</option>");
sb.append("<option value=\"shanghai\">上海1</option>");
sb.append("</select>");
}
out.print(sb.toString());
}catch (Exception e) {
// TODO: handle exception
}
return super.EVAL_PAGE;
}
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
}
为了简化标签开发的复杂度,在JSP 2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现标签的功能。一般地,我们做开发都是继承SimpleTagSupport类(该类实现了SimpleTag)来编写自定义标签。
实现了SimpeTag接口的标签称之为简单标签:
public class SimpSelectButton extends SimpleTagSupport {
private String flag;
@Override
public void doTag() throws JspException, IOException {
StringBuffer sb = new StringBuffer();
sb.append("<select>");
if (flag == "0") {
sb.append("<option value =\"shanxi\"><--简单的标签实现方式--></option>");
sb.append("<option value =\"shanxi\">山西</option>");
sb.append("<option value =\"beijing\">北京</option>");
sb.append("<option value=\"shanghai\">上海</option>");
sb.append("</select>");
} else {
sb.append("<option value =\"shanxi\">山西1</option>");
sb.append("<option value =\"beijing\">北京1</option>");
sb.append("<option value=\"shanghai\">上海1</option>");
sb.append("</select>");
}
this.getJspContext().getOut().write(sb.toString());
}
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
}
在WEB-INF目录下创建tld(Tag Library Descriptor)文件,在tld文件中对标签处理类(实现Tag接口的Java类)进行描述
<?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 http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>自定义标签库</description>
<display-name>author functions</display-name>
<tlib-version>1.0</tlib-version>
<short-name>author</short-name>
<uri>/author</uri>
<tag>
<description><![CDATA[Render a select element]]></description>
<name>select</name>
<tag-class>com.qiyun.SelectButton</tag-class> <!-- 注意这里是自己定义的标签类(处理你自己的标签内容)-->
<body-content>JSP</body-content>
<attribute>
<description><![CDATA[The css class to use for element]]></description>
<name>flag</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
<tag>
<description><![CDATA[Render a select element]]></description>
<name>simpselect</name>
<tag-class>com.qiyun.SimpSelectButton</tag-class> <!-- 注意这里是自己定义的标签类(处理你自己的标签内容)-->
<body-content>empty</body-content>
<attribute>
<description><![CDATA[The css class to use for element]]></description>
<name>flag</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>
自定义标签的使用:
如果要使用tag标签,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明)
<%@taglib prefix="author" uri="/author" %>
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。
prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。
引用自定义标签的简单使用:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="author" uri="/author" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>练习自定义标签TLD的用法</title>
</head>
<body>
<div><author:select flag="0"></author:select> </div>
<div><author:simpselect flag="0"></author:simpselect> </div>
</body>
</html>
自定义函数:
自定义函数也是自定义标签的一种,只是更加简单。
编写自定义函数的步骤:
1.编写一个实现function接口的Java类【标签处理器类】;
2.在WEB-INF目录下创建tld(Tag Library Descriptor)文件,在tld文件中对标签处理类(实现function接口的Java类)进行描述;
自定义函数TLD文件配置属性说明:
taglib子元素说明:
tlib-version:标签库的版本
jsp-version:这个标签库要求的JSP规范版本
short-name:JSP页面编写工具可以用来创建助记名的可选名字
uri:唯一标识该标签库的的URI
display-name:将由工具显示的可选名
description:可选的标签特定信息
listener:一个tag库可能定义一些类做为它的事件侦听类,这些类在TLD中被称为listener 元素,jsp服务器将会实例化这些侦听类,并且注册它们。Listener元素中有一个叫listener-class的子元素,这个元素的值必须是该侦听类的完整类名。
function子元素说明:
description:可选的标签特定信息
name:独一无二的元素名
function-class:定义函数处理类
function-signature:定义函数的对应方法
实例:执行标签具体的方法的类
实例:编写执行标签具体的方法的类:
public class Tools {
/**
* 获取当前用户权限
*/
public static String getUserAuthor(String menuId) {
return menuId;
}
}
在WEB-INF目录下创建tld(Tag Library Descriptor)文件,在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 http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>自定义标签库</description>
<display-name>author functions</display-name>
<tlib-version>1.0</tlib-version>
<short-name>author</short-name>
<uri>/author</uri>
<function>
<description>取得用户权限</description>
<name>author</name>
<function-class>com.qiyun.Tools</function-class>
<function-signature>java.lang.String getUserAuthor(java.lang.String)</function-signature>
</function>
</taglib>
自定义函数的使用:
如果要使用自定义函数,与自定义标签一样,则应用JSP的taglib指示符来指定其tag库(注意:taglib要在在使用此tag标签之前声明)
<%@taglib prefix="author" uri="/author" %>
uri属性定义了唯一的标签库描述(以下简称TLD),它可以是直接是tld文件名或一个独一无二的名字。
prefix是用来区别其它TLD中和本TLD中有重名的tag的一种手段。
TLD必须以.tld作为扩展名,并且存放在当前应用的WEB-INF目录或其子目录下。你可以通过它的文件名直接引用它,也可以通过别的方式间接地引用它。
引用自定义标签的简单使用:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="author" uri="/author" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>练习自定义标签TLD的用法</title>
</head>
<body>
<button class="${author:author('button1')}">${author:author('button')}</button>
<h1 class="hidden">这是一个隐藏标题</h1>
<h1>这是一个标题</h1>
</body>
</html>
<style>
button.button{
display: none;
}
h1.hidden {display:none;}
</style>