自定义标签

第一建立一个java类:

public class HelloWorldTag extends SimpleTagSupport

{

    //重写doTag方法,该方法在标签结束生成页面内容

    public void doTag()throws JspException,

        IOException

    {

        //获取页面输出流,并输出字符串

        getJspContext().getOut().write("Hello World "

            + new java.util.Date());

    }

}

2.建立TLD(Tag Library Definition)文件:

<?xml version="1.0" encoding="GBK"?>



<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">

    <tlib-version>1.0</tlib-version>

    <short-name>mytaglib</short-name>

    <!-- 定义该标签库的URI -->

    <uri>/mytaglib</uri>



    <!-- 定义第一个标签 -->

    <tag>

        <!-- 定义标签名 -->

        <name>helloWorld</name>

        <!-- 定义标签处理类 -->

        <tag-class>lee.HelloWorldTag</tag-class>

        <!-- 定义标签体为空 -->

        <body-content>empty</body-content>

    </tag>

  </taglib>

标签库的使用:

第一:前提条件:
1.标签库URI:确定使用那个标签库。

2标签名:确定使用那个标签。

步骤:

1导入标签库

<%@ taglib uri="tagliburi" prefix="tagPrefix"%>

2在jsp页面中使用标签

<tagPrefix:tagName tagAttribute="tagValue" ...>

<tagBody/>

</tagPrefix:tagName>

实例:根据上文建立的tld,编写如下jsp页面

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>

<!-- 导入标签库,指定mytag前缀的标签,由http://www.crazyit.org/mytaglib的标签库处理 -->

<%@ taglib uri="/mytaglib" prefix="mytag"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <title>自定义标签示范</title>

    <meta name="website" content="http://www.crazyit.org" />

</head>

<body bgcolor="#ffffc0">

<h2>下面显示的是自定义标签中的内容</h2>

<!-- 使用标签 ,其中mytag是标签前缀,根据taglib的编译指令,
mytag前缀将由http://www.crazyit.org/mytaglib的标签库处理 -->

<mytag:helloWorld/><br/>

</body>

</html>

还要加上一步:

在web.xml文件中添加引入代码:

    <jsp-config>

        <taglib>

            <taglib-uri>/mytaglib</taglib-uri>

            <taglib-location>/WEB-INF/mytaglib.tld</taglib-location>

        </taglib>

    </jsp-config>

带属性的标签:

 

<!-- 定义第二个标签 -->

    <tag>

        <!-- 定义标签名 -->

        <name>query</name>

        <!-- 定义标签处理类 -->

        <tag-class>lee.QueryTag</tag-class>

        <!-- 定义标签体为空 -->

        <body-content>empty</body-content>

        <!-- 配置标签属性:driver -->

        <attribute>

            <name>driver</name> 

            <required>true</required>

            <fragment>true</fragment>

        </attribute>

        <!-- 配置标签属性:url -->

        <attribute>

            <name>url</name> 

            <required>true</required>

            <fragment>true</fragment>

        </attribute>

        <!-- 配置标签属性:user -->

        <attribute>

            <name>user</name> 

            <required>true</required>

            <fragment>true</fragment>

        </attribute>

        <!-- 配置标签属性:pass -->

        <attribute>

            <name>pass</name> 

            <required>true</required>

            <fragment>true</fragment>

        </attribute>

        <!-- 配置标签属性:sql -->

        <attribute>

            <name>sql</name> 

            <required>true</required>

            <fragment>true</fragment>

        </attribute>

    </tag>

java代码清单:

public class QueryTag extends SimpleTagSupport

{

    //标签的属性

     
private String driver;

    private String url;

    private String user;

    private String pass;

    private String sql;



    //setter和getter方法省略

    //执行数据库访问的对象 

    private Connection conn = null;

    private Statement stmt = null;

    private ResultSet rs = null;

    private ResultSetMetaData rsmd = null;

    public void doTag()throws JspException,

        IOException

    {

           try

        {

            //注册驱动

            Class.forName(driver);

            //获取数据库连接

            conn = DriverManager.getConnection(url,user,pass);

            //创建Statement对象

            stmt = conn.createStatement();

            //执行查询

            rs = stmt.executeQuery(sql);

            rsmd = rs.getMetaData();

            //获取列数目

            int columnCount = rsmd.getColumnCount();

            //获取页面输出流

            Writer out = getJspContext().getOut();

            //在页面输出表格

            out.write("<table border='1' bgColor='#9999cc' width='400'>");

            //遍历结果集

            while (rs.next())

            {

                out.write("<tr>");

                //逐列输出查询到的数据

                for (int i = 1 ; i <= columnCount ; i++ )

                {

                    out.write("<td>");

                    out.write(rs.getString(i));

                    out.write("</td>");

                }

                out.write("</tr>");

            }

        }

        catch(ClassNotFoundException cnfe)

        {

            cnfe.printStackTrace();

            throw new JspException("自定义标签错误" + cnfe.getMessage());

        }

        catch (SQLException ex)

        {

            ex.printStackTrace();

            throw new JspException("自定义标签错误" + ex.getMessage());

        }

        finally

        {

            //关闭结果集

            try

            {

                if (rs != null)

                    rs.close();

                if (stmt != null)

                    stmt.close();

                if (conn != null)

                    conn.close();

            }

            catch (SQLException sqle)

            {

                sqle.printStackTrace();

            }

        }

    }

}

