Seguimos con nuestro recorrido por las características de JSF 2.2 . Esta vez veremos el Lenguaje de Expresiones, o también conocido como EL (Expression Language).
El EL es usado en varias tecnologías de JavaEE, tales como JSF, JSP y CDI. Además lo podemos encontrar en entornos stand-alone. Lo que veremos ahora solo es cuando se ejecuta en contenedores Java EE.
Las expresiones nos permite acceder a los datos de los componentes JavaBean. Como sabemos, un JavaBean (no confundir con Enterprise JavaBean) debe tener el siguiente formato:
-
Las propiedades deben accederse usando los métodos con prefijo
setpara poner un valor ygetpara obtener un valor. Para los valores boolean se puede utilizargetois, el resultado es el mismo. -
Después del prefijo, debe comenzar el nombre con mayúscula
-
Los métodos
setsolo deben tener un único parámetro -
Los métodos
getno deben tener ningún parámetro. -
Los métodos son
public
Ejemplo:
public void setNombre(String nombre){
//...
}
public String getNombre(){
//...
}
public boolean isActivo(){
//...
}
Y para accederlo desde un EL, simplemente se utiliza el nombre sin el prefijo, pero comenzando con minúsculas
<c:if test="#{sessionScope.persona.activo}">
Hola #{sessionScope.persona.nombre}
...
</c:if>
Para abreviar, el EL proporciona una manera simple - usando expresiones - para realizar las siguientes tareas:
-
Leer dinámicamente datos almacenados en los componentes JavaBeans, diversas estructuras de datos y objetos implícitos
-
Escribir dinámicamente datos, tales como entradas de formularios a componentes JavaBeans.
-
Invocar arbitrariamente métodos públicos y estáticos.
-
Realizar operaciones aritméticas, lógicas y de cadena.
-
Construir colecciones de objetos y realizar operaciones en colecciones.
Sintaxis de evaluación de expresiones
Existen dos maneras para evaluar una expresión:
-
De manera inmediata
-
De manera diferida.
La manera inmediata se hace cuando se necesita que el valor del componente bean se escriba directamente cuando construye la página. Para ello se utiliza la sintaxis ${}
<c:out value="${persona.nombre}" />
La manera diferida se utiliza cuando el valor a obtener debe pasar por todo el ciclo de vida. Se pueden utilizar para:
-
Leer y escribir datos
-
Utilizar expresiones de método
<h:inputText value="#{persona.nombre}" />
<h:outputText value="#{persona.calcularRenta(tasa.ingreso)}" />
Referenciando expresiones
Para mostrar o manejar las expresiones de objetos, se hace simplemente (como se vió hasta ahora) con la declaración tal cual
#{persona.nombre}
también podemos invocar a la misma propiedad usando corchetes:
#{persona["nombre"]}
Con esto, como podrás imaginar, podrías invocar a cada propiedad de una manera dinámica
#{persona[campoActual]}
Donde campoActual es una variable de tipo String que contiene el nombre del campo a mostrar.
#{ valor == objeto.campo }
Si tenemos una clase enum:
public enum Estado {
activo,enProceso,suspendido,terminado
}
.. también podemos invocarlo desde la expresión:
#{ estado == estado.activo }
Los arreglos también se pueden acceder usando un índice entre corchetes
#{cliente.pedidos[1]}
También podemos manipular mapas (java.util.Map). Supongamos que la propiedad pedidos es un java.util.Map con el key de tipo String, y queremos acceder al pedido con key “teclado”. Estas dos líneas hacen lo mismo:
#{cliente.pedido["teclado"]}
#{cliente.pedido.teclado}
Es decir, manipula los maps como si fueran propiedades de un objeto.
Lambda
También podemos usar las expresiones Lambda. A pesar que son parte de Java SE 8, se pueden usar en expresiones EL de Java EE 7 con Java SE 7.
Para probar las expresiones lambda en Java SE debemos agregar la biblioteca respectiva a nuestro proyecto. Por ello - para efectos de este ejemplo - agregaremos la siguiente dependencia a nuestro proyecto Maven.
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>[3.0-b03,)</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
Y usaremos el paquete javax.el.*. Para nuestro ejemplo usaremos el siguiente código:
void eval(String input) {
System.out.println("\n====");
System.out.println("Cadena EL: " + input);
Object ret = elp.eval(input); //aquí evaluamos el contenido
System.out.println("Valor obtenido: " + ret);
}
Las expresiones Lambda usan el operador flecha (->). Los identificadores que se encuentran a la izquierda del operador son llamados parámetros lambda. El cuerpo, que se encuentra a la derecha del operador, pueden ser expresiones EL. Los parámetros lambda pueden estar envueltos en signos de paréntesis, y pueden ser omitidos si solo tienen un parámetro.
x -> x+1
(x,y) -> x + y
() -> 64
Las expresiones lambda pueden ser utilizadas como una función, y se pueden invocar inmediatamente:
((x,y)-> x + y)(3,4)
.. e imprime 7
También se pueden usar en conjunción con un asignamiento, separados por un punto y coma (;)
v = (x,y) -> x + y; v(3,4)
v es la función lambda creada, y después se invoca con v(3,4)
` `
` `
Operaciones con colecciones
EL permite operaciones de colecciones de objetos: conjuntos (set), listas y mapas. Permite la creación dinámica de colecciones de objetos, los cuales pueden ser manipulados por streams *y *pipelines.
Al igual que las expresiones lambda, las operaciones sobre colecciones de objetos son parte de Java SE 8, pero podemos usar estas expresiones EL en Java EE 7 sobre Java SE 7.
Veamos: así creamos un par de conjuntos (set):
{1,2,3}
{"Ana","Beto","Carlos"}
Para construir una lista, es como sigue… además podemos hacer que una lista contenga diferentes tipos:
["Abraham","Bart","Carl"]
[1,"dos",[tres,cuatro]]
Las variables tres y cuatro deben existir
void run() {
eval("nums={1,2,3}");
eval("noms={'Ana','Beto','Carlos'}");
eval("noms2=['Abraham','Bart','Carl']");
eval("tres=3;cuatro='4'");
eval("lista=['Abraham','Bart','Carl']");
eval("lista2=[1,'dos',[tres,cuatro]]");
}
Ok, ok, he mostrado el EL en un Java SE, pero la idea es mostrar en un JSF. Aquí va el ejemplo. Primer código:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>Ejemplos de EL</title>
</h:head>
<h:body>
<h1>Ejemplos de EL</h1>
${lista= [512,128,65] }
</h:body>
</html>
Y cuando se ejecuta, aparece…
Todo bien, todo normal. Ahora con la ayuda de nuestro super IDE NetBeans, a la variable que acabamos de crear vamos a ordenarlo. Vean qué pasa cuando escribimos el nombre de la variable lista seguido del punto (.)
Automáticamente, el IDE sabe que ese objeto es una lista y nos mostrará las propiedades de esa lista…. y de sus objetos
Por tanto, ejecutamos el código:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>Ejemplos de EL</title>
</h:head>
<h:body>
<h1>Ejemplos de EL</h1>
${lista= [512,128,65].stream().sorted().toList() }
</h:body>
</html>
Y el resultado es lo esperado:
Operadores
Son los clásicos que conocemos
-
Aritméticos:
+, -, *, /, div, %, mod, -(signo negativo) -
Concatenación de cadenas:
+= -
Lógicos:
and, &&, or, ||, not, ! -
Relacional:
==, eq, !=, ne, <, lt, >, gt, <=, ge, >=, le -
Si es vacío: El operador
emptydetermina si una lista está vacía o un objeto es nulo -
Condicional:
A ? B : C(Lo mismo que en Java SE) -
Lambda:
->(ya lo conocemos) -
Asignación:
= -
Punto y coma:
;
En esta página podremos encontrar varios ejemplos de expresiones EL http://docs.oracle.com/javaee/7/tutorial/doc/jsf-el007.htm
Bibliografía
Me basé en el siguiente tutorial 9 Expression Language, y para más detalle sobre esta especificación, visitar la página del JSR 341 http://www.jcp.org/en/jsr/detail?id=341
Si te gustó, hazlo saber.. y si crees que es útil, compártelo. Es gratis






