Javaweb学习笔记之JSP(七):自定义标签

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

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>

输出结果:

 

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

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>

 输出结果:

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>

输出结果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JSP(JavaServer Pages)是一种服务器端的动态网页开发技术,它可以将 Java 代码嵌入 HTML 页面中,从而实现动态网页的生成。 JSP 的基本原理是将 JSP 页面翻译成 Servlet,在服务器端执行 Servlet 代码,再将执行结果返回给客户端。因此,我们在使用 JSP 开发网页时,需要先了解 Servlet 的相关知识。 JSP 的语法基本上就是 HTML 标签加上 Java 代码。以下是一些基本的 JSP 标签: 1. <% ... %>:嵌入 Java 代码,可以用于定义变量、写循环、判断语句等。 2. <%= ... %>:输出 Java 代码的执行结果。 3. <%-- ... --%>:注释,不会被翻译成 Servlet。 4. <jsp:include ... />:包含其他 JSP 页面或 HTML 页面。 5. <jsp:forward ... />:将请求转发到其他资源(JSP 页面、Servlet 或 HTML 页面)。 6. <jsp:useBean ... />:创建 JavaBean 对象。 7. <jsp:setProperty ... />:为 JavaBean 对象设置属性。 8. <jsp:getProperty ... />:取得 JavaBean 对象的属性值。 在 JSP 页面中,我们还可以使用 EL 表达式和 JSTL 标签库来简化代码编写,提高开发效率。 EL(Expression Language)表达式是一种简化的表达式语言,可以用于取值、赋值、计算等操作。例如,${name} 表示取得名为 name 的变量的值。 JSTL(JavaServer Pages Standard Tag Library)是一套标签库,提供了循环、条件判断、格式化、国际化等常用功能的标签。例如,<c:forEach> 标签可以用于循环遍历集合,<c:if> 标签可以用于条件判断。 除了以上标签库,JSP 还支持自定义标签库。我们可以通过编写标签处理器来扩展 JSP 的功能。 JSP 的优点是可以将 Java 代码嵌入 HTML 页面中,使得网页的开发更加灵活和方便。但是,由于 JSP 页面需要翻译成 Servlet,因此会增加服务器的负担和响应时间。此外,JSP 页面中夹杂着 Java 代码,也不利于代码的维护和调试。因此,在开发大型网站时,建议使用 MVC 设计模式,将业务逻辑和视图分离,使得代码更加清晰和易于维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值