在JSP EL枚举值中始终为空

sib*_*iba 8 java enums jsp jstl el

当试图让EL条件工作时,我发现枚举值完全被忽略了.这在我看来与规范相反.

<c:out value='${com.foobar.data.BookingStatus.FAILED}' />
<c:out value='${BookingStatus.FAILED}' />
<c:out value='${com.foobar.data.BookingStatus.failed}' />
<c:out value='${BookingStatus.failed}' />
<c:if test="${empty BookingStatus.FAILED }">empty</c:if>
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,这些都评估为.为什么Enum类不被识别?这发生在当前稳定的Tomcat实例中.

这可能是类路径问题吗?Enum在控制器代码中成功使用,但在JSP中没有其他地方使用.它在部署的lib目录中的jar中提供.

更新:

我的目的是将提供的Integer与Enum的属性进行比较,如下所示:

<c:when test='${bookingInformation.bookingStatus eq BookingStatus.FAILED.code}'>
    FOOBARFAIL
</c:when>
Run Code Online (Sandbox Code Playgroud)

不幸的是,被检查的值无法更改,并且仍将是整数.Enum看起来如下(简化):

public enum BookingStatus {

    COMPLETED(0), FAILED(1);

    private final int code;

    private BookingStatus(int code) {
        this.code = code;
    }

    public int getCode() {
        return code;
    }

}
Run Code Online (Sandbox Code Playgroud)

我想避免硬编码FAIL等的Integer值,而是使用enum代替比较.

Bal*_*usC 15

那是因为当前版本的EL不支持访问枚举,也不支持调用枚举常量.此支持仅适用于EL 3.0.

目前还不清楚你的意图是什么,但很高兴知道你可以将枚举属性比作StringEL中的.他们即被解决为String.

假设你有一个看起来像这样的bean:

public class Booking {
    public enum Status { NEW, PROGRESS, SUCCESS, FAILED }

    private Status status;

    public Status getStatus() {
        return status;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以测试Status.FAILED条件如下:

<c:if test="${booking.status == 'FAILED'}">
    Booking status is FAILED.
</c:if>
Run Code Online (Sandbox Code Playgroud)

也可以看看:

  • 不要使用序数.使用值得信赖的枚举值.你的`getStatus()`必须返回`Status`而不是`int`.这是设计不良模型的标志.普通不是常数.无论何时添加/删除/重新排列枚举值,它们都可能会发生变化.这听起来就像是将这样做作为(坏)解决方法,以便能够在数据库中保存Java枚举.那么这是一个不同的主题. (2认同)
  • 不,EL不支持它.它只支持[Javabeans规范](http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html)中描述的Javabeans.你可以添加一个getter来返回状态的所有值,但这很简单.你必须在不同的层面解决这个问题:即不要使用序数,而是使用枚举. (2认同)

Ste*_*tez 7

正如BalusC指出的那样,您无法使用EL访问枚举,但是,您可以这样做:

<c:set var="enumFailed" value="<%=BookingStatus.FAILED%>"/>

<c:if test="${enumFailed.code == bookingInformation.bookingStatus}">
    ...
</c:if>
Run Code Online (Sandbox Code Playgroud)

如果bookingInformation.bookingStatus是枚举而不是int,那将是理想的,但如果由于其遗留性质重新分解您的应用程序是不可能的,那么我的上述示例应该有所帮助.你需要<c:set/>为枚举的每个值(在你的例子中看起来只有两个).