我有一个名为 Status 的枚举,定义如下:
public enum Status {
VALID("valid"), OLD("old");
private final String val;
Status(String val) {
this.val = val;
}
public String getStatus() {
return val;
}
}
我想从 JSTL 标记访问 VALID
的值。特别是 <c:when>
标记的 test
属性。例如
<c:when test="${dp.status eq Status.VALID">
我不确定这是否可能。
与字符串的简单比较有效:
<c:when test="${someModel.status == 'OLD'}">
如果使用 Spring MVC,Spring 表达式语言 (SpEL) 可能会有所帮助:
<spring:eval expression="dp.status == T(com.example.Status).VALID" var="isValid" />
<c:if test="${isValid}">
isValid
</c:if>
<c:if>
和 <c:when>
并不总是发生这种情况(它们会悄悄地失败)。
您在这里有 3 个选择,但没有一个是完美的:
您可以在 test 属性中使用 scriptlet:
我更喜欢最后一个选项 (3),尽管它也使用了 scriptlet。这是因为它仅在您设置值时使用它。稍后您可以将它与其他 EL 条件一起用于更复杂的 EL 表达式。在选项 (1) 中,您不能在单个 when
标记的 test
属性中使用 scriptlet 和 EL 表达式。
Enum.valueOf(Class<T> enumType, String name)
转换为枚举,如果枚举没有具有该名称的常量,则会触发 ELException
。表达式不会总是错误的。
因此,要完全解决我的问题,我需要执行以下操作:
<% pageContext.setAttribute("old", Status.OLD); %>
然后我能够做到:
<c:when test="${someModel.status == old}"/>...</c:when>
按预期工作。
这里还有两种可能性:
JSP EL 3.0 常量
只要您至少使用 3.0 版的 EL,您就可以将常量导入您的页面,如下所示:
<%@ page import="org.example.Status" %>
<c:when test="${dp.status eq Status.VALID}">
但是,一些 IDE 还不理解这一点(例如 IntelliJ),因此如果您输入错误,直到运行时才会收到任何警告。
一旦获得适当的 IDE 支持,这将是我的首选方法。
辅助方法
您可以将吸气剂添加到您的枚举中。
public enum Status {
VALID("valid"), OLD("old");
private final String val;
Status(String val) {
this.val = val;
}
public String getStatus() {
return val;
}
public boolean isValid() {
return this == VALID;
}
public boolean isOld() {
return this == OLD;
}
}
然后在您的 JSP 中:
<c:when test="${dp.status.valid}">
这在所有 IDE 中都受支持,如果您还不能使用 EL 3.0,也可以使用。这就是我目前所做的,因为它将所有逻辑都包含在我的枚举中。
如果存储枚举的变量可能为空,也要小心。如果您的代码不能保证它不为空,您需要先检查它:
<c:when test="${not empty db.status and dp.status.valid}">
我认为这种方法优于在 JSP 中设置中间值的方法,因为您必须在需要使用枚举的每个页面上执行此操作。但是,使用此解决方案,您只需声明一次 getter。
${MyEnum.}
时显示可用常量列表,将插入符号放在点后面并按 Ctrl+Space
显示建议。
public enum TestEnum { AWAITING, FILE_PRESENT, FILE_NOT_FOUND; }
但这不可行:public class TestClass { public enum TestEnum { AWAITING, FILE_PRESENT, FILE_NOT_FOUND; } }
这非常令人沮丧,因为我从未将整个类文件专用于枚举!
为此,我执行以下操作:
<c:set var="abc">
<%=Status.OLD.getStatus()%>
</c:set>
<c:if test="${someVariable == abc}">
....
</c:if>
它看起来很丑,但有效!
我对 Kornel 的问题没有答案,但我对其他脚本示例有意见。大多数表达式都隐式信任 toString()
,但 Enum.valueOf()
需要一个来自/匹配 Enum.name()
属性的值。所以应该使用例如:
<% pageContext.setAttribute("Status_OLD", Status.OLD.name()); %>
...
<c:when test="${someModel.status == Status_OLD}"/>...</c:when>
向枚举添加一个方法,例如:
public String getString() {
return this.name();
}
例如
public enum MyEnum {
VALUE_1,
VALUE_2;
public String getString() {
return this.name();
}
}
然后你可以使用:
<c:if test="${myObject.myEnumProperty.string eq 'VALUE_2'}">...</c:if>
使用 MVC 框架时,我将以下内容放入我的控制器中。
request.setAttribute(RequestParameterNamesEnum.INBOX_ACTION.name(), RequestParameterNamesEnum.INBOX_ACTION.name());
这允许我在我的 JSP 页面中使用以下内容。
<script> var url = 'http://www.nowhere.com/?${INBOX_ACTION}=' + someValue;</script>
它也可以用于您的比较
<c:when test="${someModel.action == INBOX_ACTION}">
我更喜欢放入字符串文字。
<%@ page import="com.example.Status" %>
1. ${dp.status eq Title.VALID.getStatus()}
2. ${dp.status eq Title.VALID}
3. ${dp.status eq Title.VALID.toString()}
将导入放在顶部,在 JSP 页面标题中
如果您想使用 getStatus 方法,请使用 #1
如果要使用枚举元素本身,请使用 #2 或 #3
您可以使用 == 代替 eq
我通常认为将 java 代码混合到 jsps/tag 文件中是不好的做法。使用 'eq' 应该可以解决问题:
<c:if test="${dp.Status eq 'OLD'}">
...
</c:if>
==
而不是 eq
是一种不好的做法?它们的作用完全相同,因此没有“技巧”。
当有很多点可以使用时,我会这样做......
public enum Status {
VALID("valid"), OLD("old");
private final String val;
Status(String val) {
this.val = val;
}
public String getStatus() {
return val;
}
public static void setRequestAttributes(HttpServletRequest request) {
Map<String,String> vals = new HashMap<String,String>();
for (Status val : Status.values()) {
vals.put(val.name(), val.value);
}
request.setAttribute("Status", vals);
}
}
JSP
<%@ page import="...Status" %>
<% Status.setRequestAttributes(request) %>
<c:when test="${dp.status eq Status.VALID}">
...
在 Java 类中:
public class EnumTest{
//Other property link
private String name;
....
public enum Status {
ACTIVE,NEWLINK, BROADCASTED, PENDING, CLICKED, VERIFIED, AWARDED, INACTIVE, EXPIRED, DELETED_BY_ADMIN;
}
private Status statusobj ;
//Getter and Setters
}
所以现在 POJO 和 enum obj 被创建了。现在 EnumTest 您将在 servlet 或控制器类 session.setAttribute("enumTest", EnumTest ); 中设置会话对象。
在 JSP 页面中
<c:if test="${enumTest.statusobj == 'ACTIVE'}">
//TRUE??? THEN PROCESS SOME LOGIC