Utilizando JSTL en JSF

1
50415

UTILIZANDO JSTL EN APLICACIONES JSF

Introducción

Java Server Pages Standard Tag library (JSTL) es un
conjunto de librerías de etiquetas simples y estándares que encapsulan
funcionalidad habitualmente utilizada en aplicaciones Web. Soportan funciones
como iteraciones, procesamiento condicional, procesamiento XML,
internacionalización, etc. Su uso está extendido debido sobre todo a que se
integran en las páginas JSP de forma sencilla y limpia, además de proporcionar
la mayoría de funcionalidades necesarias en un JSP.

 

Por otra parte Java Server Faces (JSF) es un marco de
trabajo basado en el patrón MVC (Modelo-Vista-Controlador) cuya
característica novedosa con respecto a Struts, por ejemplo, es que la parte de Vista
se crea a partir de un conjunto de componentes reutilizables disponibles del
lado del servidor.

 

En este tutorial veremos algunos beneficios y también
problemas al intentar utilizar estas dos tecnologías combinadamente.

 

Herramientas
utilizadas

  • Sistema
    operativo: Windows XP Professional.
  • Servidor
    Web: Apache TomCat 5.5.9
  • Entorno
    de desarrollo: Eclipse 3.1.1 con ExadelStudio-3[1].0.5

Preparamos el entorno

Vamos a seguir los siguientes pasos:

 

1.     
Creamos
un nuevo proyecto JSF en Eclipse.

 

Para ello selecciono File>New>Proyect>JSF
Project

 

Los ficheros generados son los siguientes:

2.     
Incorporamos
al proyecto todo lo necesario para trabajar con JSTL

 

Debemos conseguir las librerías y taglibs de JSTL; todo esto
lo podemos conseguir en: 

http://jakarta.apache.org/taglibs/doc/standard-doc/intro.html

 

A día de hoy, la versión más actual se encuentra en el
fichero jakarta-taglibs-standard-20060227.zip; lo descomprimimos y
copiamos los ficheros jstl.jar y standard.jar al directorio lib
de nuestra aplicación. La librería jstl.jar ya la había incorporado
Exadel por defecto al crear el proyecto, pero por evitar problemas de
versiones, he machacado la que ya había.

 

Después, actualizamos el classpath del proyecto con las
nuevas librerías

 

 

 

Además de las librerías, es necesario incorporar a  nuestro proyecto los taglib que serán
invocados en nuestras páginas JSF. El único que voy a utilizar para este
ejemplo es c.tld, así que lo copio al directorio WEB-INF de la
aplicación.

 

3.      Creamos
la página index.jsp

 

Esta página redireccionará a la página gestionUsuarios.jsf
que crearemos más adelante:

<%@ taglib
uri=»http://myfaces.apache.org/extensions» prefix=»t»
%>

<!doctype
html public «-//w3c//dtd html 4.0 transitional//en»>

<html>

<head>AUTENTIA-
TUTORIAL JSTL-JSF</head>

            <body>

                        <jsp:forward
page=»gestionUsuarios.jsf» />

            </body>

</html>

 

4.      Generando
el bean y las clases de apoyo

 

Creamos el bean UsuarioBean
cuya responsabilidad, por ahora, será la de proporcionar un listado estático de
usuarios. Para ello, sobre el paquete JavaSource seleccionamos New>Class y
creamos la clase:

 

Creamos las variables de instancia que necesitamos, y
preparamos un método que devuelve un listado de usuarios:

 

package com.autentia.pruebaJstl;

import java.util.ArrayList;

import java.util.List;

/**

 * Bean encargado de la
gestión de usuarios

 * @author AUTENTIA

 */

public class UsuarioBean implements
Serializable

