viernes, 19 de junio de 2020

Java Server Faces Expression Language (JSF EL)

Los Facelets no soportan las secuencias de comandos de Java Server Pages. Por ello, se requiere de una forma de indirectamente invocar al código Java. Así JSP y Facelets son dos tecnologías diferentes.

JSF permite la utilización de ambas incluso conjuntamente. A ello se debe acotar que Facelets es más reciente y específica para JSF ofreciendo más posibilidades al desarrollador. Se recomenda el uso de los Facelets en JSF.

El lenguaje de expresión de JSF fue inspirado en la tecnología JSTL mediante el uso de prefijos en sus bibliotecas estándar. Este se encuentra entre las capas de modelo y vista mediante la aplicación de las propiedades Setter y Getter.

Formatos

Emplear minúsculas al hacer referencia a un Bean. 
Tipo de bean EL
Atributo de un Bean Simple
#{nombre.atributo}
Ejemplo: Supongamos un Bean llamado "Mascota" que tiene un atributo llamado "peso", para llamarlo usaríamos
#{mascota.peso}
Método de un Bean Simple con retorno
#{nombre.metodo()}
Ejemplo: Supongamos un Bean llamado "Mascota" que tiene un método llamado "ladrido" que devuelve un valor String, para llamarlo usaríamos
#{mascota.ladrido()}
Atributo o método de un atributo tipo objeto de un Bean Simple
#{nombre.atrib1.atrib2}
Ejemplo: Supongamos un Bean llamado "Mascota" que tiene un atributo que es del tipo "Propietario" llamado "propietario" que devuelve un objeto y este objeto en su declaración tiene "id" y "nombre", para llamar al nombre del propietario usaríamos
#{mascota.propietario.nombre}


Aplicación

Nota: Para este caso se usa la versión JSF 2.3 y Java EE 8 con un servidor Payara

Supongamos que tenemos el siguiente "bean" llamado "AutorBeans"
package proyectoJSF.model;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class AutorBean {

 private Integer idAutor = 1;
 private String nombre = "Jhon";

 public AutorBean() {
 }
 
 public Integer getIdAutor() {
  return idAutor;
 }

 public void setIdAutor(Integer idAutor) {
  this.idAutor = idAutor;
 }

 public String getNombre() {
  return nombre;
 }

 public void setNombre(String nombre) {
  this.nombre = nombre;
 }

}


A partir de la versión 2.0 de JSF se puede emplear las EL desde cualquier parte del Facelet, ya no es necesario hacerlo dentro de sus etiquetas JSF. Para invocar a sus métodos Getter y Setter desde un Facelet debemos colocar lo siguiente:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
 xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
 <title>Prueba 03</title>
</h:head>
<h:body>
  <h1>Autor - Método GET</h1>
  <ul>
    <li>Id del autor: #{autorBean.idAutor}</li>
    <li>Nombre: #{autorBean.nombre}</li>
  </ul>
  <hr/>
  <h1>Autor - Método SET</h1>
  <h:form>
    <h:outputLabel value="Ingrese ID: "/>
    <h:inputText value="#{autorBean.idAutor}"/>
    <br/><br/>
    <h:outputLabel value="Ingrese nombre: "/>
    <h:inputText value="#{autorBean.nombre}"/>
    <br/><br/>
    <h:commandButton type="submit" value="Cambiar"/> 
  </h:form>
</h:body>
</html>


Se observa los siguiente, en este caso se modifico las cajas de texto con "10001" y "Jhon Paul" que originalmente tenían los mismos valores "1" y "Jhon":

La expresión #{autorBean.idAutor} invoca automáticamente al método GET del atributo "idAutor" y lo mismo en el caso de "nombre". Si se hace clic en el botón "Cambiar" se obtendrá el siguiente resultado:

En este caso la expresión #{autorBean.idAutor} dentro de los "h:inputText" invoca automáticamente al método SET del atributo "idAutor" y lo mismo en el caso de "nombre", que luego se ve reflejado en la primera sección del Facelet. Esto permite mucha simplicidad para el manejo de los atributos.



Manejando estructuras de datos con EL

