Доступ к значению Enum с использованием EL с JSTL

У меня есть 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">

Я не уверен, что это возможно.

Ответы

Ответ 1

Простым сравнением с строками работает:

<c:when test="${someModel.status == 'OLD'}">

Ответ 2

При использовании Spring MVC может быть полезен <Язык > Язык выражения Spring:

<spring:eval expression="dp.status == T(com.example.Status).VALID" var="isValid" />
<c:if test="${isValid}">
   isValid
</c:if>

Ответ 3

У вас есть 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.

Ответ 4

Итак, чтобы полностью решить мою проблему, мне нужно было сделать следующее:

<% pageContext.setAttribute("old", Status.OLD); %>

Тогда я смог:

<c:when test="${someModel.status == old}"/>...</c:when>

который работал как ожидалось.

Ответ 5

Вот еще две возможности:

Константы 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, потому что вы должны делать это на каждой странице, где вам нужно использовать enum. Однако с этим решением вам нужно только объявить получатель один раз.

Ответ 6

Для этого я делаю следующее:

<c:set var="abc">
    <%=Status.OLD.getStatus()%>
</c:set>

<c:if test="${someVariable == abc}">
    ....
</c:if>

Это выглядит уродливо, но работает!

Ответ 7

У меня нет ответа на вопрос Корнеля, но у меня есть замечание о других примерах script. Большая часть выражения неявно ссылается на toString(), но Enum.valueOf() ожидает значение, которое исходит от/соответствует свойству Enum.name(). Поэтому следует использовать, например:

<% pageContext.setAttribute("Status_OLD", Status.OLD.name()); %>
...
<c:when test="${someModel.status == Status_OLD}"/>...</c:when>

Ответ 8

Добавьте метод к перечислению вроде:

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>

Ответ 9

При использовании структуры 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}">

Я предпочитаю использовать строковый литерал.

Ответ 10

<%@ 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
  • Если вы хотите работать с самим элементом enum, используйте либо # 2, либо # 3
  • Вы можете использовать == вместо эквалайзера

Ответ 11

Обычно я считаю неправильной практикой смешивать java-код в файлы jsps/tag. Использование 'eq' должно сделать трюк:

<c:if test="${dp.Status eq 'OLD'}">
  ...
</c:if>

Ответ 12

Я делаю это так, когда есть много точек, чтобы использовать...

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}">
...

Ответ 13

В классе 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