带标签体的标签:

tld内容:

    <!-- 定义第三个标签 -->

    <tag>

        <!-- 定义标签名 -->

        <name>iterator</name>

        <!-- 定义标签处理类 -->

        <tag-class>lee.IteratorTag</tag-class>

        <!-- 定义标签体不允许出现JSP脚本 -->

        <body-content>scriptless</body-content>

        <!-- 配置标签属性:collection -->

        <attribute>

            <name>collection</name> 

            <required>true</required>

            <fragment>true</fragment>

        </attribute>

        <!-- 配置标签属性:item -->

        <attribute>

            <name>item</name> 

            <required>true</required>

            <fragment>true</fragment>

        </attribute>

    </tag>
package org.sh.com.tag;



import javax.servlet.jsp.tagext.*;

import javax.servlet.jsp.*;

import java.io.*;

import java.util.*;



public class IteratorTag extends SimpleTagSupport {

    // 标签属性,用于指定需要被迭代的集合

    private String collection;

    // 标签属性,指定迭代集合元素,为集合元素指定的名称

    private String item;



    // collection属性的setter和getter方法

    public void setCollection(String collection) {

        this.collection = collection;

    }



    public String getCollection() {

        return this.collection;

    }



    // item属性的setter和getter方法

    public void setItem(String item) {

        this.item = item;

    }



    public String getItem() {

        return this.item;

    }



    // 标签的处理方法,简单标签处理类只需要重写doTag方法

    public void doTag() throws JspException, IOException {

        // 从page scope中获取属性名为collection的集合

        Collection itemList = (Collection) getJspContext().getAttribute(

                collection);

        // 遍历集合

        for (Object s : itemList) {

            // 将集合的元素设置到page 范围

            getJspContext().setAttribute(item, s);

            // 输出标签体

            getJspBody().invoke(null);

        }

    }

}
jsp页面:
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>

<%@ page import="java.util.*"%>

<!-- 导入标签库,指定mytag前缀的标签,

由http://www.crazyit.org/mytaglib的标签库处理 -->

<%@ taglib uri="/mytaglib" prefix="mytag"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <title> 带标签体的标签-迭代器标签 </title>

    <meta name="website" content="http://www.crazyit.org" />

</head>

<body>

    <h2>带标签体的标签-迭代器标签</h2><hr/>

    <%

    //创建一个List对象

    List<String> a = new ArrayList<String>();

    a.add("疯狂Java");

    a.add("www.crazyit.org");

    a.add("java");

    //将List对象放入page范围内

    pageContext.setAttribute("a" , a);

    %>

    <table border="1" bgcolor="#aaaadd" width="300">

        <!-- 使用迭代器标签,对a集合进行迭代 -->

        <mytag:iterator collection="a" item="item">

        <tr>

            <td>${pageScope.item}</td>

        <tr>

        </mytag:iterator>

    </table>

</body>

</html>

以页面片段作为属性的标签:

tld文件:

    <tag>

        <!-- 定义标签名 -->

        <name>fragment</name>

        <!-- 定义标签处理类 -->

        <tag-class>lee.FragmentTag</tag-class>

        <!-- 指定该标签不支持标签体 -->

        <body-content>scriptless</body-content>

        <!-- 定义标签属性:fragment -->

        <attribute>

            <name>fragment</name>

            <required>true</required>

            <fragment>true</fragment>

        </attribute>

    </tag>

java文件:

public class FragmentTag extends SimpleTagSupport 

{

    private JspFragment fragment;

    

    //fragment属性的setter和getter方法

    public void setFragment(JspFragment fragment)

    {

        this.fragment = fragment;

    }

    public JspFragment getFragment()

    {

        return this.fragment;

    }

    @Override

    public void doTag() throws JspException, IOException

    {

        JspWriter out = getJspContext().getOut();

        out.println("<div style='padding:10px;border:1px solid black'>");

        out.println("<h3>下面是动态传入的JSP片段</h3>");

        //调用、输出“页面片段”

        fragment.invoke( null );

        out.println("</div");

    }

}

