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