java - tag - jstl maven
Acceda al valor de Enum usando EL con JSTL (11)
Tengo un Enum llamado Status definido como tal:
public enum Status {
VALID("valid"), OLD("old");
private final String val;
Status(String val) {
this.val = val;
}
public String getStatus() {
return val;
}
}
Me gustaría acceder al valor de VALID
de una etiqueta JSTL. Específicamente, el atributo de test
de la etiqueta <c:when>
. P.ej
<c:when test="${dp.status eq Status.VALID">
No estoy seguro si esto es posible.
Agregue un método a la enumeración como:
public String getString() {
return this.name();
}
Por ejemplo
public enum MyEnum {
VALUE_1,
VALUE_2;
public String getString() {
return this.name();
}
}
Entonces puedes usar:
<c:if test="${myObject.myEnumProperty.string eq ''VALUE_2''}">...</c:if>
Aquí hay dos posibilidades más:
Constantes JSP EL 3.0
Siempre que use al menos la versión 3.0 de EL, puede importar constantes en su página de la siguiente manera:
<%@ page import="org.example.Status" %>
<c:when test="${dp.status eq Status.VALID}">
Sin embargo, algunos IDEs aún no lo entienden (por ejemplo, IntelliJ ) por lo que no recibirás ninguna advertencia si haces un error tipográfico, hasta el tiempo de ejecución.
Este sería mi método preferido una vez que reciba el soporte IDE adecuado.
Métodos de ayuda
Podrías agregar getters a tu 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;
}
}
Entonces en tu JSP:
<c:when test="${dp.status.valid}">
Esto es compatible con todos los IDEs y también funcionará si aún no puede usar EL 3.0. Esto es lo que hago en este momento porque mantiene toda la lógica envuelta en mi enumeración.
También tenga cuidado si es posible que la variable que almacena la enumeración sea nula. Debería verificarlo primero si su código no garantiza que no sea nulo:
<c:when test="${not empty db.status and dp.status.valid}">
Creo que este método es superior a aquellos en los que establece un valor intermedio en el JSP porque tiene que hacer eso en cada página donde necesita usar el enum. Sin embargo, con esta solución solo necesita declarar el getter una vez.
Cuando uso un marco MVC pongo lo siguiente en mi controlador.
request.setAttribute(RequestParameterNamesEnum.INBOX_ACTION.name(), RequestParameterNamesEnum.INBOX_ACTION.name());
Esto me permite usar lo siguiente en mi página JSP.
<script> var url = ''http://www.nowhere.com/?${INBOX_ACTION}='' + someValue;</script>
También se puede usar en tu comparación
<c:when test="${someModel.action == INBOX_ACTION}">
Lo cual prefiero sobre poner una cadena literal.
En general, considero que es una mala práctica mezclar el código Java en archivos jsps / tag. Usar ''eq'' debería hacer el truco:
<c:if test="${dp.Status eq ''OLD''}">
...
</c:if>
No tengo una respuesta a la pregunta de Kornel, pero tengo un comentario sobre los otros ejemplos de guiones. La mayor parte de la expresión confía implícitamente en toString()
, pero Enum.valueOf()
espera un valor que proviene de / coincide con la propiedad Enum.name()
. Entonces uno debería usar, por ejemplo:
<% pageContext.setAttribute("Status_OLD", Status.OLD.name()); %>
...
<c:when test="${someModel.status == Status_OLD}"/>...</c:when>
Para este propósito, hago lo siguiente:
<c:set var="abc">
<%=Status.OLD.getStatus()%>
</c:set>
<c:if test="${someVariable == abc}">
....
</c:if>
Se ve feo, pero funciona!
Para resolver mi problema por completo, necesitaba hacer lo siguiente:
<% pageContext.setAttribute("old", Status.OLD); %>
Entonces pude hacer:
<c:when test="${someModel.status == old}"/>...</c:when>
que funcionó como se esperaba
Si usa Spring MVC, el Lenguaje de Expresión de Primavera (SpEL) puede ser útil:
<spring:eval expression="dp.status == T(com.example.Status).VALID" var="isValid" />
<c:if test="${isValid}">
isValid
</c:if>
Tienes 3 opciones aquí, ninguna de las cuales es perfecta:
Puede usar un scriptlet en el atributo de
test
:<c:when test="<%= dp.getStatus() == Status.VALID %>">
Esto usa la enumeración, pero también usa un scriptlet, que no es el "camino correcto" en JSP 2.0. Pero lo más importante es que esto no funciona cuando desea agregar otra condición al mismo uso de
${}
. Y esto significa que todas las variables que desea probar deben declararse en un scriptlet, o mantenerse en la solicitud, o en la sesión (la variablepageContext
no está disponible en los archivos.tag
).Puedes comparar contra la secuencia:
<c:when test="${dp.status == ''VALID''}">
Esto parece limpio, pero está introduciendo una cadena que duplica el valor enum y no puede ser validado por el compilador. Entonces, si elimina ese valor de la enumeración o lo renombra, no verá que esta parte del código ya no está accesible. Básicamente tienes que buscar / reemplazar a través del código cada vez.
Puede agregar cada uno de los valores enum que usa en el contexto de la página:
<c:set var="VALID" value="<%=Status.VALID%>"/>
y luego puedes hacer esto:
<c:when test="${dp.status == VALID}">
Prefiero la última opción (3), aunque también usa scriptlet. Esto se debe a que solo lo usa cuando establece el valor. Más adelante, puede usarlo en expresiones EL más complejas, junto con otras condiciones EL. Mientras que en la opción (1) no puede usar un scriptlet y una expresión EL en el atributo de test
de una sola etiqueta.
Una simple comparación contra trabajos de cuerdas:
<c:when test="${someModel.status == ''OLD''}">
En Java Class:
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
}
Entonces ahora se crea POJO y enum obj. Ahora, EnumTest establecerá el objeto de sesión utilizando en el servlet o clase de controlador session.setAttribute ("enumTest", EnumTest);
En la página JSP
<c:if test="${enumTest.statusobj == ''ACTIVE''}">
//TRUE??? THEN PROCESS SOME LOGIC