如何使用 JSTL 确定列表中的对象是否实现了 class

How to determine if object in a list implements a class using JSTL

在我的 jsp(标记)文件中,如果对象实现了特定的 class(Orderable),我需要以不同的顺序显示对象列表。

显示部分很好,我只是不知道如何确定对象是否实现了我的可订购 class。

我需要帮助:

<c:set var="isOrderable" value="${items[0] implements 'Orderable'}" />

所以这可行:

<c:choose>
    <c:when test="${isOrderable}" >
        <sorter:sortByProperty items="${items}" var="items" property="ordinal"/>
    </c:when>
    <c:otherwise>
        <sorter:sortByProperty items="${items}" var="items" property="name"/>
    </c:otherwise>
</c:choose>

正如 Sotirios Delimanolis 所说,这不适合 JSP 来处理。下移一层。

无论如何,我什至不确定是否有可能检查一个对象是否实现了给定的接口。我能想到的唯一解决方案是检查对象的实际 class 并可能以这种方式计算出来。

例子

<c:set var="isOrderable" value="${items[0].getClass().name == 'OrderableImpl'}" />

(请注意,这至少需要 Tomcat 7 和 JSP EL 2.2)

您可以列出对象实现的接口Class.getInterfaces()

这可以在 JSP 中使用,如下所示:

<c:set var="isComparable" value="false" />
<c:forEach  var="interface" items="${yourobject.class.interfaces}">
  <c:if test="${interface.name eq 'java.lang.Comparable'}">
      <c:set var="isComparable" value="true" />
  </c:if>
</c:forEach>

然而,正如 Sotirios Delimanolis 和 Robin Jonsson 所说,这非常混乱,确实应该移到更合适的层。

看起来没有办法干净地做到这一点。因为我不能事先做,所以我选择制作 另一个 自定义标签来确定对象是否继承了 class:

添加了这个自定义标签:

<sorter:isOrderable items="${items}" var="isOrderable" />

这样才能奏效:

<c:choose>
    <c:when test="${isOrderable}" >
        <sorter:sortByProperty items="${items}" var="items" property="ordinal"/>
    </c:when>
    <c:otherwise>
        <sorter:sortByProperty items="${items}" var="items" property="name"/>
    </c:otherwise>
</c:choose>

这是实际检查的 java 标记文件:

public class IsOrderableTag extends TagSupport {

    private static final long   serialVersionUID    = -842326085194300052L;
    private String              var;
    private Collection<?>       items;

    @Override
    public int doStartTag() throws JspException {

        boolean isOrderable = false;
        if (items != null && !items.isEmpty()) {
            Object firstItem = items.iterator().next();
            isOrderable = firstItem instanceof Orderable;
        }
        pageContext.setAttribute(var, isOrderable);
        return SKIP_BODY;
    }

    //... getters and setters

}

起初这似乎有点过分,但对我来说,我会在 jsp 上有一些漂亮的 "messy" 代码(根据@obourgain),或者使用 [=29= 的更简洁的实现].

(我没有将此标记为已选择的答案,因为问题是如何使用 jstl 在 jsp 上执行此操作——如果你真的必须这样做的话——而这不是。但是,对于与我处于相同位置的其他人来说,这也许是一个不错的选择。)