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

news2025/5/11 14:11:52

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

  • 前言
  • 一、什么是标签
  • 二、标签的类型有哪些?
    • 1. 空标签
    • 2. 带有属性的标签
    • 3. 带主体的标签
  • 三、自定义标签的部件
    • 3.1 自定义标签的四步骤
    • 3.2 标签处理程序
    • 3.3 自定义标签的开发及使用步骤
      • 第一步:创建标签助手类
      • 第二步:创建TLD文件
      • 第三步:在JSP中使用自定义标签
  • 四、JSP标签文件
    • 4.1 Tag File简介
    • 4.2 Tag File的基本结构
    • 4.3 在JSP中使用Tag File


前言

  • 在前面的博客中,我们深入探讨了如何通过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

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

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2373181.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java—— 泛型详解

泛型概述 泛型是JDK5中引入的特性&#xff0c;可以在编译阶段约束操作的数据类型&#xff0c;并进行检查。 泛型的格式&#xff1a;<数据类型> 注意&#xff1a;泛型只能支持引用数据类型。 泛型的好处 没有泛型的时候&#xff0c;可以往集合中添加任意类型的数据&#x…

GPT-4o, GPT 4.5, GPT 4.1, O3, O4-mini等模型的区别与联系

大模型时代浪潮汹涌,作为其中的领军者,OpenAI 其推出的系列模型以强大的能力深刻影响着整个行业,并常常成为业界其他公司对标和比较的基准。因此,深入了解 OpenAI 的大模型,不仅是为了使用它们,更是为了理解当前大模型的能力边界和发展趋势,这对于我们评估和选择其他各类…

Kubernetes生产实战(十二):无工具容器网络连接数暴增指南

当线上容器突然出现TCP连接数暴涨&#xff0c;而容器内又没有安装任何调试工具时&#xff0c;如何快速定位问题&#xff1f;本文将分享一套经过大型互联网公司验证的排查方案&#xff0c;涵盖从快速应急到根因分析的全流程。 一、快速锁定问题容器 查看pod 连接数方式&#x…

MySQL的Order by与Group by优化详解!

目录 前言核心思想&#xff1a;让索引帮你“排好序”或“分好组”Part 1: ORDER BY 优化详解1.1 什么是 Filesort&#xff1f;为什么它慢&#xff1f;1.2 如何避免 Filesort&#xff1f;—— 利用索引的有序性1.3 EXPLAIN 示例 (ORDER BY) Part 2: GROUP BY 优化详解2.1 什么是…

软件测试——用例篇(3)

目录 一、设计测试用例的具体方法 1.1等价类 1.1.1等价类概念介绍 1.1.2等价类分类 1.2边界值 1.2.1边界值分析法 1.2.2边界值分类 1.3正交法 1.3.1正交表 1.3.2正交法设计测试用例步骤 1.4判定表法 1.4.1判定表 1.4.2判定表方法设计测试用例 1.5 场景法 1.6错误…

在 Win11 下安装 Wireshark 的详细步骤

目录 一、了解 Wireshark1. 作用和功能2. 使用步骤 二、下载安装包三、运行安装包四、使用 Wireshark1. 抓包2. 窗口介绍3. 过滤器&#xff08;显示 / 捕获过滤器&#xff09;4. 保存过滤后的报文1&#xff09;显示过滤器表达式&#xff08;了解&#xff09;2&#xff09;过滤表…

AI编程: 使用Trae1小时做成的音视频工具,提取音频并识别文本

背景 在上个月&#xff0c;有网页咨询我怎么才能获取视频中的音频并识别成文本&#xff0c;我当时给他的回答是去问一下AI&#xff0c;让AI来给你答案。 他觉得我在敷衍他&#xff0c;大骂了我一顿&#xff0c;大家觉得我的回答对吗&#xff1f; 小编心里委屈&#xff0c;我…

RTC实时时钟DS1337S/PT7C4337WEX国产替代FRTC1337S

NYFEA徕飞公司的FRTC1337S串行实时时钟是一种低功耗时钟/日历&#xff0c;被设计成可以无缝替代市场上流行的DS1337S和PT7C4337WEX(SOP8)两种型号, 具有两个可编程的时钟闹钟和一个可编程方波输出。 地址和数据通过2线双向总线串行传输。时钟/日历提供秒、分钟、小时、天、日期…

Vue3.5 企业级管理系统实战(十七):角色管理

