Jsp技术入门指南【十二】自定义标签

发布于:2025-05-11 ⋅ 阅读:(21) ⋅ 点赞:(0)


前言

  • 在前面的博客中,我们深入探讨了如何通过JSTL的SQL标签库简化数据库操作,解决了原生JDBC代码冗余、耦合度高的问题,实现了数据库与页面数据的高效交互。这一实践让我们认识到,标签化开发是提升JSP页面简洁性和可维护性的关键手段

然而,随着Web应用复杂度的提升,标准标签库(如JSTL)提供的通用功能已难以满足个性化业务需求
当我们需要封装特定业务逻辑、复用高频操作或实现更灵活的页面控制时,自定义标签便成为必然选择

  • 自定义标签允许开发者将重复的Java代码或复杂逻辑封装为可复用的标签组件,使JSP页面彻底摆脱脚本代码的冗余,真正实现“标签即逻辑”的开发模式。
  • 它不仅延续了标签化开发“关注点分离”的优势,更赋予开发者根据项目需求自由扩展标签功能的能力,是构建高效、整洁Web应用的重要技术手段

接下来,我们将从自定义标签的核心部件(标签处理类、TLD文件)入手,结合实战案例解析其开发流程、类型特性及最佳实践,来逐步讲解自定义标签

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的JSP知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12950980.html?spm=1001.2014.3001.5482


一、什么是标签

  • 在JSP(JavaServer Pages)中,标签是一种特殊的标记,用于封装功能并简化JSP页面的开发。
  • 标签可以替代复杂的Java代码,使页面结构更清晰、更易于维护。
  • 标签类似于HTML标记,但它们执行的是自定义的Java逻辑。

二、标签的类型有哪些?

1. 空标签

空标签是没有主体内容的标签,它们只包含标签名和属性。例如:

<jsp:include page="header.jsp" />

2. 带有属性的标签

这类标签可以接受参数(属性)来控制其行为。例如:

<c:if test="${condition}">
    <!-- 标签主体 -->
</c:if>

其中testc:if标签的一个属性。

3. 带主体的标签

带主体的标签包含内容(主体),标签处理程序可以处理这些内容。例如:

<mytag:repeat count="5">
    <p>这是重复内容</p>
</mytag:repeat>

三、自定义标签的部件

3.1 自定义标签的四步骤

自定义标签的开发通常包含四个主要步骤:

  1. 标签处理程序:编写Java类实现标签的逻辑
  2. TLD文件:创建标签库描述符文件
  3. JSP文件:在JSP页面中使用自定义标签
  4. 部署:将标签处理类和TLD文件部署到应用中

我们重点关注前两个步骤:标签处理程序和TLD文件

3.2 标签处理程序

标签处理程序是实现标签逻辑的Java类。它通常继承自TagSupportBodyTagSupport,并重写以下方法:

  • doStartTag():当遇到标签开始时执行
  • doEndTag():当遇到标签结束时执行
  • doAfterBody():处理完标签主体后执行(仅当标签有主体时)

这些方法的返回值控制标签的行为,常见的返回值常量有:

  • SKIP_BODY:跳过标签主体内容
  • EVAL_BODY_INCLUDE:计算并包含标签主体内容
  • EVAL_PAGE:继续处理页面剩余部分
  • SKIP_PAGE:跳过页面剩余部分
  • EVAL_BODY_AGAIN:再次计算标签主体内容(用于迭代)

示例代码
下面是一个简单的标签处理程序示例,它会在页面上显示当前时间:

package com.example.tags;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class CurrentTimeTag extends BodyTagSupport {

    private String format = "yyyy-MM-dd HH:mm:ss"; // 默认格式

    public void setFormat(String format) {
        this.format = format;
    }

    @Override
    public int doStartTag() throws JspException {
        try {
            // 获取当前时间并格式化
            LocalDateTime now = LocalDateTime.now();
            String formattedTime = now.format(DateTimeFormatter.ofPattern(format));
            
            // 将格式化后的时间输出到页面
            pageContext.getOut().print(formattedTime);
        } catch (IOException e) {
            throw new JspException("Error writing to JSP writer", e);
        }
        return SKIP_BODY; // 跳过标签主体,因为我们不需要处理主体内容
    }
}

3.3 自定义标签的开发及使用步骤

第一步:创建标签助手类

标签助手类是实现标签逻辑的核心。下面是一个更复杂的示例,展示了如何处理标签主体内容:

