gpt4 book ai didi

jsp - 如何测试 is empty/null in a tag file?

转载 作者:行者123 更新时间:2023-12-04 14:27:37 26 4
gpt4 key购买 nike

我最近发现了 jsp 标签并使用它们来避免重复我的观点的共同部分。

所以在我的 JSP View 中,我有

<web-component:mytag>
<!-- HTML specific to that page -->
</web-component:mytag>

在我的标签文件中,我得到了带有 <jsp:doBody/> 的 HTML .

我的问题是,我如何测试 <jsp:doBody/>是空的,所以我可以放一个默认的 HTML 内容?

就像是
<c:choose>
<c:when test="${!doBody.empty}">
<jsp:doBody/>
</c:when>
<c:otherwise>
<!-- My default HTML content here -->
</c:otherwise>
</c:choose>

所以我正在寻找 doBody.empty 的正确表达式。

提前致谢。

最佳答案

您可以使用三个选项,每个选项都有其优点和缺点。

1. <jsp:doBody var="bodyText" />
这可能是最常见和最明显的解决方案。

您执行一次主体,将其输出存储在一个变量中,然后检查该变量是否为空。

<jsp:doBody var="bodyText"/>
<c:choose>
<c:when test="${not empty fn:trim(bodyText)}">
${bodyText}
</c:when>
<c:otherwise>
<!-- Default content here -->
</c:otherwise>
</c:choose>

Why use ${not empty fn:trim(bodyText)} instead of the simpler condition ${empty bodyText}? Thanks to @ach, who pointed this out, the latter trims whitespace and thus behaves consistently regardless of the trimDirectiveWhitespaces setting.



优点
  • 作为规范的解决方案,它可能是最不令人惊讶的。

  • 缺点
  • 正文 总是 被执行。您可能不想仅仅为了测试它的存在而执行标签主体(以及任何副作用)。
  • 标签正文的全部内容都存储在内存中。对于较长的标签主体,这可能是一个问题。
  • (使用 ${not empty fn:trim(bodyText)} 时忽略这一点。它仅适用于 ${empty bodyText} 。)

    是否条件${empty bodyText}是否为真取决于调用 JSP 是否启用 trimDirectiveWhitespaces .

    当标签的主体只包含空格时

    <%@ page trimDirectiveWhitespaces="true" %>
    <my:tag value="a">
    </my:tag>

    页面定义trimDirectiveWhitespaces="true" ,您的标签文件将检测到没有正文。如果 trimDirectiveWhitespaces="false" ,您的标签文件将检测到有一个正文。

    请注意,这只适用于标签文件,而不适用于简单/经典的标签处理程序。在上面的例子中,如果 <my:tag>如果在标记处理程序中定义,则处理程序的行为就像一个主体存在,而不管空白设置如何:
  • 对于简单的标签处理程序,getJspBody()将是非空的。
  • 对于经典标签处理程序,doAfterBody()会被调用。

  • 2. 小脚本

    您可以通过使用 Java 代码测试空主体来消除第一个解决方案的缺点。这个解决方案和下一个解决方案正是这样做的,除了这个更简单并且使用脚本。

    <c:choose>
    <c:when test="<%= super.getJspBody() != null %>">
    <jsp:doBody />
    </c:when>
    <c:otherwise>
    <!-- My default HTML content here -->
    </c:otherwise>
    </c:choose>

    这样做的原因是标签文件被翻译成扩展 SimpleTagSupport 的处理程序。 (见 javax.servlet.jsp.tagext )并且脚本在处理程序的 doTag() 中执行方法。因此 super.getJspBody() == null与您在任何简单的标签处理程序中所期望的一样工作。

    优点
  • 对空主体的测试是在不执行主体的情况下完成的。
  • 正文不存储在变量中。

  • 缺点
  • 小脚本的使用。 (但请注意,无论 JSP 文件的 scripting-invalid 配置如何,标签文件都可以使用 scriptlet。)

  • 3. 助手标签

    如果您需要 scriptlet 解决方案的功能而不实际使用 scriptlet,请继续阅读。

    这里的想法是将主体空测试封装在从标记文件调用的标记处理程序中。标签处理程序可以通过 getParent() 访问标签文件。并将 bool 测试结果导出为变量:

    class HasBody extends SimpleTag {
    @Override
    public void doTag() throws JspException {
    TagAdapter adapter = (TagAdapter)this.getParent();
    SimpleTagSupport parent = (SimpleTagSupport)adapter.getAdaptee();

    // `getJspBody()` is a protected method, so actually you must use reflection.
    JspFragment body = parent.getJspBody();

    this.getJspContext().setAttribute("hasBody", body == null);
    }
    }

    现在您的标记文件可能如下所示:

    <my:hasBody />
    <c:choose>
    <c:when test="${hasBody}">
    <jsp:doBody />
    </c:when>
    <c:otherwise>
    <!-- Default content here -->
    </c:otherwise>
    </c:choose>

    优点
  • 不使用小脚本。
  • 功能上等同于 scriptlet 解决方案。

  • 缺点
  • 复杂。需要一个单独的标记处理程序来执行主体空测试。
  • 需要使用反射。

  • 附录:与非正文 JSPF 片段一起使用

    @Ryan想知道如何将这种方法应用于一般 JSPFragment属性。幸运的是,因为所有属性都可以作为 EL 中的变量直接访问(而主体不是),所以测试空片段属性很简单:
    <%@ attribute name="frag" fragment="true" %>
    <c:choose>
    <c:when test="${frag != null}">
    <jsp:invoke fragment="frag" />
    </c:when>
    <c:otherwise>
    <!-- Default content here -->
    </c:otherwise>
    </c:choose>

    关于jsp - 如何测试 <jsp :doBody/> is empty/null in a tag file?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25134005/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com