我最近发现了jsp标记,并使用它们来避免重复我的视图的公共部分。
所以在我的JSP视图中
<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的正确表达式
提前谢谢。
发布于 2015-01-01 15:02:30
您可以使用三个选项,每个选项都有其优点和缺点。
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>为什么使用
${not empty fn:trim(bodyText)}而不是更简单的条件${empty bodyText}?感谢@ach,他指出了这一点,后者简化了空格,因此无论trimDirectiveWhitespaces设置如何,其行为都是一致的。
优点
缺点
${not empty fn:trim(bodyText)}时忽略这一点。(它只适用于${empty bodyText}。)
条件${empty bodyText}是否为真取决于调用的JSP是否启用trimDirectiveWhitespaces。
当标签的主体只包含空格时
<%@ page trimDirectiveWhitespaces="true“%>
并且页面定义了trimDirectiveWhitespaces="true",您的标记文件将检测到没有主体。如果是trimDirectiveWhitespaces="false",您的标记文件将检测到存在一个主体。
请注意,这只适用于标记文件,而不是简单/经典的标记处理程序。在上面的示例中,如果<my:tag>是在标记处理程序中定义的,则无论空格设置如何,处理程序的行为都会像存在主体一样:- For simple tag handler, `getJspBody()` would be non-null.
- For a classic tag handler, `doAfterBody()` would be called.
2. Scriptlet
您可以通过使用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的工作方式与您在任何简单标记处理程序中所期望的一样。
优点
缺点
scripting-invalid文件的配置如何,标记文件都可以使用脚本。)3.辅助标签
如果您需要scriptlet解决方案的功能,而不需要实际使用scriptlet,请继续阅读。
这里的想法是将body空测试封装在标记文件调用的标记处理程序中。标记处理程序可以通过getParent()访问标记文件,并将布尔测试结果导出为变量:
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>优点
缺点
增编:与非身体JSPFragments一起使用
@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>发布于 2014-09-15 09:11:40
你可以这样做。
<jsp:doBody var="bodyText"/>
<c:if test="${not empty bodyText}">
//will shown if its not empty
</c:if>https://stackoverflow.com/questions/25134005
复制相似问题