首页 > 代码库 > Java Web总结十六之一自定义标签

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即可