zoukankan      html  css  js  c++  java
  • 自定义标签

    第一建立一个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>则报错,具体可参考后面附源码。

  • 相关阅读:
    Java多线程(3) Volatile的实现原理
    Java 多线程(2)-Executor
    Java 多线程(1)-Thread和Runnable
    nginx+php部署
    MySQL的慢查询分析
    MySQL 错误
    log4j.properties配置详解
    Windows下Nginx的安装与配置(转)
    Java 字符的验证
    Spring MVC3返回JSON数据中文乱码问题解决(转)
  • 原文地址:https://www.cnblogs.com/sunhan/p/3800826.html
Copyright © 2011-2022 走看看