开发一个简单的自定义标签分三步:

1、创建一个普通的 Java 类,继承 SimpleTagSupport 类,叫做 标签处理器类:

package com.customtag.demo;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
自定义一个标签处理器类:
    1、继承 SimpleTagSupport 类;
    2、覆盖 doTag 方法,编写功能代码;
*/
public class CustomTag extends SimpleTagSupport {
    @Override
    public void doTag() throws JspException, IOException {
        // 获取系统当前时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = sdf.format(new Date());

        // 获取 JspContext 对象,并将其转换成 PageContext 对象
        PageContext pageContext = (PageContext)this.getJspContext();

        // 通过 pageContext 对象可以获取到 jsp 的其他八个内置对象
        JspWriter out = pageContext.getOut();

        // 将当前时间输出到浏览器
        out.write(date);
    }
}

2、在 web 项目的 WEB-INF 目录下创建一个 .tld 文件(比如 custom.tld),这个 tld 文件叫做 标签库的声明文件;(参考核心标签库的 c.tld 文件)。web 项目启动的时候,服务器会加载 WEB-INF 下的所有文件,比如 web.xml。

<?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.1</tlib-version>                <!-- 标签库的版本 -->
    <short-name>custom</short-name>                 <!-- 标签库前缀(<%@taglib> 指令中 prefix 的值) -->
    <uri>http://com.customtag.demo.CustomTag</uri>  <!-- tld 文件的唯一资源标记(<%@taglib> 指令中 uri 的值) -->

    <!-- 声明一个标签 -->
    <tag>
        <name>showDate</name>                               <!-- 标签的名字 -->
        <tag-class>com.customtag.demo.CustomTag</tag-class> <!-- 标签处理器类的全名(含包名) -->
        <!--
            输出标签体内容格式:
            scriptless:标签体不可以写 jsp 的 java 代码;
            JSP:在传统标签中使用的,可以写和执行 jsp 的 java 代码;
            empty:必须是空标签;
            tagdependent:标签体内容可以写 jsp 的 java 代码,但不会执行;
         -->
        <body-content>scriptless</body-content>
    </tag>

</taglib>

3、在 jsp 页面(07_custom.jsp)中导入 自定义标签库并使用;

<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="custom" uri="http://com.customtag.demo.CustomTag" %> <%-- 导入自定义标签库 --%>
<html>
<head>
    <title>自定义标签</title>
</head>
<body>
    <%
        // 获取当前时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = sdf.format(new Date());
        // 输出到浏览器
        out.write("当前时间:" + date);
    %>
    <%-- 上面的功能 用现有的标签无法实现,可以通过自定义标签实现 --%>
    <hr>

    <%-- 使用自定义标签实现上面的功能,在浏览器输出当前时间 --%>
    用自定义标签输出的当前时间:<custom:showDate />
</body>
</html>

输出结果:

java update scheduler开机后不跳出了 java auto updater_xml

 

自定义标签的 五个 功能细节:

1、输出标签体内容 :默认情况下不会输出 标签体内容,需要在 doTag 方法中手动设置输出标签体内容;

public class CustomTag extends SimpleTagSupport {
    @Override
    public void doTag() throws JspException, IOException {
        System.out.println("执行了自定义标签");

        /*
        输出标签体内容(默认情况下不会输出标签体内容)
        * */
        // 1、得到封装 标签体内容 的对象
        JspFragment jspBody = this.getJspBody();

        // 2、得到 JspWriter 对象
        JspWriter out = this.getJspContext().getOut();

        // 3、执行 invoke 方法,把标签体内容输出到指定的 Writer 对象中,
        // Writer 对象就会自动把标签体内容输出到浏览器;
        jspBody.invoke(out);

        // 当 Writer 为 null 时,默认情况下也是向浏览器输出内容
//        jspBody.invoke(null); // 这一行代码可以代替上面 2、3 两步的代码
    }
}

2、禁止执行标签后面的代码(默认情况下,标签后面的内容会继续执行)

public class CustomTag extends SimpleTagSupport {
    @Override
    public void doTag() throws JspException, IOException {
        System.out.println("执行了自定义标签");

        /*
        禁止执行标签后面的内容(默认情况下会执行)
        抛出 SkipPageException 异常,标签后面的代码都不会执行了;
        * */
        throw new SkipPageException();
    }
}

3、重复输出标签体内容:

public class CustomTag extends SimpleTagSupport {
    @Override
    public void doTag() throws JspException, IOException {
        System.out.println("执行了自定义标签");

        // 得到封装 标签体内容 的对象
        JspFragment jspBody = this.getJspBody();

        // 控制重复输出标签体内容:调用几次 jspBody.invoke(null) 方法,就会向浏览器输出几次 标签体内容
        for (int i = 0; i < 5; i++){
            jspBody.invoke(null);
        }
    }
}

4、修改标签体内容:

java 文件: 

public class CustomTag2 extends SimpleTagSupport {
    @Override
    public void doTag() throws JspException, IOException {
        System.out.println("执行了自定义标签");

        // 得到封装 标签体内容 的对象
        JspFragment jspBody = this.getJspBody();

        /*
        修改标签体内容
        * */
        // 1、创建 StringWriter 对象,作为一个缓存区存放 标签体内容
        StringWriter sw = new StringWriter();
        // 2、把标签体内容输出到 字符缓冲区
        jspBody.invoke(sw);
        // 3、从缓冲区中取出 标签体内容
        String content = sw.toString();
        // 4、修改标签体内容
        content = content + "--- 我被修改了!";
        // 5、将改变后的标签体内容输出到浏览器
        this.getJspContext().getOut().write(content);
    }
}

jsp 文件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="custom" uri="http://com.customtag.demo.CustomTag" %>
<html>
<head>
    <title>控制自定义标签体内容是否输出</title>
</head>
<body>
    <custom:print>
        标签体内容
    </custom:print>
</body>
</html>

 输出结果:

java update scheduler开机后不跳出了 java auto updater_java_02

5、带属性的自定义标签:

java 文件:

public class CustomTag2 extends SimpleTagSupport {
    // 1、声明属性的成员变量
    private Integer num;
    // 2、必须提供公开的 setter 方法,用于给属性赋值
    public void setNum(Integer num){
        this.num = num;
    }
    @Override
    public void doTag() throws JspException, IOException {
        System.out.println("执行了自定义标签:" + num);
    }
}

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

    <tlib-version>1.1</tlib-version>                <!-- 标签库的版本 -->
    <short-name>custom</short-name>                 <!-- 标签库前缀(<%@taglib> 指令中 prefix 的值) -->
    <uri>http://com.customtag.demo.CustomTag</uri>  <!-- tld 文件的唯一资源标记(<%@taglib> 指令中 uri 的值) -->

    <tag>
        <name>print</name>
        <tag-class>com.customtag.demo.CustomTag2</tag-class>
        <body-content>scriptless</body-content>
        <!-- 声明属性 -->
        <attribute>
            <name>num</name>                <!-- 属性名称 -->
            <required>true</required>       <!-- 是否必填 -->
            <rtexprvalue>false</rtexprvalue><!-- 是否支持 EL 表达式 -->
        </attribute>
    </tag>
    
</taglib>

jsp 文件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="custom" uri="http://com.customtag.demo.CustomTag" %>
<html>
<head>
    <title>控制自定义标签体内容是否输出</title>
</head>
<body>
    <custom:print num="33">
        标签体内容
    </custom:print>
</body>
</html>

输出结果:

java update scheduler开机后不跳出了 java auto updater_java_03