0

0

JSP Tag 文件中实现完全求值 Body 内容的方法

碧海醫心

碧海醫心

发布时间:2025-07-10 18:56:15

|

875人浏览过

|

来源于php中文网

原创

jsp tag 文件中实现完全求值 body 内容的方法

本文探讨了在 JSP Tag 文件中实现完全求值 Body 内容的方法,类似于 Java 类中 BodyTag 接口的 EVAL_BODY_INCLUDE 功能。由于 JSP Tag 文件本身的限制,直接支持完整的 JSP 代码(包括 Scriptlet 和表达式)是不可能的。本文将解释这一限制,并提供替代方案。

JSP Tag 文件提供了一种方便的方式来封装和重用 JSP 代码片段。然而,它们在处理 Body 内容时存在一些限制。一个常见的问题是如何让 Tag 文件支持其 Body 中包含完整的 JSP 代码,包括 Scriptlet () 和表达式 ()。

Tag 文件 Body 内容的限制

在 Tag 文件中,body-content 属性用于指定 Body 内容的类型。常用的值包括:

  • empty: Tag 没有 Body 内容。
  • scriptless: Tag 的 Body 内容可以包含 EL 表达式和 JSTL 标签,但不能包含 Scriptlet。
  • tagdependent: Tag 的 Body 内容由 Tag 自身处理,JSP 引擎不会对其进行解释。

遗憾的是,没有一个 body-content 的值允许在 Tag 文件的 Body 中使用完整的 JSP 代码。尝试这样做会导致类似于 "Scripting elements are disallowed here" 的错误。

示例:无法在 Tag 文件中使用 Scriptlet

考虑以下 Tag 文件 dialog.tag:

<%@tag pageEncoding="UTF-8" body-content="scriptless" %>

以及使用它的 Tag 文件 use-dialog.tag:

<%@tag pageEncoding="UTF-8" %>
<%@attribute name="someAttribute" type="java.lang.String" required="false" %>
<%@taglib prefix="mytaglib" uri="/WEB-INF/tlds/mytaglib" %>


    <%-- 使用变量 --%>
    Hello <%= someAttribute %>

    <%-- 使用其他标签 --%>
    

这段代码会抛出异常,因为 dialog.tag 的 Body 中包含了 Scriptlet 表达式 ()。

使用 Java 类实现 BodyTag

站长俱乐部购物系统
站长俱乐部购物系统

功能介绍:1、模块化的程序设计,使得前台页面设计与程序设计几乎完全分离。在前台页面采用过程调用方法。在修改页面设计时只需要在相应位置调用设计好的过程就可以了。另外,这些过程还提供了不同的调用参数,以实现不同的效果;2、阅读等级功能,可以加密产品,进行收费管理;3、可以完全可视化编辑文章内容,所见即所得;4、无组件上传文件,服务器无需安装任何上传组件,无需支持FSO,即可上传文件。可限制文件上传的类

下载

解决这个限制的唯一方法是使用 Java 类来实现 BodyTag 接口。BodyTag 允许你完全控制 Body 内容的处理方式。

以下是一个 Dialog.java 的示例:

import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyTag;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.JspException;
import java.io.IOException;

public class Dialog implements BodyTag {

    private PageContext pageContext;
    private Tag parent;
    private BodyContent bodyContent;

    @Override
    public void setPageContext(PageContext pageContext) {
        this.pageContext = pageContext;
    }

    @Override
    public void setParent(Tag parent) {
        this.parent = parent;
    }

    @Override
    public Tag getParent() {
        return parent;
    }

    @Override
    public void setBodyContent(BodyContent bodyContent) {
        this.bodyContent = bodyContent;
    }

    @Override
    public void doInitBody() throws JspException {
        // 可选:在 Body 内容求值之前执行一些初始化操作
    }

