Access enum value using EL with JSTL

Mam Enum o nazwie Status zdefiniowane jako takie:

public enum Status { 

    VALID("valid"), OLD("old");

    private final String val;

    Status(String val) {
        this.val = val;
    }

    public String getStatus() {
        return val;
    }

}

Chciałbym uzyskać dostęp do wartości VALID z tagu JSTL. W szczególności atrybut test znacznika <c:when>. Np.

<c:when test="${dp.status eq Status.VALID">
Nie wiem, czy to możliwe.
Author: ROMANIA_engineer, 2008-09-24

11 answers

Proste porównanie ze stringami działa:

<c:when test="${someModel.status == 'OLD'}">
 104
Author: Alexander Vasiljev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-07 11:04:09

Jeśli używasz Spring MVC, język wyrażenia Spring (SpEL) może być pomocny:

<spring:eval expression="dp.status == T(com.example.Status).VALID" var="isValid" />
<c:if test="${isValid}">
   isValid
</c:if>
 53
Author: James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-07 11:04:42

Masz tu 3 opcje, z których żadna nie jest idealna:

  1. Możesz użyć skryptu w atrybucie test:

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

    To używa enum, ale używa również skryptleta, który nie jest "właściwą drogą" w JSP 2.0. Ale co najważniejsze, nie działa to, gdy chcesz dodać kolejny warunek do tego samego when za pomocą ${}. Oznacza to, że wszystkie zmienne, które chcesz przetestować, muszą być zadeklarowane w skrypcie lub przechowywane w request lub session (pageContext zmienna nie jest dostępna w plikach .tag).

  2. Możesz porównać z ciągiem znaków:

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

    Wygląda to czysto, ale wprowadzasz ciąg znaków, który duplikuje wartość enum i nie może być zweryfikowany przez kompilator. Jeśli więc usuniesz tę wartość z enum lub zmienisz jej nazwę, nie zobaczysz, że ta część kodu nie jest już dostępna. W zasadzie za każdym razem musisz przeszukiwać/zastępować kod.

  3. Możesz dodać każdy z wartości enum używane w kontekście strony:

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

    I wtedy możesz to zrobić:

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

Wolę ostatnią opcję (3), mimo że używa również skryptleta. Dzieje się tak, ponieważ używa go tylko wtedy, gdy ustawisz wartość. Później można go używać w bardziej złożonych wyrażeniach EL, wraz z innymi warunkami EL. Podczas gdy w option (1) nie można użyć skryptleta i wyrażenia EL w atrybucie test pojedynczego znacznika when.

 36
Author: Matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-07 11:05:42

Więc aby mój problem został w pełni rozwiązany, musiałem wykonać następujące czynności:

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

Potem udało mi się zrobić:

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

Który działał zgodnie z oczekiwaniami.

 21
Author: IaCoder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-07 11:05:15

W tym celu wykonuję następujące czynności:

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

<c:if test="${someVariable == abc}">
    ....
</c:if>
Wygląda brzydko, ale działa!
 9
Author: Xtreme Biker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-07 11:06:49

Oto jeszcze dwie możliwości:

JSP El 3.0 Stałe

Tak długo, jak używasz co najmniej wersji 3.0 EL, możesz zaimportować stałe do swojej strony w następujący sposób:

<%@ page import="org.example.Status" %>
<c:when test="${dp.status eq Status.VALID}">

Jednak niektóre IDE jeszcze tego nie rozumieją (np.IntelliJ ), więc nie otrzymasz żadnych ostrzeżeń, jeśli popełnisz literówkę, aż do czasu uruchomienia.

To byłaby moja preferowana metoda, gdy tylko uzyska odpowiednie wsparcie IDE.

Metody Pomocnicze

Możesz po prostu dodać gettery do swojego enum.

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;
  }
}

Następnie w JSP:

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

Jest to obsługiwane we wszystkich IDE i będzie działać, jeśli nie możesz jeszcze użyć EL 3.0. To jest to, co robię w tej chwili, ponieważ trzyma całą logikę zawiniętą w moim enum.

Należy również uważać, czy zmienna przechowująca enum może mieć wartość null. Musisz najpierw to sprawdzić, jeśli twój kod nie gwarantuje, że nie jest null:

<c:when test="${not empty db.status and dp.status.valid}">
Myślę, że ta metoda jest lepsza od tych, w których ustawiasz pośrednika wartość w JSP, ponieważ musisz to zrobić na każdej stronie, na której musisz użyć enum. Jednak przy takim rozwiązaniu wystarczy zadeklarować getter tylko raz.
 7
Author: Rupert Madden-Abbott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-07 08:46:05

Nie mam odpowiedzi na pytanie Kornela, ale mam uwagę na inne przykłady skryptów. Większość wyrażeń zaufała niejawnie toString(), ale Enum.valueOf() oczekuje wartości, która pochodzi z / pasuje do Właściwości Enum.name(). Należy więc użyć np.:

<% pageContext.setAttribute("Status_OLD", Status.OLD.name()); %>
...
<c:when test="${someModel.status == Status_OLD}"/>...</c:when>
 3
Author: eremmel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-17 15:32:31

Dodaj metodę do enum jak:

public String getString() {
    return this.name();
}

Na przykład

public enum MyEnum {
    VALUE_1,
    VALUE_2;
    public String getString() {
        return this.name();
    }
}

Wtedy możesz użyć:

<c:if test="${myObject.myEnumProperty.string eq 'VALUE_2'}">...</c:if>
 2
Author: Dean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-15 01:34:48

Podczas korzystania z frameworku MVC umieszczam w moim kontrolerze następujące elementy.

request.setAttribute(RequestParameterNamesEnum.INBOX_ACTION.name(), RequestParameterNamesEnum.INBOX_ACTION.name());

To pozwala mi używać następujących elementów na mojej stronie JSP.

<script> var url = 'http://www.nowhere.com/?${INBOX_ACTION}=' + someValue;</script>

Może być również użyty w Twoim porównaniu

<c:when test="${someModel.action == INBOX_ACTION}">

Które wolę od umieszczania ciągów literalnych.

 1
Author: ElectronicBlacksmith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-10 16:21:41

Ogólnie uważam, że mieszanie kodu Javy z plikami jsps/tag jest złą praktyką. Użycie ' eq ' powinno załatwić sprawę:

<c:if test="${dp.Status eq 'OLD'}">
  ...
</c:if>
 -1
Author: Eclatante,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-24 02:17:58

W Klasie 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
}

Więc teraz powstaje POJO i enum obj. Teraz EnumTest ustawisz w obiekcie session używając w klasie servlet lub controller sesja.setAttribute ("enumTest", EnumTest );

Na stronie JSP

<c:if test="${enumTest.statusobj == 'ACTIVE'}">

//TRUE??? THEN PROCESS SOME LOGIC
 -2
Author: Pavan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-15 19:51:27