Ответ 1
Простым сравнением с строками работает:
<c:when test="${someModel.status == 'OLD'}">
У меня есть Enum, называемый Status, определяемый как таковой:
public enum Status {
VALID("valid"), OLD("old");
private final String val;
Status(String val) {
this.val = val;
}
public String getStatus() {
return val;
}
}
Я хотел бы получить доступ к значению VALID
из тега JSTL. В частности, атрибут test
тега <c:when>
. Например.
<c:when test="${dp.status eq Status.VALID">
Я не уверен, что это возможно.
Простым сравнением с строками работает:
<c:when test="${someModel.status == 'OLD'}">
При использовании Spring MVC может быть полезен <Язык > Язык выражения Spring:
<spring:eval expression="dp.status == T(com.example.Status).VALID" var="isValid" />
<c:if test="${isValid}">
isValid
</c:if>
У вас есть 3 варианта, ни один из которых не идеален:
Вы можете использовать скриптлет в атрибуте test
:
<c:when test="<%= dp.getStatus() == Status.VALID %>">
Это использует перечисление, но также использует скриптлет, который не является "правильным способом" в JSP 2.0. Но самое главное, это не работает, если вы хотите добавить другое условие к тому же when
, используя ${}
. И это означает, что все переменные, которые вы хотите протестировать, должны быть объявлены в сценарии или сохранены в запросе, или переменная session (pageContext
недоступна в файлах .tag
).
Вы можете сравнить со строкой:
<c:when test="${dp.status == 'VALID'}">
Это выглядит чисто, но вы вводите строку, которая дублирует значение перечисления и не может быть проверена компилятором. Поэтому, если вы удалите это значение из перечисления или переименуете его, вы не увидите, что эта часть кода больше не доступна. Вы в основном должны выполнять поиск/замену через код каждый раз.
Вы можете добавить каждое значение перечисления, которое вы используете в контексте страницы:
<c:set var="VALID" value="<%=Status.VALID%>"/>
а затем вы можете сделать это:
<c:when test="${dp.status == VALID}">
Я предпочитаю последний вариант (3), хотя он также использует скриптлет. Это связано с тем, что он использует его только при установке значения. Позже вы можете использовать его в более сложных выражениях EL вместе с другими условиями EL. Хотя в опции (1) вы не можете использовать скриптлет и выражение EL в атрибуте test
одного тега when
.
Итак, чтобы полностью решить мою проблему, мне нужно было сделать следующее:
<% pageContext.setAttribute("old", Status.OLD); %>
Тогда я смог:
<c:when test="${someModel.status == old}"/>...</c:when>
который работал как ожидалось.
Вот еще две возможности:
Пока вы используете как минимум версию 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, потому что вы должны делать это на каждой странице, где вам нужно использовать enum. Однако с этим решением вам нужно только объявить получатель один раз.
Для этого я делаю следующее:
<c:set var="abc">
<%=Status.OLD.getStatus()%>
</c:set>
<c:if test="${someVariable == abc}">
....
</c:if>
Это выглядит уродливо, но работает!
У меня нет ответа на вопрос Корнеля, но у меня есть замечание о других примерах script. Большая часть выражения неявно ссылается на 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()}
Обычно я считаю неправильной практикой смешивать java-код в файлы jsps/tag. Использование 'eq' должно сделать трюк:
<c:if test="${dp.Status eq 'OLD'}">
...
</c:if>
Я делаю это так, когда есть много точек, чтобы использовать...
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 вы установите для объекта сеанса, используя класс сервлета или контроллера session.setAttribute( "enumTest", EnumTest);
На странице JSP
<c:if test="${enumTest.statusobj == 'ACTIVE'}">
//TRUE??? THEN PROCESS SOME LOGIC