Domanda

Ho un Enum chiamato Status definito come tale:

public enum Status { 

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

    private final String val;

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

    public String getStatus() {
        return val;
    }

}

Vorrei accedere al valore di VALID da un tag JSTL. In particolare l'attributo test del tag <c:when>. Per es.

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

Non sono sicuro che sia possibile.

È stato utile?

Soluzione

Un semplice confronto con le stringhe funziona:

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

Altri suggerimenti

Se si utilizza Spring MVC, lo Spring Expression Language (SpEL) può essere utile:

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

Qui hai 3 scelte, nessuna delle quali è perfetta:

  1. Puoi usare uno scriptlet nell'attributo test:

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

    Questo usa l'enum, ma usa anche uno scriptlet, che non è il " modo giusto " in JSP 2.0. Ma soprattutto, questo non funziona quando si desidera aggiungere un'altra condizione allo stesso when usando ${}. Ciò significa che tutte le variabili che si desidera testare devono essere dichiarate in uno scriptlet o mantenute su richiesta o sessione (pageContext la variabile non è disponibile in .tag file).

  2. Puoi confrontare con string:

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

    Sembra pulito, ma stai introducendo una stringa che duplica il valore enum e non può essere convalidato dal compilatore. Quindi se rimuovi quel valore dall'enum o lo rinomini, non vedrai che questa parte di codice non è più accessibile. Fondamentalmente devi fare una ricerca / sostituire ogni volta il codice.

  3. Puoi aggiungere ciascuno dei valori enum che usi nel contesto della pagina:

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

    e quindi puoi farlo:

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

Preferisco l'ultima opzione (3), anche se usa anche uno scriptlet. Questo perché lo utilizza solo quando si imposta il valore. Successivamente puoi usarlo in espressioni EL più complesse, insieme ad altre condizioni EL. Nell'opzione (1) non è possibile utilizzare uno scriptlet e un'espressione EL nell'attributo <=> di un singolo tag <=>.

Quindi, per risolvere completamente il mio problema, dovevo fare quanto segue:

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

Quindi sono stato in grado di fare:

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

che ha funzionato come previsto.

Ecco altre due possibilità:

Costanti JSP EL 3.0

Finché stai utilizzando almeno la versione 3.0 di EL, puoi importare costanti nella tua pagina come segue:

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

Tuttavia, alcuni IDE non lo comprendono ancora (ad es. IntelliJ ) non riceverà alcun avviso se si effettua un refuso, fino al runtime.

Questo sarebbe il mio metodo preferito una volta ottenuto il supporto IDE corretto.

Metodi di supporto

Potresti semplicemente aggiungere getter al tuo 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;
  }
}

Quindi nel tuo JSP:

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

Questo è supportato in tutti gli IDE e funzionerà anche se non è ancora possibile utilizzare EL 3.0. Questo è quello che faccio al momento perché mantiene tutta la logica racchiusa nel mio enum.

Fai anche attenzione se è possibile che la variabile che memorizza l'enum sia nulla. Dovresti verificarlo prima se il tuo codice non garantisce che non sia nullo:

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

Penso che questo metodo sia superiore a quelli in cui hai impostato un valore intermedio nel JSP perché devi farlo su ogni pagina in cui devi usare l'enum. Tuttavia, con questa soluzione devi dichiarare il getter solo una volta.

A tal fine, faccio quanto segue:

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

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

Sembra brutto, ma funziona!

Non ho una risposta alla domanda di Kornel, ma ho un'osservazione sugli altri esempi di script. La maggior parte dell'espressione si fida implicitamente di toString(), ma Enum.valueOf() prevede un valore che proviene / corrisponde alla proprietà Enum.name(). Quindi si dovrebbe usare ad esempio:

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

Aggiungi un metodo all'enum come:

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

Ad esempio

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

Quindi puoi usare:

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

Quando utilizzo un framework MVC ho inserito quanto segue nel mio controller.

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

Questo mi permette di usare quanto segue nella mia Pagina JSP.

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

Può anche essere usato nel tuo confronto

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

Che preferisco piuttosto che inserire una stringa letterale.

<%@ 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()}
  • Metti l'importazione in in alto , nell'intestazione della pagina JSP
  • Se vuoi lavorare con metodo getStatus , usa #1
  • Se vuoi lavorare con l'elemento enum stesso, usa # 2 o # 3
  • Puoi utilizzare == invece di eq

In genere considero una cattiva pratica mescolare il codice java in file jsps / tag. Usare 'eq' dovrebbe fare il trucco:

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

Lo faccio in questo modo quando ci sono molti punti da usare ...

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

Nella classe 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
}

Quindi ora vengono creati POJO ed enum obj. Ora EnumTest verrà impostato nell'oggetto sessione utilizzando nella classe servlet o controller session.setAttribute (" enumTest " ;, EnumTest);

Nella pagina JSP

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

//TRUE??? THEN PROCESS SOME LOGIC
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top