{

            /** Login
del usuario */

            private String
login;

            /** Password del
usuario */

            private String
password;

            /** Nombre completo
del usuario */

            private String
nombre;

            /** Lista de
usuarios */

            private static
List listaUsuarios;

            ////////////////////////
CONSTRUCTORES

            public
UsuarioBean()

            {

                        listaUsuarios
= new ArrayList();

            }

            ////////////////////////
FIN DE CONSTRUCTORES

            ////////////////////////
METODOS DE ACCESO A VARIABLES PRIVADAS

            public String
getLogin() {

                        return login;

            }

            public void setLogin(String login) {

                        this.login = login;

            }

            public String getNombre() {

                        return nombre;

            }

            public void setNombre(String nombre) {

                        this.nombre = nombre;

            }

            public String getPassword() {

                        return password;

            }

            public void setPassword(String password) {

                        this.password = password;

            }          

            public List
getListaUsuarios()

            {

                        if(listaUsuarios.size()==0)

                                   listaUsuarios=creaListaInicialUsuarios();

                        return
listaUsuarios;

            }

            ////////////////////////FIN
DE METODOS DE ACCESO A VARIABLES PRIVADAS

            /**

             * Crea una lista estática de usuarios.

             */

            private static List creaListaInicialUsuarios()

            {

                        List lResultados = new ArrayList();

                        lResultados.add(new
Usuario(«autentia1″,»pautentia1″,»Javier Pérez
Gómez»));

                        lResultados.add(new
Usuario(«autentia2″,»pautentia2″,»Juan Cuesta
García»));

                        lResultados.add(new
Usuario(«autentia3″,»pautentia3″,»Pepe González
Cam»));

                        return
lResultados;

            }

}

 

Nos apoyamos en una clase que representa la entidad usuario:

 

package com.autentia.pruebaJstl;

/**

 * Clase que representa un usuario

 * @author AUTENTIA

 */

public class Usuario implements Serializable

{

            /** Login del usuario */

            private String login;

            /** Password del usuario */

            private String password;

            /**
Nombre del
usuario */

            private
String nombre;

            /**
Constructor */

            public
Usuario(String login,String password,String nombre)

            {

                        this.login=login;

                        this.nombre=nombre;

                        this.password=password;

            }

            public
String getLogin() {

                        return
login;

            }

            public
void setLogin(String login) {

                        this.login
= login;

            }

            public
String getNombre() {

                        return
nombre;

            }

            public
void setNombre(String nombre) {

                        this.nombre
= nombre;

            }

            public
String getPassword() {

                        return
password;

            }

            public
void setPassword(String password) {

                        this.password = password;

            }

           

}

 

5.      Registramos
el bean en el fichero descriptor de JSF

en nuestro caso,
el ficheros descriptor se llama examples-config.xml:

 

<faces-config>

  <managed-bean>

             
<description>

             
           
Bean para la gestión de usuarios

              </description>

             
<managed-bean-name>usuariosBean</managed-bean-name>

             
<managed-bean-class>com.autentia.pruebaJstl.UsuarioBean</managed-bean-class>

             
<managed-bean-scope>session</managed-bean-scope>

  </managed-bean>

</faces-config>

 

6.      Creamos
los ficheros de recursos

Así los mensajes que aparezcan en nuestra aplicación se adaptan al
idioma del usuario que esté accediendo a la misma; en este tutotial sólo los
voy a generar en español e inglés; estos ficheros estarán en el paquete
com.autentia.pruebaJstl:

 

recursos_es

recursos_en

###### FICHEROS DE RECURSOS

usuarios_bienvenido=Bienvenido!!!

gestionUsuarios_generacion_jsf=Listado generado con JSF

gestionUsuarios_generacion_jstl=Listado generado con JSTL

gestionUsuarios_nombre=Nombre

gestionUsuarios_login=Login

###### BOUNDLES FILE

usuarios_bienvenido=Welcome!!!

 

Primera prueba. Mostrando la lista de usuarios con el
componente dataTable de JSF y con JSTL

 

Creamos la página  gestionUsuarios.jsp y mostramos la lista de usuarios con JSF como
se muestra a continuación:

 

<%@ taglib
uri=»http://java.sun.com/jsf/html» prefix=»h» %>

<%@ taglib
uri=»http://java.sun.com/jsf/core» prefix=»f» %>

<%@ taglib
uri=»http://myfaces.apache.org/extensions» prefix=»t»
%>

<html>

<head>

<title>AUTENTIA
– TUTORIAL JSTL-JSF</title>

<style>

