Java Web总结十六之一自定义标签
一、自定义标签简介
1、为什么要使用自定义标签?
自定义标签主要用于移除Jsp页面中的<%java%>代码。
2、开发自定义标签的步骤:
1)开发自定义标签处理类,该类需要实现SimpleTag接口/SimpleTagSupport类,重写doTag()方法。
2)编写标签库描述符(tld)文件,在tld文件中对自定义标签进行描述,并放置在WEB-INF/目录下。
3)完成以上操作,即可在JSP页面中导入和使用自定义标签。
二、自定义标签描述
1、实现SimpleTag接口的标签通常称为简单标签。简单标签共定义5个方法:
1)setJspContext方法
2)setParent和getParent方法
3)setJspBody方法
4)doTag方法
2、setJspContext方法:用于把JSP页面的pageContext对象传递给标签处理器对象。
3、setParent方法:用于把父标签处理器对象传递给当前标签处理器对象。
4、getParent方法:用于获得当前标签的父标签处理器对象。
5、setJspBody方法:用于把代表标签体的JspFragment对象(即标签体内容)传递给标签处理器对象。
6、doTag方法:用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等。在doTag方法中可以抛出javax.servlet.jsp.SkipPageException异常,用于通知WEB容器不再执行JSP页面中位于结束标记后面的内容。
三、建立TLD文件
1、TLD是Tag Library Definition的缩写,即标签库定义,文件的后缀是tld,每个tld文件对应一个标签库,一个标签库中可包含多个标签。通常我们可以到Web容器下复制一个标签库定义文件,并在此基础上进行修改即可。例如Tomcat 7.0,在webapps\examples\WEB-INF\jsp2路径下包含了一个jsp2-example-taglib.tld文件,这就是一个TLD文件的范例。将该文件复制到Web应用的WEB-INF/路径下,或WEB-INF的任意子路径下,并对该文件进行简单修改,修改后的.tld文件代码如下:
<?xml version="1.0" encoding="ISO-8859-1" ?> <!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>simple</short-name> <uri>http://java.sun.com/jstl/simple</uri> <tag> <name>IP</name> <tag-class>com.gnnuit.web.jsp.tag.IpTag</tag-class> <body-content>empty</body-content> </tag> <tag> <name>Execute</name> <tag-class>com.gnnuit.web.jsp.tag.ExecuteTag</tag-class> <body-content>scriptless</body-content> </tag> <tag> <name>skip</name> <tag-class>com.gnnuit.web.jsp.tag.SkipTag</tag-class> <body-content>scriptless</body-content> </tag> <tag> <name>for1</name> <tag-class>com.gnnuit.web.jsp.tag.For1Tag</tag-class> <body-content>scriptless</body-content> </tag> <tag> <name>up</name> <tag-class>com.gnnuit.web.jsp.tag.UpTag</tag-class> <body-content>scriptless</body-content> </tag> <tag> <name>for2</name> <tag-class>com.gnnuit.web.jsp.tag.For2Tag</tag-class> <body-content>scriptless</body-content> <attribute> <name>count</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <tag> <name>for3</name> <tag-class>com.gnnuit.web.jsp.tag.For3Tag</tag-class> <body-content>scriptless</body-content> <attribute> <name>var</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>begin</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>end</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>step</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <tag> <name>referer</name> <tag-class>com.gnnuit.web.jsp.tag.ReferenceTag</tag-class> <body-content>scriptless</body-content> <attribute> <name>url</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>error</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
2、taglib下有如下三个子元素:
1)tlib-version:指定该标签库实现的版本,这是一个作为标识的内部版本号,对程序没有太大的作用。
2)short-name:该标签库的默认短名,该名称通常也没有太大的用处。
3)uri:这个属性非常重要,它指定标签库的URI,相当于指定该标签库的唯一标识,JSP页面中使用标签库时就是根据该URI属性来定位标签库的。
3、taglib元素可以包含多个tag元素,每个tag元素定义一个标签,tag元素下允许出现如下常用子元素。
1)name:该标签库的名称,这个子元素很重要,JSP页面中就是根据该名称来使用此标签的。
2)tag-class:指定标签的处理类,这个子元素很重要,它指定了标签由哪个标签处理类来处理。
3)body-content:这个子元素也很重要,它指定标签体内容。该子元素的值可以是如下几个:
a、tagdependent:指定标签处理类自己负责处理标签体。
b、empty:指定该标签只能作为空标签使用。
c、scriptless:指定该标签的标签体可以是静态HTML元素、表达式语言,但不允许出现JSP脚本。
d、JSP:指定该标签的标签体可以使用JSP脚本。实际上该值不可以使用。
e、dynamic-attributes:指定该标签是否支持动态属性。只有当定义动态属性标签时才需要该子元素。
4、对于有属性的标签,需要为<tag.../>元素增加<attribute.../>子元素,每个attribute子元素定义一个标签属性。<attribute.../>子元素通常还需要指定如下几个子元素。
1)name:设置属性名,子元素的值时字符串内容。
2)required:设置该属性是否为必须属性,该子元素的值时true或false。
3)fragment:设置该属性是否支持JSp脚本、表达式等动态内容,子元素的值是true或false。
四、案例:自定义标签的开发步骤:
1 写一个标签处理类
//标签处理类
public class IpTag implements SimpleTag
{
private PageContext pageContext;
//Web容器调用NO1
public void
setJspContext(JspContext pc)
{
System.out.println("setJspContext()");
pageContext = (PageContext)
pc;
}
//Web容器调用NO2
public void doTag() throws JspException,
IOException
{
System.out.println("doTag()");
//取得HttpServletRequest请求对象
HttpServletRequest
request = (HttpServletRequest)
pageContext.getRequest();
//取得客户端的IP地址
String ip =
request.getRemoteAddr();
//取得out(JspWriter)对象
JspWriter out =
pageContext.getOut();
//向浏览器输出
out.write("<font size=‘44‘
color=‘red‘>"+ip+"</font>");
}
...
}
2 在/WEB-INF/目录下,写一个*.tld文件,目的是让Web容器知道自定义标签和标签处理类的对应关系
<?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">
<tlib-version>1.0</tlib-version>
<short-name>simple</short-name>
<uri>http://java.sun.com/jsp/jstl/simple</uri>
<tag>
<name>ip</name>
<tag-class>cn.itcast.web.jsp.tag.IpTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
3 在JSP页面中,通过<%@taglib%>指令引用标签库
<%@ page language="java"
pageEncoding="UTF-8"%>
<%@ taglib
uri="http://java.sun.com/jsp/jstl/simple" prefix="simple" %>
<!DOCTYPE
HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<body>
客户端IP为:<simple:ip/>
</body>
</html>
4 部署web应用,访问simple.jsp即可