Podemos visualizar Array y colecciones. Supongamos la siguiente clase "LibroBean" que emplea la anterior
package proyectoJSF.model;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class LibroBean {

 private Integer id = 105;
 private String nombre = "JSF EL";
 private AutorBean autor = new AutorBean();
 private String[] idiomas = { "Español", "Inglés", "italiano" };
 private List<String> paises;
 private Map<String, LocalDate> ediciones;

 public LibroBean() {
  cargarPaises();
  cargarEdiciones();
 }

 public String[] getIdiomas() {
  return idiomas;
 }

 public List<String> getPaises() {
  return paises;
 }

 public Map<String, LocalDate> getEdiciones() {
  return ediciones;
 }

 private void cargarPaises() {
  paises = new ArrayList<>();
  paises.add("Perú");
  paises.add("Canadá");
  paises.add("Japón");
 }

 private void cargarEdiciones() {
  ediciones = new TreeMap<>();
  ediciones.put("Primera", LocalDate.of(2012, 12, 30));
  ediciones.put("Segunda", LocalDate.of(2015, 2, 12));
  ediciones.put("Tercera", LocalDate.of(2020, 6, 7));
 }

 public Integer getId() {
  return id;
 }

 public void setId(Integer id) {
  this.id = id;
 }

 public String getNombre() {
  return nombre;
 }

 public void setNombre(String nombre) {
  this.nombre = nombre;
 }

 public AutorBean getAutor() {
  return autor;
 }

 public void setAutor(AutorBean autor) {
  this.autor = autor;
 }

}

Si deseamos mostrar el Array "idiomas", usaremos el siguiente código:
<h1>Libro - Idiomas disponibles</h1>
<ul>
 <li>#{libroBean.idiomas[0]}</li>
 <li>#{libroBean.idiomas[1]}</li>
 <li>#{libroBean.idiomas[2]}</li>
</ul>

Si deseamos mostrar la colección List "paises", usaremos el siguiente código:

<h1>Libro - Países de venta disponibles</h1>
<ul>
 <li>#{libroBean.paises[0]}</li>
 <li>#{libroBean.paises[1]}</li>
 <li>#{libroBean.paises[2]}</li>
</ul>

Si deseamos mostrar la colección Map "ediciones", usaremos el siguiente código:

<h1>Libro - Ediciones y fechas</h1>
<ul>
 <li>#{libroBean.ediciones["Primera"]}</li>
 <li>#{libroBean.ediciones["Segunda"]}</li>
 <li>#{libroBean.ediciones["Tercera"]}</li>
</ul>


Obteniendo el siguiente resultado:


Operaciones con EL

Podemos emplear operaciones de comparación, aritméticas, lógicas y el operador "empty".

Operaciones aritméticas
Expresión Resultado
Suma (+) #{2+2} 4
Resta (-) #{2-12} -10
Producto (*) #{7*5} 35
División ("div" o "/") #{4/5} 0.8
Residuo ("mod" o "%") #{12 mod 5} 2
Operación combinada #{(5 % 3)*2-1} 3

Operaciones de comparación
Expresión Resultado
Igual ("==" o "eq") #{"hola" eq "hola"} true
Diferente ("!=" o "ne") #{20 ne 20} false
Mayor ("gt") #{30 gt 20} true
Menor ("lt") #{10 lt 20} true
Mayor o igual ("ge") #{11 ge 22} false
Menor o igual ("le") #{12 le 12} true

Nota evitar el uso de los símbolos < y > para las comparaciones por las reglas de XML

Operaciones lógicas
Expresión Resultado
Disyunción ("or") #{(1 ne 1) or (5 ne 6)} true
Conjunción ("and") #{(1 ne 1) and (5 ne 6)} false
Negación ("!") #{!(1 eq 2)} true

El operador "empty" verifica si un contenido es vacío o nulo y retornará verdadero o falso según sea el caso. Se puede ejemplificar mediante
  • #{empty ""}
  • #{empty null}
Ambos ejemplos devolverán "true", si tenemos un valor capturado que es nulo entonces la siguiente expresión también devolverá "true"
  • #{empty clase.atributo}


Condicionales en EL

Para hacer uso de estos se emplea el operador ternario con la sintaxis:
  • #{ condición ? valorTrue : valorFalse}

Ejemplo:

<p class=" #{clase.atributo eq 5 ? 'class5' : 'class10'} ">
 
Del ejemplo se comprueba si el atributo recuperado es 5, de ser el caso la clase será "class5", sino será "class10". Tener mucha atención en el uso de comillas simples y dobles.

Otra manera de emplear los condicionales es el atributo "rendered", si este tiene como valor una condición verdadera, el elemento que posee este atributo se hará visible, de lo contrario tendrá visibilidad oculta.

Ejemplo:
<!--  Elemento invisible, porque 11 no es igual a 10 -->
<h:outputText value="Primer saludo" rendered="#{11 eq 10}"/>
<br/>
<!--  Elemento visible porque 10 es igual a 10 -->
<h:outputText value="Segundo saludo" rendered="#{10 eq 10}"/>


Resultado visual:
  • Segundo saludo




No hay comentarios:

Publicar un comentario