    @Override
    public int doStartTag() throws JspException {
        try {
            JspWriter out = pageContext.getOut();
            out.print("
"); } catch (IOException e) { throw new JspException(e); } return EVAL_BODY_BUFFERED; // EVAL_BODY_INCLUDE 已经过时,推荐使用 EVAL_BODY_BUFFERED } @Override public int doEndTag() throws JspException { try { JspWriter out = pageContext.getOut(); if (bodyContent != null) { out.print(bodyContent.getString()); // 输出 Body 内容 } out.print("
"); } catch (IOException e) { throw new JspException(e); } finally { if (bodyContent != null) { try { bodyContent.clear(); // 清理 BodyContent } catch (IOException e) { // ignore } } } return EVAL_PAGE; // 继续评估 JSP 页面 } @Override public void release() { pageContext = null; parent = null; bodyContent = null; } }

关键点:

  • setPageContext(PageContext pageContext): 设置 PageContext 对象,允许访问 JSP 页面上下文。
  • doStartTag(): 在 Tag 开始标签处执行,输出
    。EVAL_BODY_BUFFERED 指示容器评估 Tag 的 Body 并将其存储在 BodyContent 对象中。
  • doEndTag(): 在 Tag 结束标签处执行,输出
。在此方法中,我们从 bodyContent 获取 Body 内容并将其输出。
  • release(): 释放资源,这是一个好习惯。
  • 使用 Java Tag

    为了使用 Java Tag,需要在 TLD 文件中声明它。例如,如果你的 TLD 文件是 mytaglib.tld,你可以添加以下内容:

    
        dialog
        com.example.Dialog
        JSP
    

    然后,你可以像这样在 JSP 页面中使用它:

    <%@taglib prefix="mytaglib" uri="/WEB-INF/tlds/mytaglib.tld" %>
    
    
        <%-- 使用变量 --%>
        Hello <%= request.getParameter("name") %>
    
        <%-- 使用其他标签 --%>
        
    

    总结

    虽然 JSP Tag 文件提供了一种便捷的方式来创建可重用的组件,但它们在处理包含完整 JSP 代码的 Body 内容时存在限制。要实现完全求值的 Body 内容,你需要使用 Java 类来实现 BodyTag 接口。这种方法允许你完全控制 Body 内容的处理方式,并支持 Scriptlet 和表达式。这种方式虽然稍微复杂,但提供了更大的灵活性和控制力。

    热门AI工具

    更多
    DeepSeek
    DeepSeek

    幻方量化公司旗下的开源大模型平台

    豆包大模型
    豆包大模型

    字节跳动自主研发的一系列大型语言模型

    通义千问
    通义千问

    阿里巴巴推出的全能AI助手

    腾讯元宝
    腾讯元宝

    腾讯混元平台推出的AI助手

    文心一言
    文心一言

    文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

    讯飞写作
    讯飞写作

    基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

    即梦AI
    即梦AI

    一站式AI创作平台,免费AI图片和视频生成。

    ChatGPT
    ChatGPT

    最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

    相关专题

    更多
    硬盘接口类型介绍
    硬盘接口类型介绍

    硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

    1127

    2023.10.19

    PHP接口编写教程
    PHP接口编写教程

    本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

    192

    2025.10.17

    php8.4实现接口限流的教程
    php8.4实现接口限流的教程

    PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

    1647

    2025.12.29

    java接口相关教程
    java接口相关教程

    本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

    20

    2026.01.19

    class在c语言中的意思
    class在c语言中的意思

    在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

    469

    2024.01.03

    python中class的含义
    python中class的含义

    本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

    13

    2025.12.06

    jsp分页功能如何实现
    jsp分页功能如何实现

    当数据有几万、几十万甚至上百万时,户必须要拖动页面才能浏览更多的数据,很大程度的影响了户体验。这时可以使用分页来显示数据,能够使数据更加清晰直观,环受数量的限制。php中文网为大家带来了jsp分页功能相关教程、以及相关文章等内容,供大家免费下载使用。

    101

    2023.06.21

    jsp怎么打开
    jsp怎么打开

    打开jsp的步骤是安装Java开发环境、配置Web服务器、创建JSP文件、部署到Web服务器、启动Web服务器、在浏览器中访问JSP页面。本专题为大家提供jsp相关的文章、下载、课程内容,供大家免费下载体验。

    124

    2023.10.08

    俄罗斯Yandex引擎入口
    俄罗斯Yandex引擎入口

    2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

    158

    2026.01.28

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    誉天教育RHCE视频教程
    誉天教育RHCE视频教程

    共9课时 | 1.4万人学习

    尚观Linux RHCE视频教程(二)
    尚观Linux RHCE视频教程(二)

    共34课时 | 5.8万人学习

    尚观RHCE视频教程(一)
    尚观RHCE视频教程(一)

    共28课时 | 4.8万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号