首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何测试标签文件中的<jsp:doBody/>是否为空/空?

如何测试标签文件中的<jsp:doBody/>是否为空/空?
EN

Stack Overflow用户
提问于 2014-08-05 08:11:43
回答 2查看 3K关注 0票数 6

我最近发现了jsp标记,并使用它们来避免重复我的视图的公共部分。

所以在我的JSP视图中

代码语言:javascript
复制
<web-component:mytag>
<!-- HTML specific to that page -->
</web-component:mytag>

在我的标记文件中,我使用<jsp:doBody/>获得HTML。

我的问题是,如何测试<jsp:doBody/>是否是空的,这样就可以放置默认的HTML?

有点像

代码语言:javascript
复制
<c:choose>
    <c:when test="${!doBody.empty}">
        <jsp:doBody/>
    </c:when>
    <c:otherwise>
    <!-- My default HTML content here -->
    </c:otherwise>
</c:choose>

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

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-01 15:02:30

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

1. <jsp:doBody var="bodyText" />

这可能是最常见和最明显的解决办法。

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

代码语言:javascript
复制
<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>

为什么使用${not empty fn:trim(bodyText)}而不是更简单的条件${empty bodyText}?感谢@ach,他指出了这一点,后者简化了空格,因此无论trimDirectiveWhitespaces设置如何,其行为都是一致的。

优点

  • 作为典型的解决方案,这可能是最不令人惊讶的。

缺点

  • body 总是被执行。您可能不希望仅仅为了测试标记体是否存在而执行标记体(和任何副作用)。
  • 标记体的全部内容存储在内存中。这对更长的身体来说可能是个问题。
  • (使用${not empty fn:trim(bodyText)}时忽略这一点。(它只适用于${empty bodyText}。) 条件${empty bodyText}是否为真取决于调用的JSP是否启用trimDirectiveWhitespaces。 当标签的主体只包含空格时 <%@ page trimDirectiveWhitespaces="true“%> 并且页面定义了trimDirectiveWhitespaces="true",您的标记文件将检测到没有主体。如果是trimDirectiveWhitespaces="false",您的标记文件将检测到存在一个主体。 请注意,这只适用于标记文件,而不是简单/经典的标记处理程序。在上面的示例中,如果<my:tag>是在标记处理程序中定义的,则无论空格设置如何,处理程序的行为都会像存在主体一样:
代码语言:javascript
复制
- For simple tag handler, `getJspBody()` would be non-null.
- For a classic tag handler, `doAfterBody()` would be called.

2. Scriptlet

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

代码语言:javascript
复制
<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的工作方式与您在任何简单标记处理程序中所期望的一样。

优点

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

缺点

  • 使用脚本。(但是请注意,无论scripting-invalid文件的配置如何,标记文件都可以使用脚本。)

3.辅助标签

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

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

代码语言:javascript
复制
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);
  }
}

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

代码语言:javascript
复制
<my:hasBody />
<c:choose>
  <c:when test="${hasBody}">
    <jsp:doBody />
  </c:when>
  <c:otherwise>
    <!-- Default content here -->
  </c:otherwise>
</c:choose>

优点

  • 不使用脚本。
  • 功能等效于scriptlet解决方案。

缺点

  • 很复杂。只需要一个单独的标记处理程序来执行body空测试。
  • 需要使用反射。

增编:与非身体JSPFragments一起使用

@Ryan想知道如何使这种方法适应一般的JSPFragment属性。幸运的是,由于所有属性都可以作为来自EL的变量直接访问(而主体不是),因此对空片段属性的测试非常简单:

代码语言:javascript
复制
<%@ 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>
票数 8
EN

Stack Overflow用户

发布于 2014-09-15 09:11:40

你可以这样做。

代码语言:javascript
复制
<jsp:doBody var="bodyText"/>
<c:if test="${not empty bodyText}">
    //will shown if its not empty
</c:if>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25134005

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档