web-dev-qa-db-fra.com

Accédez à la valeur Enum en utilisant EL avec JSTL

J'ai un Enum appelé Status défini comme tel:

public enum Status { 

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

    private final String val;

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

    public String getStatus() {
        return val;
    }

}

J'aimerais accéder à la valeur de VALID à partir d'une balise JSTL. Plus précisément, l'attribut test de la <c:when> tag. Par exemple.

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

Je ne sais pas si c'est possible.

102
IaCoder

Une simple comparaison avec les œuvres de chaîne:

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

Si vous utilisez Spring MVC, le langage d'expression Spring (SpEL) peut être utile:

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

Vous avez 3 choix ici, dont aucun n'est parfait:

  1. Vous pouvez utiliser un scriptlet dans l'attribut test:

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

    Cela utilise l'énumération, mais également un scriptlet, ce qui n'est pas la "bonne façon" dans JSP 2.0. Mais surtout, cela ne fonctionne pas lorsque vous souhaitez ajouter une autre condition au même when en utilisant ${}. Et cela signifie que toutes les variables que vous souhaitez tester doivent être déclarées dans un scriptlet ou conservées dans une requête ou une session (pageContext la variable n'est pas disponible dans .tag des dossiers).

  2. Vous pouvez comparer la chaîne:

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

    Cela semble propre, mais vous introduisez une chaîne qui duplique la valeur enum et ne peut pas être validée par le compilateur. Donc, si vous supprimez ou renommez cette valeur de l'énumération, vous ne verrez plus que cette partie du code n'est plus accessible. Vous devez fondamentalement faire une recherche/remplacement par le code à chaque fois.

  3. Vous pouvez ajouter chacune des valeurs enum que vous utilisez dans le contexte de la page:

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

    et alors vous pouvez faire ceci:

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

Je préfère la dernière option (3), même si elle utilise également un scriptlet. En effet, il ne l'utilise que lorsque vous définissez la valeur. Plus tard, vous pourrez l'utiliser dans des expressions EL plus complexes, avec d'autres conditions EL. Dans l'option (1), vous ne pouvez pas utiliser de scriptlet et une expression EL dans l'attribut test d'une seule balise when.

38
Matt

Donc, pour que mon problème soit complètement résolu, je devais procéder comme suit:

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

Ensuite j'ai pu faire:

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

qui a fonctionné comme prévu.

22
IaCoder

Voici deux autres possibilités:

Constantes JSP EL 3.0

Tant que vous utilisez au moins la version 3.0 de EL, vous pouvez importer des constantes dans votre page comme suit:

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

Cependant, certains IDE ne comprennent pas encore cela (par exemple, IntelliJ ). Par conséquent, vous ne recevrez aucun avertissement si vous faites une faute de frappe jusqu'à l'exécution.

Ce serait ma méthode préférée une fois que cela devient approprié IDE support.

Méthodes d'assistance

Vous pouvez simplement ajouter des accesseurs à votre 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;
  }
}

Puis dans votre JSP:

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

Ceci est supporté par tous les IDE et fonctionnera également si vous ne pouvez pas utiliser EL 3.0 pour le moment. C’est ce que je fais en ce moment, parce que toute la logique est enchâssée dans mon enum.

Faites également attention s'il est possible que la variable stockant l'énumération soit nulle. Vous devrez d'abord vérifier si votre code ne garantit pas qu'il n'est pas nul:

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

Je pense que cette méthode est supérieure à celles où vous définissez une valeur intermédiaire dans le JSP car vous devez le faire sur chaque page où vous devez utiliser l'énum. Cependant, avec cette solution, il suffit de déclarer le getter une fois.

12

Pour cela, je fais ce qui suit:

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

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

C'est moche, mais ça marche!

10
Dmitry R

Je n'ai pas de réponse à la question de Kornel, mais j'ai une remarque à propos des autres exemples de script. La plupart des expressions font confiance implicitement à la toString(), mais la Enum.valueOf() s'attend à une valeur provenant de/qui correspond à la propriété Enum.name(). Donc, on devrait utiliser par exemple:

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

Ajouter une méthode à l'énumération comme:

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

Par exemple

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

Ensuite, vous pouvez utiliser:

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

Lors de l'utilisation d'un framework MVC, je place les éléments suivants dans mon contrôleur.

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

Cela me permet d’utiliser les éléments suivants dans ma page JSP.

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

Il peut également être utilisé dans votre comparaison

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

Ce que je préfère plutôt que de mettre un littéral de chaîne.

1
<%@ 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()}
  • Placez l'importation à la position haut, dans l'en-tête de page JSP
  • Si vous voulez utiliser méthode getStatus, utilisez # 1
  • Si vous voulez utiliser le élément enum lui-même, utilisez soit # 2 ou #
  • Vous pouvez utiliser == au lieu de eq
0
Mehdi