Получите доступ к значению Enum, используя EL с JSTL - PullRequest
102 голосов
/ 24 сентября 2008

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

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

Ответы [ 12 ]

111 голосов
/ 15 декабря 2008

Простое сравнение со строковыми произведениями:

<c:when test="${someModel.status == 'OLD'}">
54 голосов
/ 02 мая 2011

При использовании Spring MVC может быть полезен язык выражений Spring (SpEL):

<spring:eval expression="dp.status == T(com.example.Status).VALID" var="isValid" />
<c:if test="${isValid}">
   isValid
</c:if>
38 голосов
/ 22 мая 2013

У вас есть 3 варианта, ни один из которых не идеален:

  1. Вы можете использовать скриптлет в атрибуте test:

    <c:when test="<%= dp.getStatus() == Status.VALID %>">

    Это использует enum, но также использует скриптлет, который не является "правильным способом" в JSP 2.0. Но самое главное, это не работает, когда вы хотите добавить другое условие к тому же when, используя ${}. А это означает, что все переменные, которые вы хотите проверить, должны быть объявлены в скриптлете, сохранены в запросе или сеансе (переменная pageContext недоступна в .tag файлах).

  2. Вы можете сравнить со строкой:

    <c:when test="${dp.status == 'VALID'}">

    Это выглядит чисто, но вы вводите строку, которая дублирует значение enum и не может быть проверена компилятором. Поэтому, если вы удалите это значение из перечисления или переименуете его, вы не увидите, что эта часть кода больше недоступна. В основном вам нужно каждый раз выполнять поиск / замену кода.

  3. Вы можете добавить каждое из перечисленных значений в контекст страницы:

    <c:set var="VALID" value="<%=Status.VALID%>"/>

    и тогда вы можете сделать это:

    <c:when test="${dp.status == VALID}">

Я предпочитаю последний вариант (3), хотя он также использует скриптлет. Это потому, что он использует его только при установке значения. Позже вы можете использовать его в более сложных выражениях EL вместе с другими условиями EL. В варианте (1) нельзя использовать скриптлет и выражение EL в атрибуте test одного тега when.

22 голосов
/ 25 сентября 2008

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

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

Тогда я смог сделать:

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

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

11 голосов
/ 07 июля 2017

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

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

10 голосов
/ 10 июля 2009

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

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

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

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

3 голосов
/ 17 марта 2011

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

<% pageContext.setAttribute("Status_OLD", Status.OLD.name()); %>
...
<c:when test="${someModel.status == Status_OLD}"/>...</c:when>
2 голосов
/ 15 декабря 2010

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

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>
1 голос
/ 10 июля 2017

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

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

0 голосов
/ 12 ноября 2018

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

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