package com.example.tags;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import java.io.IOException;

public class RepeatTag extends BodyTagSupport {

    private int count;

    public void setCount(int count) {
        this.count = count;
    }

    private int currentIteration = 0;

    @Override
    public int doStartTag() throws JspException {
        currentIteration = 0;
        if (count > 0) {
            return EVAL_BODY_INCLUDE; // 计算并包含标签主体内容
        } else {
            return SKIP_BODY; // 跳过标签主体
        }
    }

    @Override
    public int doAfterBody() throws JspException {
        currentIteration++;
        if (currentIteration < count) {
            return EVAL_BODY_AGAIN; // 再次计算标签主体内容
        } else {
            return SKIP_BODY; // 完成迭代,跳过剩余主体
        }
    }

    @Override
    public int doEndTag() throws JspException {
        // 重置状态,确保标签可以被重用
        currentIteration = 0;
        return EVAL_PAGE; // 继续处理页面剩余部分
    }
}

第二步:创建TLD文件

TLD(Tag Library Descriptor)文件是一个XML文件,用于描述标签库和其中的标签。下面是对应上述标签的TLD文件示例:

<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
        version="2.1">
    
    <tlib-version>1.0</tlib-version>
    <short-name>custom</short-name>
    <uri>/WEB-INF/tlds/custom.tld</uri>
    
    <!-- 定义currentTime标签 -->
    <tag>
        <name>currentTime</name>
        <tag-class>com.example.tags.CurrentTimeTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>format</name>
            <required>false</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
    
    <!-- 定义repeat标签 -->
    <tag>
        <name>repeat</name>
        <tag-class>com.example.tags.RepeatTag</tag-class>
        <body-content>scriptless</body-content>
        <attribute>
            <name>count</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
</taglib>

第三步:在JSP中使用自定义标签

下面是如何在JSP页面中使用上述自定义标签的示例:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/tlds/custom.tld" prefix="custom" %>

<!DOCTYPE html>
<html>
<head>
    <title>自定义标签示例</title>
</head>
<body>
    <h3>当前时间:<custom:currentTime format="yyyy-MM-dd" /></h3>
    
    <h3>重复内容示例:</h3>
    <custom:repeat count="3">
        <p>这是第 <custom:currentTime format="ss" /> 次重复</p>
    </custom:repeat>
</body>
</html>

四、JSP标签文件

4.1 Tag File简介

Tag File是一种特殊的JSP文件,用于创建自定义标签

  • 与编写Java类不同,Tag File使用JSP语法,可以更方便地实现简单的标签功能。

Tag File必须放在WEB-INF/tags目录下或其子目录中才能被JSP容器识别。例如:

  • WEB-INF/tags/mytag.tag
  • WEB-INF/tags/utils/format.tag

在这里插入图片描述

4.2 Tag File的基本结构

Tag File的基本结构与JSP文件类似,但不需要包含完整的JSP页面元素(如htmlbody标签)。下面是一个简单的Tag File示例:

<%@ attribute name="message" required="true" type="java.lang.String" %>
<%@ attribute name="color" required="false" type="java.lang.String" default="black" %>

<span style="color: ${color};">${message}</span>

4.3 在JSP中使用Tag File

  • 要在JSP页面中使用Tag File,需要通过taglib指令引用标签库:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib tagdir="/WEB-INF/tags" prefix="mytag" %>

<!DOCTYPE html>
<html>
<head>
    <title>Tag File示例</title>
</head>
<body>
    <h3>使用Tag File的消息:</h3>
    <mytag:messageTag message="欢迎使用JSP Tag File" color="blue" />
    
    <h3>循环示例:</h3>
    <c:forEach var="i" begin="1" end="5">
        <mytag:messageTag message="这是第 ${i} 条消息" color="green" />
    </c:forEach>
</body>
</html>
  • Tag File的优点是开发简单,不需要编译Java类,但对于复杂的标签逻辑,仍然建议使用Java类实现的标签处理程序。

以上就是这篇博客的全部内容,下一篇我们将继续探索JSP的更多精彩内容。

我的个人主页,欢迎来阅读我的其他文章
https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343
我的JSP知识文章专栏
欢迎来阅读指出不足
https://blog.csdn.net/2402_83322742/category_12950980.html?spm=1001.2014.3001.5482

非常感谢您的阅读,喜欢的话记得三连哦

在这里插入图片描述