jsp文件:

<%@ page contentType="text/html; charset=GBK" language="java"

    errorPage=""%>

<!-- 导入标签库,指定mytag前缀的标签,

    由http://www.crazyit.org/mytaglib的标签库处理 -->

<%@ taglib uri="/mytaglib" prefix="mytag"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>自定义标签示范</title>

<meta name="website" content="http://www.crazyit.org" />

</head>

<body bgcolor="#ffffc0">

    <h2>下面显示的是自定义标签中的内容</h2>

    <mytag:fragment>

        <jsp:attribute name="fragment">

            <mytag:helloWorld />

        </jsp:attribute>

    </mytag:fragment>

    <br />

    <mytag:fragment>

        <jsp:attribute name="fragment">

            ${pageContext.request.remoteAddr}

        </jsp:attribute>

    </mytag:fragment>

</body>

</html>
注意:如果在 < mytag:fragment > 里面加上注释会出现“According to TLD, tag mytag:fragment must be empty, but is not”错误,

把<mytag:fragment> 开始标签
与</mytag:fragment>结束标签之间的注释全部去掉——HTML注释、JSP注释都要去掉。
——最新版本的Tomcat不允许此处出现注释

动态属性的标签:

动态属性的标签比普通标签多了如下两个额外的要求:

-->标签处理累还需要实现DynamivAttributes接口。

-->配置标签是通过<dynamic-attributes…/>子元素制定该标签支持动态属性

下面一个例子:

java代码:

public class DynaAttributesTag extends SimpleTagSupport implements

        DynamicAttributes {

    // 保存每个属性名的集合

    private ArrayList<String> keys = new ArrayList<String>();

    // 保存每个属性值的集合

    private ArrayList<Object> values = new ArrayList<Object>();



    @Override

    public void doTag() throws JspException, IOException {

        JspWriter out = getJspContext().getOut();

        // 此处只是简单地输出每个属性

        out.println("<ol>");

        for (int i = 0; i < keys.size(); i++) {

            String key = keys.get(i);

            Object value = values.get(i);

            out.println("<li>" + key + " = " + value + "</li>");

        }

        out.println("</ol>");

    }



    @Override

    public void setDynamicAttribute(String uri, String localName, Object value)

            throws JspException {

        // 添加属性名

        keys.add(localName);

        // 添加属性值

        values.add(value);

    }

}

TLD代码:

    <!-- 定义接受动态属性的标签 -->

    <tag>

        <name>dynaAttr</name>

        <tag-class>org.sh.com.tag.DynaAttributesTag</tag-class>

        <body-content>empty</body-content>

        <!-- 指定支持动态属性 -->

        <dynamic-attributes>true</dynamic-attributes>

    </tag>

JSP代码:
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>

<!-- 导入标签库,指定mytag前缀的标签,

    由http://www.crazyit.org/mytaglib的标签库处理 -->

<%@ taglib uri="http://www.crazyit.org/mytaglib" prefix="mytag"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <title>自定义标签示范</title>

    <meta name="website" content="http://www.crazyit.org" />

</head>

<body bgcolor="#ffffc0">

<h2>下面显示的是自定义标签中的内容</h2>

<h4>指定两个属性</h4>

<mytag:dynaAttr name="crazyit" url="crazyit.org"/><br/>

<h4>指定四个属性</h4>

<mytag:dynaAttr 书名="疯狂Java讲义" 价格="99.0"

    出版时间="2008年" 描述="Java图书"/><br/>

</body>

</html>


另注:body-content取值的意义 转自:http://blog.csdn.net/aaa1117a8w5s6d/article/details/8157212

body-content的值有下面4种:

<xsd:enumeration value="tagdependent"/>



 <xsd:enumeration value="JSP"/>



 <xsd:enumeration value="empty"/>



 <xsd:enumeration value="scriptless"/>

tagdependent:标签体内容直接被写入BodyContent,由自定义标签类来进行处理,而不被JSP容器解释,

如下:

<test:myList>



select name,age from users



</test:myList>

JSP:接受所有JSP语法,如定制的或内部的tag、scripts、静态HTML、脚本元素、JSP指令和动作。如:

<my:test>



 <%=request.getProtocol()%>  // ②



</my:test>

具体可参考后面附源码。

empty:空标记,即起始标记和结束标记之间没有内容。

下面几种写法都是有效的,

<test:mytag />



<test:mytag uname="Tom" />



<test:mytag></test:mytag>

scriptless:接受文本、EL和JSP动作。如上述使用<body-content> scriptless </body-content>则报错,具体可参考后面附源码。

你可能感兴趣的:(自定义标签)