webentwicklung-frage-antwort-db.com.de

Greifen Sie mit EL mit JSTL auf den Enum-Wert zu

Ich habe eine Enumeration namens Status als solche definiert:

public enum Status { 

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

    private final String val;

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

    public String getStatus() {
        return val;
    }

}

Ich möchte über ein JSTL-Tag auf den Wert von VALID zugreifen. Insbesondere das test -Attribut des <c:when> Etikett. Z.B.

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

Ich bin mir nicht sicher, ob das möglich ist.

102
IaCoder

Ein einfacher Vergleich mit Zeichenfolgen funktioniert:

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

Bei Verwendung von Spring MVC kann die Spring Expression Language (SpEL) hilfreich sein:

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

Sie haben hier 3 Möglichkeiten, von denen keine perfekt ist:

  1. Sie können ein Scriptlet im Attribut test verwenden:

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

    Hierbei wird die Aufzählung verwendet, es wird jedoch auch ein Scriptlet verwendet, was in JSP 2.0 nicht der "richtige Weg" ist. Vor allem aber funktioniert dies nicht, wenn Sie demselben when mit ${} Eine weitere Bedingung hinzufügen möchten. Das bedeutet, dass alle Variablen, die Sie testen möchten, in einem Scriptlet deklariert oder in einer Anforderung oder Sitzung gespeichert werden müssen (pageContext -Variable ist in .tag - Dateien nicht verfügbar).

  2. Sie können gegen Zeichenfolge vergleichen:

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

    Dies sieht sauber aus, aber Sie führen eine Zeichenfolge ein, die den Enum-Wert dupliziert und vom Compiler nicht überprüft werden kann. Wenn Sie diesen Wert aus der Aufzählung entfernen oder umbenennen, werden Sie nicht feststellen, dass auf diesen Teil des Codes nicht mehr zugegriffen werden kann. Grundsätzlich müssen Sie den Code jedes Mal durchsuchen/ersetzen.

  3. Sie können jeden der von Ihnen verwendeten Aufzählungswerte in den Seitenkontext einfügen:

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

    und dann kannst du das machen:

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

Ich bevorzuge die letzte Option (3), obwohl sie auch ein Scriptlet verwendet. Dies liegt daran, dass es nur verwendet wird, wenn Sie den Wert festlegen. Später können Sie es zusammen mit anderen EL-Bedingungen in komplexeren EL-Ausdrücken verwenden. In Option (1) können Sie kein Scriptlet und keinen EL-Ausdruck im test -Attribut eines einzelnen when -Tags verwenden.

38
Matt

Um mein Problem vollständig zu lösen, musste ich Folgendes tun:

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

Dann konnte ich tun:

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

das hat wie erwartet funktioniert.

22
IaCoder

Hier sind zwei weitere Möglichkeiten:

JSP EL 3.0-Konstanten

Solange Sie mindestens Version 3.0 von EL verwenden, können Sie Konstanten wie folgt in Ihre Seite importieren:

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

Einige IDEs verstehen dies jedoch noch nicht (z. B. IntelliJ ), sodass Sie bis zur Laufzeit keine Warnungen erhalten, wenn Sie einen Tippfehler machen.

Dies wäre meine bevorzugte Methode, sobald sie die richtige IDE Unterstützung erhält.

Hilfsmethoden

Sie können Ihrer Aufzählung einfach Getter hinzufügen.

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

Dann in Ihrer JSP:

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

Dies wird in allen IDEs unterstützt und funktioniert auch, wenn Sie EL 3.0 noch nicht verwenden können. Dies ist, was ich im Moment tue, weil es die gesamte Logik in meiner Aufzählung festhält.

Seien Sie auch vorsichtig, wenn die Variable, in der die Aufzählung gespeichert ist, möglicherweise null ist. Sie müssen dies zuerst überprüfen, wenn Ihr Code nicht garantiert, dass er nicht null ist:

<c:when test="${not empty db.status and dp.status.valid}">

Ich denke, diese Methode ist denen überlegen, bei denen Sie einen Zwischenwert in der JSP festlegen, da Sie dies auf jeder Seite tun müssen, auf der Sie die Aufzählung verwenden müssen. Mit dieser Lösung müssen Sie den Getter jedoch nur einmal deklarieren.

12

Zu diesem Zweck mache ich folgendes:

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

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

Es sieht hässlich aus, funktioniert aber!

10
Dmitry R

Ich habe keine Antwort auf die Frage von Kornel, aber ich habe eine Bemerkung zu den anderen Skriptbeispielen. Die meisten Ausdrücke vertrauen implizit auf die toString(), aber die Enum.valueOf() erwartet einen Wert, der von der Enum.name() -Eigenschaft stammt/mit dieser übereinstimmt. So sollte man z.

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

Fügen Sie dem Enum eine Methode wie folgt hinzu:

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

Beispielsweise

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

Dann können Sie verwenden:

<c:if test="${myObject.myEnumProperty.string eq 'VALUE_2'}">...</c:if>
2
Dean

Bei Verwendung eines MVC-Frameworks habe ich Folgendes in meinen Controller eingefügt.

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

Auf diese Weise kann ich auf meiner JSP-Seite Folgendes verwenden.

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

Es kann auch in Ihrem Vergleich verwendet werden

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

Was ich dem Einfügen eines String-Buchstabens vorziehe.

<%@ 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()}
  • Fügen Sie den Import am oben in den JSP-Seitenkopf ein
  • Wenn Sie mit getStatus-Methode arbeiten möchten, verwenden Sie # 1
  • Wenn Sie mit dem enum-Element selbst arbeiten möchten, verwenden Sie entweder # 2 oder #
  • Sie können == anstelle von eq verwenden
0
Mehdi