• jsp自定义标签


          我们在Javaweb中常常会用到一些jsp的标签,比如<c:foreach>、<c:if>、<fmt:formatDate>等标签,但是sun公司提供的这些标签虽然能够满足我们大部分的应用需求,但是对于一些特殊应用需求就不能满足了,这时候我们就需要自定义一些我们自己的标签库。要开始编写我们自定义的标签库之前,我们需要了解下自定义标签的作用是什么和自定义标签的实现骤是什么?然后采用对应的步骤针对这几个作用来进行自定义标签的学习和应用。

    1.自定义标签的作用

    ①用于移除jsp页面的Java代码。

    ②控制jsp页面某一部分内容是否执行(内容权限控制) 

    ③控制整个jsp页面是否执行(页面权限控制) 

    ④控制jsp页面内容(标签体)重复执行 

    ⑤修改jsp页面的内容输出 

    2.自定义标签的实现步骤

    ①编写一个实现了Tag接口的Java类,把页面Java代码移到这个Java类中(标签处理器类)

    ②在项目的WEB-INF目录或者子目录下编写标签库(tld)文件,在tld文件中把标签处理器类描述成一个标签。

    可以从下面的标签描述文件中摘抄相关的配置信息

    <?xml version="1.0" encoding="UTF-8" ?>
    <!--
     Licensed to the Apache Software Foundation (ASF) under one or more
      contributor license agreements.  See the NOTICE file distributed with
      this work for additional information regarding copyright ownership.
      The ASF licenses this file to You under the Apache License, Version 2.0
      (the "License"); you may not use this file except in compliance with
      the License.  You may obtain a copy of the License at
    
          http://www.apache.org/licenses/LICENSE-2.0
    
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.
    -->
    
    <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>A tag library exercising SimpleTag handlers.</description>
        <tlib-version>1.0</tlib-version>
        <short-name>SimpleTagLibrary</short-name>
        <uri>http://tomcat.apache.org/jsp2-example-taglib</uri>
        <tag>
            <description>Outputs Hello, World</description>
            <name>helloWorld</name>
            <tag-class>jsp2.examples.simpletag.HelloWorldSimpleTag</tag-class>
            <body-content>empty</body-content>
        </tag>
        <tag>
            <description>Repeats the body of the tag 'num' times</description>
            <name>repeat</name>
            <tag-class>jsp2.examples.simpletag.RepeatSimpleTag</tag-class>
            <body-content>scriptless</body-content>
            <variable>
                <description>Current invocation count (1 to num)</description>
                <name-given>count</name-given>
            </variable>
            <attribute>
                <name>num</name>
                <required>true</required>
                <rtexprvalue>true</rtexprvalue>
            </attribute>
        </tag>
        <tag>
            <description>Populates the page context with a BookBean</description>
            <name>findBook</name>
            <tag-class>jsp2.examples.simpletag.FindBookSimpleTag</tag-class>
            <body-content>empty</body-content>
            <attribute>
                <name>var</name>
                <required>true</required>
                <rtexprvalue>true</rtexprvalue>
            </attribute>
        </tag>
        <tag>
            <description>
                Takes 3 fragments and invokes them in a random order
            </description>
            <name>shuffle</name>
            <tag-class>jsp2.examples.simpletag.ShuffleSimpleTag</tag-class>
            <body-content>empty</body-content>
            <attribute>
                <name>fragment1</name>
                <required>true</required>
                <fragment>true</fragment>
            </attribute>
            <attribute>
                <name>fragment2</name>
                <required>true</required>
                <fragment>true</fragment>
            </attribute>
            <attribute>
                <name>fragment3</name>
                <required>true</required>
                <fragment>true</fragment>
            </attribute>
        </tag>
        <tag>
            <description>Outputs a colored tile</description>
            <name>tile</name>
            <tag-class>jsp2.examples.simpletag.TileSimpleTag</tag-class>
            <body-content>empty</body-content>
            <attribute>
                <name>color</name>
                <required>true</required>
            </attribute>
            <attribute>
                <name>label</name>
                <required>true</required>
            </attribute>
        </tag>
        <tag>
            <description>
              Tag that echoes all its attributes and body content
            </description>
            <name>echoAttributes</name>
            <tag-class>jsp2.examples.simpletag.EchoAttributesTag</tag-class>
            <body-content>empty</body-content>
            <dynamic-attributes>true</dynamic-attributes>
        </tag>
        <function>
            <description>Reverses the characters in the given String</description>
            <name>reverse</name>
            <function-class>jsp2.examples.el.Functions</function-class>
            <function-signature>java.lang.String reverse( java.lang.String )</function-signature>
        </function>
        <function>
            <description>Counts the number of vowels (a,e,i,o,u) in the given String</description>
            <name>countVowels</name>
            <function-class>jsp2.examples.el.Functions</function-class>
            <function-signature>java.lang.String numVowels( java.lang.String )</function-signature>
        </function>
        <function>
            <description>Converts the string to all caps</description>
            <name>caps</name>
            <function-class>jsp2.examples.el.Functions</function-class>
            <function-signature>java.lang.String caps( java.lang.String )</function-signature>
        </function>
    </taglib>

    一、传统自定义标签

    (一).传统自定义标签库的类结构图

    (二) jsp执行自定义标签的调用图

     

    (三)使用传统自定义标签的案例

    1.移除jsp页面的Java代码——显示访问用户的ip的自定义标签

    ①原先嵌入Java的代码的jsp页面

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>嵌入Java代码来显示用户的ip</title>
    </head>
    <body>
        您的ip是:
        <%
        String ip = request.getRemoteAddr().toString();
        out.write(ip);
    %>
    </body>
    </html>

    ②编写Java标签处理器类需实现tag接口,将页面的Java代码移到该类中

    package com.tag;
    
    import java.io.IOException;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.JspWriter;
    import javax.servlet.jsp.tagext.Tag;
    import javax.servlet.jsp.tagext.TagSupport;
    
    /**
     * 自定义获取ip的标签
     * 
     * @author Administrator
     *
     */
    public class IpTag extends TagSupport {
    
        private static final long serialVersionUID = 1L;
    
        @Override
        public int doStartTag() throws JspException {
            // 获取request对象
            HttpServletRequest request = (HttpServletRequest) this.pageContext.getRequest();
            // 获取输出对象
            JspWriter out = this.pageContext.getOut();
            String ip = request.getRemoteAddr();
            try {
                // 将结果输出到浏览器
                out.write(ip);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            //没有标签体,所有返回Tag.SKIP_BODY
            return Tag.SKIP_BODY;
        }
    
    }

    ③编写tld文件并在里面描述我们的标签处理器类,我的文件为zjc.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>A tag library exercising SimpleTag handlers.</description>
        <tlib-version>1.0</tlib-version>
        <short-name>zjc</short-name>
        <!-- 配置uri,在jsp页面引入tablib 会用到 -->
        <uri>/mytag</uri>
        <tag>
            <!-- 标签的名称 -->
            <name>ip</name>
            <!-- 标签处理器类的全类名 -->
            <tag-class>com.tag.IpTag</tag-class>
            <!-- 因为没有标签体,所有设为empty -->
            <body-content>empty</body-content>
        </tag>
    </taglib>

    ④在jsp页面引入我们自定义的标签库即可使用

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%-- 引入我们自定义的标签库--%> 
    <%@ taglib uri="/mytag" prefix="zjc"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>显示ip</title>
    </head>
    <body>
        <%--使用我们自定义的标签 --%>
        您的ip是:
        <zjc:ip></zjc:ip>
    </body>
    </html>

    2.控制jsp页面某一部分内容是否执行(内容权限控制)

    ①编写Java处理器类需实现Tag接口

    package com.tag;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.Tag;
    import javax.servlet.jsp.tagext.TagSupport;
    
    /**
     * 控制是否显示标签体
     * 
     * @author Administrator
     *
     */
    public class ControlContentTag extends TagSupport {
    
        @Override
        public int doStartTag() throws JspException {
            //这里定义了一个随机数
            int random = (int) (Math.random() * 100);
            //如果是偶数就显示标签体,否则不显示
            if (random % 2 == 0) {
                return Tag.EVAL_BODY_INCLUDE;
            } else {
                return Tag.SKIP_BODY;
            }
        }
    
    }

    ②编写tld文件并在里面描述我们的标签处理器类,我的文件为zjc.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>A tag library exercising SimpleTag handlers.</description>
        <tlib-version>1.0</tlib-version>
        <short-name>zjc</short-name>
        <!-- 配置uri,在jsp页面引入tablib 会用到 -->
        <uri>/mytag</uri>
               <tag>
            <!-- 标签的名称 -->
            <name>content</name>
            <!-- 标签处理器类的全类名 -->
            <tag-class>com.tag.ControlContentTag</tag-class>
            <!-- 有标签体设置为jsp -->
            <body-content>JSP</body-content>
        </tag>  
    </taglib>

     ③在jsp页面引入我们自定义的标签库即可使用

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%-- 引入我们自定义的标签库--%>
    <%@ taglib uri="/mytag" prefix="zjc"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>控制标签体内容是否显示</title>
    </head>
    <body>
        控制是否显示
        <%--使用自定义标签控制标签体是否显示 --%>
        <zjc:content>内容</zjc:content>
    </body>
    </html>

     3.控制整个jsp页面是否执行(页面权限控制) 

    ①编写Java处理器类需实现Tag接口

    package com.tag;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.Tag;
    import javax.servlet.jsp.tagext.TagSupport;
    
    /**
     * 控制是否显示页面
     * 
     * @author Administrator
     *
     */
    public class ControlPageTag extends TagSupport {
    
        @Override
        public int doEndTag() throws JspException {
            //定义一个随机数,来模拟效果
            int random = (int) (Math.random() * 100);
            //为偶数就显示页面,否则就不显示
            if (random % 2 == 0) {
                return Tag.EVAL_PAGE;
            } else {
                return Tag.SKIP_PAGE;
            }
        }
    
    }

    ②编写tld文件并在里面描述我们的标签处理器类,我的文件为zjc.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>A tag library exercising SimpleTag handlers.</description>
        <tlib-version>1.0</tlib-version>
        <short-name>zjc</short-name>
        <!-- 配置uri,在jsp页面引入tablib 会用到 -->
        <uri>/mytag</uri>
            <tag>        
           <!-- 标签的名称 -->
            <name>page</name>
            <!-- 标签处理器类的全类名 -->
            <tag-class>com.tag.ControlPageTag</tag-class>
            <!-- 因为没有标签体,所有设为empty -->
            <body-content>empty</body-content>
        </tag>
    </taglib>

    ③在jsp页面引入我们自定义的标签库即可使用

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%-- 引入我们自定义的标签库--%>
    <%@ taglib uri="/mytag" prefix="zjc"%>
    <zjc:page />
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>控制页面内容是否显示</title>
    </head>
    <body>
        <h1>控制页面内容是否显示</h1>
    </body>
    </html>

    3.控制jsp页面内容(标签体)重复执行

    ①编写Java处理器类需实现Tag接口

    package com.tag;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.IterationTag;
    import javax.servlet.jsp.tagext.Tag;
    import javax.servlet.jsp.tagext.TagSupport;
    
    /**
     * 控制重复执行
     * 
     * @author Administrator
     *
     */
    public class RepeatContent extends TagSupport {
        // time用来控制执行的次数
        private int time = 0;
    
        @Override
        public int doStartTag() throws JspException {
            // 返回包含标签体,继续往下执行
            return Tag.EVAL_BODY_INCLUDE;
    
        }
    
        @Override
        public int doEndTag() throws JspException {
            return Tag.EVAL_PAGE;
        }
    
        /**
         * 在标签体之后执行
         */
        @Override
        public int doAfterBody() throws JspException {
            // 这里控制标签体执行几次,返回EVAL_BODY_AGAIN,表示重新执行标签体
            if (time++ < 10) {
                return IterationTag.EVAL_BODY_AGAIN;
            }
            // 恢复初始值
            time = 0;
    
            // 跳过标签体
            return Tag.SKIP_BODY;
        }
    
    }

    ②编写tld文件并在里面描述我们的标签处理器类,我的文件为zjc.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>A tag library exercising SimpleTag handlers.</description>
        <tlib-version>1.0</tlib-version>
        <short-name>zjc</short-name>
        <!-- 配置uri,在jsp页面引入tablib 会用到 -->
        <uri>/mytag</uri>
            <tag>
             <!-- 标签的名称 -->
            <name>repeate</name>
            <!-- 标签处理器类的全类名 -->
            <tag-class>com.tag.RepeatContent</tag-class>
            <!-- 有标签体设置为jsp -->
            <body-content>JSP</body-content>
        </tag>    
    </taglib>

    ③在jsp页面引入我们自定义的标签库即可使用

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%-- 引入我们自定义的标签库--%>
    <%@ taglib uri="/mytag" prefix="zjc"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>控制页面(标签体)内容重复执行</title>
    </head>
    <body>
        重复显示内容
        <zjc:repeate>
            <br />哈哈</zjc:repeate>
    </body>
    </html>

    3.修改jsp页面的内容输出 

    ①编写Java处理器类需实现Tag接口

    package com.tag;
    
    import java.io.IOException;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.BodyContent;
    import javax.servlet.jsp.tagext.BodyTag;
    import javax.servlet.jsp.tagext.BodyTagSupport;
    import javax.servlet.jsp.tagext.Tag;
    
    /**
     * 修改标签体的内容,这里做了个大写转换
     * 
     * @author Administrator
     *
     */
    public class ChangeContent extends BodyTagSupport {
    
        @Override
        public int doStartTag() throws JspException {
            // 返回这个字段EVAL_BODY_BUFFERED,服务器就会调用setBodyContent方法,把标签体的内容传递进来
            return BodyTag.EVAL_BODY_BUFFERED;
        }
        @Override
        public int doEndTag() throws JspException {
            // 获取标签体的内容
            BodyContent content = this.getBodyContent();
            String contentStr = content.getString();
            System.out.println(contentStr);
            // 开始修改
            contentStr = contentStr.toUpperCase();
            // 获取out对象返回给浏览器
            try {
                this.pageContext.getOut().write(contentStr);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return Tag.EVAL_PAGE;
        }
    
    }

    ②编写tld文件并在里面描述我们的标签处理器类,我的文件为zjc.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>A tag library exercising SimpleTag handlers.</description>
        <tlib-version>1.0</tlib-version>
        <short-name>zjc</short-name>
        <!-- 配置uri,在jsp页面引入tablib 会用到 -->
        <uri>/mytag</uri>
          <tag>
             <!-- 标签的名称 -->
            <name>change</name>
            <!-- 标签处理器类的全类名 -->
            <tag-class>com.tag.ChangeContent</tag-class>
            <!-- 有标签体设置为jsp -->
            <body-content>JSP</body-content>
        </tag>  
    </taglib>  

    ③在jsp页面引入我们自定义的标签库即可使用

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%-- 引入我们自定义的标签库--%>
    <%@ taglib uri="/mytag" prefix="zjc"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>修改标签体的内容,</title>
    </head>
    <body>
        修改标签体的内容,
        <zjc:change>abcdefg</zjc:change>
    
    </body>
    </html>

    二、简单自定义标签

    (一).简单自定义标签库的类结构图

    (二) jsp执行自定义标签的调用图

     (三)使用简单自定义标签的案例

    1.移除jsp页面的Java代码——显示访问用户的ip的自定义标签

    ①原先嵌入Java的代码的jsp页面

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>嵌入Java代码来显示用户的ip</title>
    </head>
    <body>
        您的ip是:
        <%
        String ip = request.getRemoteAddr().toString();
        out.write(ip);
    %>
    </body>
    </html>

    ②编写Java标签处理器类需实现tag接口,将页面的Java代码移到该类中

    package com.simpletag;
    
    import java.io.IOException;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.JspWriter;
    import javax.servlet.jsp.PageContext;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    
    /**
     * 自定义获取ip的标签
     * 
     * @author Administrator
     *
     */
    public class IpSimpleTag extends SimpleTagSupport {
    
        private static final long serialVersionUID = 1L;
    
        @Override
        public void doTag() throws JspException, IOException {
            // 获取pageContext对象
            PageContext pageContext = (PageContext) this.getJspContext();
            // 获取request对象
            HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
            // 获取输出对象
            JspWriter out = pageContext.getOut();
            String ip = request.getRemoteAddr();
            try {
                out.write(ip);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    
    }

    ③编写tld文件并在里面描述我们的标签处理器类,我的文件为zjc.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>A tag library exercising SimpleTag handlers.</description>
        <tlib-version>1.0</tlib-version>
        <short-name>zjc</short-name>
        <!-- 配置uri,在jsp页面引入tablib 会用到 -->
        <uri>/mytag</uri>
        <tag>
            <!-- 标签的名称 -->
            <name>sip</name>
            <!-- 标签处理器类的全类名 -->
            <tag-class>com.simpletag.IpSimpleTag</tag-class>
            <!-- 因为没有标签体,所有设为empty -->
            <body-content>empty</body-content>
        </tag>
    </taglib>

    ④在jsp页面引入我们自定义的标签库即可使用

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%-- 引入我们自定义的标签库--%>
    <%@ taglib uri="/mytag" prefix="zjc"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>显示ip</title>
    </head>
    <body>
        <%--使用我们自定义的标签 --%>
        您的ip是:
        <zjc:sip></zjc:sip>
    </body>
    </html>

    2.控制jsp页面某一部分内容是否执行(内容权限控制)

    ①编写Java处理器类需实现Tag接口

    package com.simpletag;
    
    import java.io.IOException;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    import javax.servlet.jsp.tagext.Tag;
    import javax.servlet.jsp.tagext.TagSupport;
    
    /**
     * 控制是否显示标签体
     * 
     * @author Administrator
     *
     */
    public class ControlContentSimpleTag extends SimpleTagSupport {
    
        @Override
        public void doTag() throws JspException, IOException {
            //定义随机数,为了做显示效果
            int random = (int) (Math.random() * 100);
            //为偶数不现实标签体,否则则显示
            if (random % 2 == 0) {
                //什么都不做,就是不写任何内容
            } else {
                //将标签体的内容写到浏览器
                this.getJspBody().invoke(this.getJspContext().getOut());
            }
    
        }
    
    }

    ②编写tld文件并在里面描述我们的标签处理器类,我的文件为zjc.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>A tag library exercising SimpleTag handlers.</description>
        <tlib-version>1.0</tlib-version>
        <short-name>zjc</short-name>
        <!-- 配置uri,在jsp页面引入tablib 会用到 -->
        <uri>/mytag</uri>
        <tag>
            <name>scontent</name>
            <tag-class>com.simpletag.ControlContentSimpleTag</tag-class>
            <!-- simpleTag就不能写成jsple,应该写成scriptless -->
            <body-content>scriptless</body-content>
        </tag>
    </taglib>

    ③在jsp页面引入我们自定义的标签库即可使用

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%-- 引入我们自定义的标签库--%>
    <%@ taglib uri="/mytag" prefix="zjc"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>控制标签体内容是否显示</title>
    </head>
    <body>
        控制是否显示
        <%--使用自定义标签控制标签体是否显示 --%>
        <zjc:scontent>内容</zjc:scontent>
    </body>
    </html>

     3.控制整个jsp页面是否执行(页面权限控制) 

    ①编写Java处理器类需实现Tag接口

    package com.simpletag;
    
    import java.io.IOException;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.SkipPageException;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    import javax.servlet.jsp.tagext.Tag;
    import javax.servlet.jsp.tagext.TagSupport;
    
    /**
     * 控制是否显示页面
     * 
     * @author Administrator
     *
     */
    public class ControlPageSimpleTag extends SimpleTagSupport {
    
        @Override
        public void doTag() throws JspException, IOException {
            // 定义随机数,为了演示效果
            int random = (int) (Math.random() * 100);
            // 为偶数抛出SkipPageException,即可不显示余下的页面
            if (random % 2 == 0) {
                throw new SkipPageException();
            } else {
                // 什么也不做,就正常显示
            }
        }
    
    }

    ②编写tld文件并在里面描述我们的标签处理器类,我的文件为zjc.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>A tag library exercising SimpleTag handlers.</description>
        <tlib-version>1.0</tlib-version>
        <short-name>zjc</short-name>
        <!-- 配置uri,在jsp页面引入tablib 会用到 -->
        <uri>/mytag</uri>
         <tag>
            <!-- 标签的名称 -->
            <name>spage</name>
            <!-- 标签处理器类的全类名 -->
            <tag-class>com.simpletag.ControlPageSimpleTag</tag-class>
            <!-- 因为没有标签体,所有设为empty -->
            <body-content>empty</body-content>
        </tag>
    </taglib>

    ③在jsp页面引入我们自定义的标签库即可使用

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%-- 引入我们自定义的标签库--%>
    <%@ taglib uri="/mytag" prefix="zjc"%>
    <zjc:spage />
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>控制页面内容是否显示</title>
    </head>
    <body>
        <h1>控制页面内容是否显示</h1>
    </body>
    </html>

    3.控制jsp页面内容(标签体)重复执行

    ①编写Java处理器类需实现Tag接口

    package com.simpletag;
    
    import java.io.IOException;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.IterationTag;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    import javax.servlet.jsp.tagext.Tag;
    import javax.servlet.jsp.tagext.TagSupport;
    
    /**
     * 控制重复显示标签体
     * 
     * @author Administrator
     *
     */
    public class RepeatContentSimple extends SimpleTagSupport {
    
        @Override
        public void doTag() throws JspException, IOException {
            for (int i = 0; i < 5; i++) {
                //重复输出5遍标签体
                this.getJspBody().invoke(this.getJspContext().getOut());
            }
        }
    
    }

    ②编写tld文件并在里面描述我们的标签处理器类,我的文件为zjc.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>A tag library exercising SimpleTag handlers.</description>
        <tlib-version>1.0</tlib-version>
        <short-name>zjc</short-name>
        <!-- 配置uri,在jsp页面引入tablib 会用到 -->
        <uri>/mytag</uri>
         <tag>
            <!-- 标签的名称 -->
            <name>srepeate</name>
            <!-- 标签处理器类的全类名 -->
            <tag-class>com.simpletag.RepeatContentSimple</tag-class>
            <!-- simpleTag就不能写成jsple,应该写成scriptless -->
            <body-content>scriptless</body-content>
        </tag>
    </taglib>

    ③在jsp页面引入我们自定义的标签库即可使用

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%-- 引入我们自定义的标签库--%>
    <%@ taglib uri="/mytag" prefix="zjc"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>控制页面(标签体)内容重复执行</title>
    </head>
    <body>
        重复显示内容
        <zjc:srepeate>
            <br />哈哈</zjc:srepeate>
    </body>
    </html>

    3.修改jsp页面的内容输出 

    ①编写Java处理器类需实现Tag接口

    package com.simpletag;
    
    import java.io.IOException;
    import java.io.StringWriter;
    
    import javax.servlet.jsp.JspContext;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.JspFragment;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    /**
     * 修改页面的内容,这里做了大写的转换
     * @author Administrator
     *
     */
    public class ChangeContentSimple extends SimpleTagSupport {
    
        @Override
        public void doTag() throws JspException, IOException {
            JspFragment jf = this.getJspBody();
            // 创建一个Stringwriter对象用接收数据
            StringWriter sw = new StringWriter();
            jf.invoke(sw);
            // 获取到数据
            String contentStr = sw.toString();
            // 开始修改
            contentStr = contentStr.toUpperCase();
            // 获取out对象返回给浏览器
            try {
                this.getJspContext().getOut().write(contentStr);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    
    }

    ②编写tld文件并在里面描述我们的标签处理器类,我的文件为zjc.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>A tag library exercising SimpleTag handlers.</description>
        <tlib-version>1.0</tlib-version>
        <short-name>zjc</short-name>
        <!-- 配置uri,在jsp页面引入tablib 会用到 -->
        <uri>/mytag</uri>
        <tag>
          <!-- 标签的名称 -->
          <name>schange</name>
          <!-- 标签处理器类的全类名 -->
          <tag-class>com.simpletag.ChangeContentSimple</tag-class>
          <!-- simpleTag就不能写成jsple,应该写成scriptless -->
          <body-content>scriptless</body-content>
        </tag>
    </taglib>  

    ③在jsp页面引入我们自定义的标签库即可使用

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%-- 引入我们自定义的标签库--%>
    <%@ taglib uri="/mytag" prefix="zjc"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>修改标签体的内容,</title>
    </head>
    <body>
        修改标签体的内容,
        <zjc:schange>abcdefg</zjc:schange>
    
    </body>
    </html>

    三、自定义标签的属性

            在上面我们自定义了标签,比如我们在上面定义了一个<zjc:srepeate>,它是用来控制将标签体重复输出的自定义标签,但是输出的次数我们已经在后面给他定死了,这样就不够灵活,所以自定义标签还支持属性的设置,我们可以把我们的参数通过自定义标签的属性传递给自定义标签类这样就能够动态的指定重复输出的个数,提高自定义标签的灵活性和复用性。

    (一)自定义标签的属性设置步骤

    1.在标签处理器类中编写每个属性对应的setter方法

    2.在TLD文件中描述标签的属性

    (二)自定义标签属性实现动态制定重复输出标签的输出次数

    1.自定义标签处理器类带上time次数属性,并提供setter方法

    package com.simpletag;
    
    import java.io.IOException;
    
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    
    /**
     * 控制重复显示标签体
     * 
     * @author Administrator
     *
     */
    public class RepeatContentSimple extends SimpleTagSupport {
        // 定义标签输出次数的属性
        private int time;
    
        @Override
        public void doTag() throws JspException, IOException {
            for (int i = 0; i < time; i++) {
                // 重复输出5遍标签体
                this.getJspBody().invoke(this.getJspContext().getOut());
            }
        }
    
        // 提供setter方法
        public void setTime(int time) {
            this.time = time;
        }
    
    }

    2.编写tld文件并在里面描述我们的标签处理器类,并描述我们的自定义属性time,我的文件为zjc.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>A tag library exercising SimpleTag handlers.</description>
        <tlib-version>1.0</tlib-version>
        <short-name>zjc</short-name>
        <!-- 配置uri,在jsp页面引入tablib 会用到 -->
        <uri>/mytag</uri>
    <tag>
            <!-- 标签的名称 -->
            <name>srepeate</name>
            <!-- 标签处理器类的全类名 -->
            <tag-class>com.simpletag.RepeatContentSimple</tag-class>
            <!-- simpleTag就不能写成jsple,应该写成scriptless -->
            <body-content>scriptless</body-content>
            <!-- 设置自定义标签胡的属性值 -->
            <attribute>
                <!-- 设置属性名称 -->
                <name>time</name>
                <!-- 设置是否必填 -->
                <required>true</required>
                <!-- 运行时表达式的值是否使用脚本表达式,如<%=value%>或者el表达式 -->
                <rtexprvalue>true</rtexprvalue>
            </attribute>
        </tag>
    
    </taglib>

    3.在jsp页面引入我们自定义的标签库即可使用(在http://localhost:8080/JavaWebDemo/tag/attribute.jsp?time=10修改time的值就可以改变重复输出的次数)

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ page import="java.util.Date"%>
    <%--导入自定义标签库 --%>
    <%@ taglib uri="/mytag" prefix="zjc"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>带属性的标签</title>
    </head>
    <body>
        <%--从页面参数map中取出数据,给time属性设值 --%>
        传入次数,控制标签体执行${param.time }次
        <zjc:srepeate time="${param.time }">标签体<br />
        </zjc:srepeate>
    </body>
    </html>

    至此,自定义标签已经说明完了,有不足的地方,希望大家多多提意见!

  • 相关阅读:
    洛谷 P1401 城市(二分+网络流)
    洛谷 P2057 善意的投票(网络流最小割)
    洛谷 P1402 酒店之王
    二分图最大匹配的一些证明
    P2764 最小路径覆盖问题(网络流24题之一)
    洛谷 P2055 [ZJOI2009]假期的宿舍
    P2891 [USACO07OPEN]吃饭Dining(最大流+拆点)
    洛谷P1345 [USACO5.4]奶牛的电信(最小割)
    网络流24题之星际转移问题(洛谷P2754)
    LeetCode Unique Binary Search Trees
  • 原文地址:https://www.cnblogs.com/nanyangke-cjz/p/7159801.html
Copyright © 2020-2023  润新知