.tabla
{font-family : verdana;

        font-size: 12px;

        padding: 0;

        cellpading:0;

        cellspacing:0;                                              

        color: #000000;width: 80%;}

.cabecera_tabla
{font-family: Verdana;

                 font-size: 11px;

                 color: #000000;

                 background-color: #AFBDB6;                                       

                 font-weight:bold;padding:
0;cellpading:0;cellspacing:0;

                 text-align: left;border: 1
px;}

.fila
{background-color: #FFFFE0;} 

.columna_left
{text-align: left;width:50%}

.texto
{font-family : verdana;

        font-weight:bold; font-size:
12px;color: #000000;}

</style>

</head>

<body>

  <f:loadBundle
basename=»com.autentia.pruebaJstl.recursos»
var=»mensajes»/>

  <h:form
id=»gestionUsuarios»>

  <f:view>

  <center>

  <h:outputText

      
value=»#{mensajes[‘gestionUsuarios_generacion_jsf’]}»

       styleClass=»texto» />

 
<f:verbatim><br><br></f:verbatim>

  <t:dataTable id=»data»
styleClass=»tabla»

                           headerClass=»cabecera_tabla»

                           footerClass=»cabecera_tabla»
rowClasses=»fila»                                               
columnClasses=»columna_left,columna_left»
var=»usuario»

                          
value=»#{usuarioBean.listaUsuarios}»                                                                preserveDataModel=»true»
rows=»10″>

            <h:column>

        <f:facet
name=»header»>        

                <h:outputText
value=»#{mensajes[‘gestionUsuarios_nombre’]}» />

        </f:facet>          

             
<t:commandLink action=»#{usuarioBean.preparaParaEditar}»

                      immediate=»true»>

                 <h:outputText
value=»#{usuario.nombre}» />  
                      

             
</t:commandLink>                

            </h:column>                 

            <h:column>                

             
<f:facet name=»header»>                                                                               

          <h:outputText
value=»#{mensajes[‘gestionUsuarios_login’]}» />

             
</f:facet>                                                      

             
<h:outputText value=»#{usuario.login}» />                                             </h:column>            

  </t:dataTable>

  </center>                                                                  

  </f:view>

  </h:form>

</body>           

</html>

 

Con:

   <f:loadBundle basename=»com.autentia.pruebaJstl.recursos»
var=»mensajes»/>

 

cargamos el fichero de recursos y con  t:dataTable
visualizamos la lista de usuarios que proporciona el método getListaUsuarios
del bean usuariosBean.

 

Probamos en el Tomcat lo que llevamos hecho
y perfecto…

 


 

Ahora intentamos hacer lo mismo
pero utilizando JSTL; para ello importamos el taglib correspondiente:

 

<%@ taglib
uri=»http://java.sun.com/jsf/html» prefix=»h» %>

<%@ taglib
uri=»http://java.sun.com/jsf/core» prefix=»f» %>

<%@ taglib
uri=»http://myfaces.apache.org/extensions» prefix=»t»
%>

<%@ taglib
uri=»http://java.sun.com/jsp/jstl/core» prefix=»c» %>

…..

 

Y creamos el listado:

 

….

<br><br>

<center>

<h:outputText

   
value=»#{mensajes[‘gestionUsuarios_generacion_jstl’]}»
styleClass=»texto» />

<table class=»tabla»>

 <tr>

 <td
class=»cabecera_tabla»>

  <h:outputText
value=»#{mensajes[‘gestionUsuarios_nombre’]}» />

 </td>

 <td
class=»cabecera_tabla»>

        
<h:outputText
value=»#{mensajes[‘gestionUsuarios_login’]}» />

 </td>

 </tr>

 <c:forEach
items=»${sessionScope.usuarioBean.listaUsuarios}»
var=»usuario1″>           

   <tr class=»fila»>           

    <td
class=»columna_left»>                    

            <t:commandLink
action=»#{usuarioBean.preparaParaEditar}»
immediate=»false»>

             <c:out
value=»${usuario1.nombre}»/>                          

            </t:commandLink>                               

    </td>                                 

    <td
class=»columna_left»><c:out
value=»${usuario1.login}»/></td>                             

   </tr>

  </c:forEach>                                  

</table>                                       

</center>                        

</f:view>                                 

</h:form>

</body>

</html>

 

Como vemos, accedo al bean a través
de la sesión:

  
<c:forEach
items=»${sessionScope.usuarioBean.listaUsuarios}»
var=»usuario1″>

 

Cuando despliego en Tomcat me
encuentro el primer problema: parece que los commandLink no funcionan
con JSTL:


Esto es debido a que el <c:forEach>
es avaluado por el contenedor de JSP cada vez que se procesa la página; el
contenedor deja disponible en la página (Page scope) la variable
usuario1, pero el concepto de Page scope es específico de JSP, y no
existe en los entornos que maneja JSF. Este problema está documentado en la
especificación de JSF (sección
9.2.8).

 

Parece entonces que los taglibs de
JSTL sí pueden acceder a los beans JSF que dejamos en sesión, en el request o a
nivel de aplicación, pero no al contrario.

 

Segunda prueba. Creando/Editando un
usuario

La página de creación y edición de los datos de un usuario será la
misma, aunque en función del tipo de acción, habrá que hacer las siguientes
consideraciones:

      
Si
estamos creando un nuevo usuario, no tiene sentido que aparezca el botón de
eliminar al usuario

      
Si
estamos editando los datos del usuario, el campo login no puede modificarse.

 

Estas excepciones las voy a manejar con JSTL en este ejemplo, aunque con
JSF sería mucho más adecuado utilizar el atributo rendered que tienen todos los componentes precisamente para esto,
que se muestren o no.

 

Antes, en la página gestionUsuarios.jsp añado un enlace para
crear un nuevo usuario:

 

….

….

<f:view>

  <table class=»tabla»>

    <tr>

      <td align=»right»>

             <t:commandLink action=»#{usuarioBean.nuevoUsuario}»
immediate=»true»>

                   <h:outputText
value=»#{mensajes[‘nuevo_usuario’]}» />

              </t:commandLink>

      </td>

     <tr>

   </table>

….

….

 

Y completo el bean usuarioBean para que cuando pinchemos en Nuevo
usuario
o sobre uno de los usuarios existentes, nos lleve a la página de
edición:

 

            

           

            /**
Indicador de si se puede mostrar el botón de borrar */

            private String mostrarBotonBorrar;

            /**
Indicador de si el campo de login es editable */

            private String loginEditable;    

           

           ….

            /**

             * Muestra el formulario de creación de un
usuario

             */

            public String nuevoUsuario()

            {

                        // Limpiamos los
campos del formulario

                        clear();

                        return «edicion_usuario»;

            }          

 

            /**

             * Limpia los campos del bean

             */

            private
void clear()

            {

                        this.login=»»;

                        this.nombre=»»;

                        this.password=»»;

                         this.mostrarBotonBorrar=»false»;

                        this.loginEditable=»true»;

            }

           

            /**

             * Recupera como parámetro el login del
usuario que se desea editar, rellena los atributos

             * del bean y redirige a la página de
edición de usuarios

             * @return la página de edición de usuarios

             */

            public
String preparaParaEditar()

            {

                        String
donde = null;

                        FacesContext
context = FacesContext.getCurrentInstance();

                        Map
map = context.getExternalContext().getRequestParameterMap();

                        // Recuperamos el login del usuario que deseamos
editar

                        String idUsuario
= (String) map.get(«idUsuario»);

                        Usuario usuario = obtenerUsuario(idUsuario);

                        if(usuario!=null)

                        {

                                   fill(usuario);

                                   this.mostrarBotonBorrar=»true»;

                                   this.loginEditable=»false»;                             

                                   donde =
«edicion_usuario»;

                        }

                        return donde;

            }

         

 

            /**

             * Itera sobre la lista de usuarios y
devuelve el que tenga el login pasado como

             * parámetro.

             */

            private Usuario
obtenerUsuario(String login)

            {

                        Usuario us = null;                     

                        List lista =
getListaUsuarios();

                        for(int
i=0;i<lista.size();i++)

                        {

                                   Usuario
obj = (Usuario)lista.get(i);

                                   if(obj.getLogin().equalsIgnoreCase(login))

                                   {

                                               us
= obj;

                                               break;

                                   }

                        }                      

                        return
us;

            }

            /**

             * Rellena el bean a partir de los datos de
un usuario

             * @param usuario

             */

            private void fill(Usuario
usuario)

            {

                        this.login=usuario.getLogin();

                        this.nombre=usuario.getNombre();

            }

 

Ahora añado la navegabilidad en el fichero examples-config.xml:

 

<navigation-rule>

             
<from-view-id>/gestionUsuarios.jsp</from-view-id>

             
<navigation-case>

              
<from-outcome>edicion_usuario</from-outcome>

              
<to-view-id>/edicionUsuario.jsp</to-view-id>

              
<redirect/>

             
</navigation-case>

 </navigation-rule>

 

Creamos la página de edición de un usuario, que llamaremos edicionUsuario.jsp

 

 

<%@ taglib
uri=»http://java.sun.com/jsf/html» prefix=»h» %>

<%@ taglib
uri=»http://java.sun.com/jsf/core» prefix=»f» %>

<%@ taglib
uri=»http://myfaces.apache.org/extensions» prefix=»t»
%>

<%@ taglib
uri=»http://java.sun.com/jsp/jstl/core» prefix=»c» %>

<html>

    <head>

      <title>AUTENTIA – TUTORIAL
JSTL-JSF</title>

      <link rel=»stylesheet»
type=»text/css» href=»css/estilos.css»>

    </head>

    <body>

        <f:loadBundle
basename=»com.autentia.pruebaJstl.recursos»
var=»mensajes»/>

    <f:view>

    <h:form id=»usuarioBean»
name=»usuarioBean»>

       
<h:panelGrid columns=»2″
styleClass=»gestionUsuariosFormTable»

                        
headerClass=»gestionUsuariosFormHeader»

                        
footerClass=»gestionUsuariosFormFooter»

                        
columnClasses=»gestionUsuariosFormLabels,
gestionUsuariosFormInputs» width=»600″>

        <!– Login –>

         <h:outputLabel
for=»login» value=»Login»/>

         <c:if test=»${sessionScope.usuarioBean.loginEditable==’true’}»>

            <h:inputText
id=»login» styleClass=»CajasTexto» size=»30″
maxlength=»50″

                               
value=»#{usuarioBean.login}» required=»true»>

                         <f:validateLength
maximum=»100″ minimum=»1″/>

             </h:inputText>

         </c:if>

         <c:if test=»${sessionScope.usuarioBean.loginEditable==’false’}»>

                     <h:outputText
value=»#{usuarioBean.login}»/>

         </c:if>   

          

        <!– Nombre
–>

        
<h:outputLabel for=»nombre»
value=»Nombre»/>

              <h:inputText
id=»nombre» styleClass=»CajasTexto» size=»30″
maxlength=»50″

                        
value=»#{usuarioBean.nombre}» required=»true»>

             <f:validateLength
maximum=»100″ minimum=»1″/>

         </h:inputText>                

         <h:panelGroup>

            <h:commandButton
action=»#{usuarioBean.save}»
value=»#{mensajes[‘bot_salvar’]}» />

            <f:verbatim>&nbsp;</f:verbatim>           

            <c:if test=»${sessionScope.usuarioBean.mostrarBotonBorrar==’true’}»>

                <h:commandButton
action=»#{usuarioBean.delete}» immediate=»true»
value=»Borrar» />

            </c:if>                     

          </h:panelGroup>

                        </h:panelGrid>                        

            </h:form>

            </f:view>              

</body>

</html>

 

Este ejemplo parece que sí funciona. Si seleccionamos el botón Nuevo Usuario el sistema permitirá al
usuario introducir un nuevo login y no aparece el botón Borrar:

 

 

Y si seleccionamos un usuario del listado, aparecerán los datos
editados, no se podrá modificar el login y sí aparecerá el botón de borrar, qué bien:

 

1 Comentario

  1. Hola, quisiera hacer una consulta, estoy usando jsf 2, quisiera mostrar un datatable solo cuando una lista tiene registros, intento lo siguiente: 0}\\\»> pero me sale el sgte. error : test=\\\»${clienteController.listCliente.size == 0}\\\» For input string: \\\»size\\\». Cual sería la forma correcta de hacerlo? Gracias

Dejar respuesta

Please enter your comment!
Please enter your name here