本篇主要探讨角色管理功能&#xff0c;其中菜单权限这里先不实现&#xff0c;后续在菜单管理中再进行实现。接口部分依然是使用 Apifox mock 的。 1 角色 api 在 src/api/role.ts 中添加角色相关 api&#xff0c;代码如下&#xff1a; //src/api/role.ts import service fro…

QTableWidget实现多级表头、表头冻结效果

最终效果&#xff1a; 实现思路&#xff1a;如果只用一个表格的话写起来比较麻烦&#xff0c;可以考虑使用两个QTableWidget组合&#xff0c;把复杂的表头一个用QTableWidget显示&#xff0c;其他内容用另一个QTableWidget。 #include "mainwindow.h" #include &qu…

A2A大模型协议及Java示例

A2A大模型协议概述 1. 协议作用 A2A协议旨在解决以下问题&#xff1a; 数据交换&#xff1a;不同应用程序之间的数据格式可能不一致&#xff0c;A2A协议通过定义统一的接口和数据格式解决这一问题。模型调用&#xff1a;提供标准化的接口&#xff0c;使得外部应用可以轻松调…

CMake 入门实践

CMake 入门实践 第一章 概念与基础项目1.1 CMake 基础认知1.2 最小 CMake 项目1.3 构建流程验证 第二章 多文件项目管理2.1 项目结构2.2 源码示例2.3 CMake 配置 第三章 库文件管理实战3.1 项目结构3.2 核心配置3.3 接口设计 第四章 构建类型与编译优化4.1 构建类型配置4.2 构建…

异地多活单元化架构下的微服务体系

治理服务间的跨IDC调用&#xff0c;而数据库层面还是要跨IDC 服务注册中心拆开、 金融要求&#xff0c;距离太远&#xff0c;异地备库&#xff0c;如果延迟没读到数据就可能有资损&#xff0c;IDC3平时不能用&#xff0c;IDC1挂了还是有数据同步问题&#xff0c;IDC3日常维护…

HarmonyOS NEXT——DevEco Studio的使用(还没写完)

一、IDE环境的搭建 Windows环境 运行环境要求 为保证DevEco Studio正常运行&#xff0c;建议电脑配置满足如下要求&#xff1a; 操作系统&#xff1a;Windows10 64位、Windows11 64位 内存&#xff1a;16GB及以上 硬盘&#xff1a;100GB及以上 分辨率&#xff1a;1280*8…

Windows系统Jenkins企业级实战

目标 在Windows操作系统上使用Jenkins完成代码的自动拉取、编译、打包、发布工作。 实施 1.安装Java开发工具包&#xff08;JDK&#xff09; Jenkins是基于Java的应用程序&#xff0c;因此需要先安装JDK。可以从Oracle官网或OpenJDK下载适合的JDK版本。推荐java17版本&#x…

C# 方法(ref局部变量和ref返回)

>本章内容: 方法的结构 方法体内部的代码执行 局部变量 局部常量 控制流 方法调用 返回值 返回语句和void方法 局部函数 参数 值参数 引用参数 引用类型作为值参数和引用参数 输出参数 参数数组 参数类型总结 方法重载 命名参数 可选参数 栈帧 递归 ref局部变量和ref返回 …

滑动窗口,438找出字符串中所有字母的异位词

1.题目 2.解析 这道题我们用滑动窗口来实现&#xff0c;加上哈希表和vector容器的使用来实现这道题目&#xff0c;每次滑动之后我们都对其和答案进行比较&#xff0c;如果全部相等我们返回left&#xff0c;不相等继续滑动即可。 本质就是我们把p中相同数量的字母框起来&#…

「国产嵌入式仿真平台:高精度虚实融合如何终结Proteus时代?」——从教学实验到低空经济,揭秘新一代AI赋能的产业级教学工具

引言&#xff1a;从Proteus到国产平台的范式革新 在高校嵌入式实验教学中&#xff0c;仿真工具的选择直接影响学生的工程能力培养与创新思维发展。长期以来&#xff0c;Proteus作为经典工具占据主导地位&#xff0c;但其设计理念已难以满足现代复杂系统教学与国产化技术需求。…

《Python星球日记》 第52天:反向传播与优化器

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。—— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、引言二、反向传播算法原理简述1. 什么是反向传播&#xff1f;2. 从数学角度…

Java常用类概述

Java常用类概述 一、字符串三剑客1. String&#xff08;不可变字符串&#xff09;2. StringBuilder&#xff08;可变&#xff0c;线程不安全&#xff09;3. StringBuffer&#xff08;可变&#xff0c;线程安全&#xff09; 二、日期时间类&#xff08;重点掌握新版API&#xff…