lunes, 6 de abril de 2015

Ejemplo: Java EE JSF+JPA - XII


10.- Pruebas, retoques y apuntes finales

Este es el aspecto que debe tener nuestro proyecto, una vez concluido:




Al arrancar la aplicación, es posible que, se produzcan algunos fallos de configuración.

El primer problema puede provenir de JPA. Es posible que hayáis tenido algún problema en el fichero persistence.xml. El filtrado de la solución debería realizarse así: primero descartar que el fallo provenga de la base de datos. Comprobar que está conectado el mysql server; que es accesible desde netBeans o el IDE que uséis; que el fichero contiene la base de datos y la tabla creada. Luego habría que comprobar que persistence.xml tiene los datos correctamente asignados, en especial el nombre de la base de datos, el login y el password de vuestra base de datos.

Superado ese trance, la mayor parte de los errores provienen del servidor. Es relativamente posible (fue mi caso concreto) que algunos ficheros que estamos suministrando al proyecto ya estén duplicados por otra vía. En mi caso fue la librería jsf la que entraba en conflicto con otra librería que tenía Tomcat: conflicto en javax.faces. Solución, quitar la librería que estaba instalada en Tomcat. Los conflictos con las librerías que tienen instaladas "de serie" o "manuales" los servidores suelen ser una de las principales vías de problemas en las instalaciones de JavaEE y en especial en JSF. Se llaman igual, pero no funcionan igual.

Pero si todo ha ido bien, las pruebas serán satisfactorias. Primeramente deberéis dar de alta un usuario, pulsando en "Nuevo" en la pantalla index.xhtml, y nos redirigirá hacia la pantalla de altas.








El resultado debe ser más o menos como en la imagen.

Luego, pulsando en "Volver" llegaremos de nuevo a la pantalla de identificación, donde si suministramos el login y password correspondiente entraremos en la pantalla de datos personales. Pulsamos en "Profesionales" y nos redirige hacia la pantalla de datos profesionales.

¡ Hagamos una modificación !







¡Todo funciona correctamente ! Pulsando en "Salir" deberíamos salir de la aplicación y nos reenviará a la pantalla de inicio.

También debemos probar que borra correctamente pulsando en "Borrar". En las pruebas realizadas, en dos configuraciones distintas, todo funcionó perfectamente.

APUNTES FINALES

Hemos visto que es relativamente fácil construir una aplicación JavaEE con JSF+JPA. Siempre y cuando tengamos claro el modelo MVC, la construcción y mantenimiento de estas aplicaciones estará al alcance de nuestros conocimientos. ¡Claro que no hablo de los megaproyectos de las grandes corporaciones!

Hay que contemplar siempre las "best practices". Recordad siempre que los atributos deben ser private y se acceden mediante getters/setters. Tener siempre presente la modularidad y la escalabilidad de los proyectos. Nunca se sabe cuando estas 4 páginas pueden acabar siendo 40 o 400. La aplicación del modelo de construcción MVC nos permite modificar-ampliar-reconstruir con mayor facilidad y en menor tiempo las aplicaciones. También es conveniente comentar bien los métodos... que no significa comentar todo, sino comentar lo que no es inmediatamente obvio. Lo que hoy parece claro quizás no lo sea tanto al pasar algunos meses y/o proyectos.

Espero que este tutorial ejemplo os haya servido de ayuda y/o aprendizaje.

Anterior tema                                                                                

miércoles, 1 de abril de 2015

Ejemplo: Java EE JSF+JPA - XI


9.- Integración entre vista y negocio: expresion languaje

La navegación entre la capa vista (páginas jsf) y la capa de negocio (ManagedBean) puede realizarse de varias formas: mediante el fichero faces-config.xml, mediante método forward-redirect, o mediante navegación implicita basada en EL (expresion languaje).

El Expresion Languaje es además una potente herramienta de comunicación de información entre la capa de vista y los managedBeans. Por ello, su uso es imprescindible en JSF.

La expresión tipo de EL es:
  • #{nombreManagedBean.atributoAmostrar} cuando queremos acceder a datos
  • #{nombreManagedBean.metodoAejecutar()} cuando queremos acceder a métodos
También existe la posibilidad de ${} en lugar de #{}. Es preferible el segundo método sobre el primero, ya que ${} se utiliza para expresiones directas sin evaluación previa, y como JSF es de ciclo multifásico suele ser preferible #{} porque la evaluación de la expresión incluida entre llaves se realiza después de completar el ciclo. Además, en muchos casos funciona igual #{} que ${}. Resumiendo, es preferible usar #{} en JSF.

Dicho todo esto, la tarea que tenemos delante es la siguiente: debemos rellenar todos los campos "value" de los formularios con la EL que relacione ese campo con el atributo correspondiente en el ManagedBean. Y por otro lado, debemos relacionar con EL los botones del formulario con los métodos que invocan en el ManagedBean.

En el caso concreto del index.xhtml:
  • <h:inputText value="#{identificacion.login}"></h:inputText>
  • <h:inputSecret value="#{identificacion.password}"></h:inputSecret>        
  • <h:commandButton  value="Login" action="#{identificacion.identifica()}"></h:commandButton>
  • <h:commandButton  value="Nuevo" action="#{identificacion.nuevo()}" ></h:commandButton>
  • <h:outputText value="#{identificacion.message}"></h:outputText>
Vemos como hemos relacionado el inputText con el atributo login del IndexBean. También hemos relacionado el inputSecret con el atributo password. Y el outputText lo hemos relacionado con el atributo message. Cuando se construya el formulario, y una vez terminadas las distintas fases del ciclo de vida de la aplicación javaEE, el formulario obtendrá los valores de los atributos login, password y message a través de los getters, y los mostrará en los correspondientes elementos de formulario.

El commandButton Login se ha relacionado con el método identifica, el cual después de procesar la identificación le devolverá un String que será incluido en la etiqueta <h:form> y será transformada en <form action="String devuelto por identifica">, y acto seguido la navegación será reenviada a la dirección de ese String. Identico comportamiento tendrá el commandButton Nuevo respecto al método nuevo del IndexBean.

El nombre "identificación" corresponde a la etiqueta name incluida dentro de la declaración @ManagedBean(name="identificación"). No es obligatorio declarar un name, pero si no se hace, entonces la EL correspondiente sería #{indexBean.loQueSea}. Personalmente considero preferible suministrarle un name al ManagedBean, por razones de flexibilidad y de mantenimiento, pero es una preferencia personal.

Por lo tanto, el formulario del fichero index.xhtml quedará reconstruido de la siguiente forma:

        <h:form>
            <h1>Identificación de usuario</h1>
            <h:panelGrid columns="2">
                <h:outputLabel>Usuario</h:outputLabel><h:inputText value="#{identificacion.login}"></h:inputText>
                <h:outputLabel>Contraseña</h:outputLabel><h:inputSecret value="#{identificacion.password}"></h:inputSecret>        
            </h:panelGrid>
            <div class="buttonForm">
                <h:commandButton  value="Login" action="#{identificacion.identifica()}"></h:commandButton>
                <h:commandButton  value="Nuevo" action="#{identificacion.nuevo()}" ></h:commandButton>
            </div>
            <div class="message">
                <h:outputText value="#{identificacion.message}"></h:outputText>
            </div>            
        </h:form>

Y con ello tendremos ya relacionadas ambas capas en lo que se refiere a estos ficheros, pero aún quedan otros tres jsf que modificar.

Modificación en alta.xhtml

        <h:form>
            <h1>Creación de nuevo usuario</h1>
            <h:panelGrid columns="2">
                <h:outputLabel>Nombre</h:outputLabel><h:inputText value="#{usuario.nombre}"></h:inputText>
                <h:outputLabel>Usuario</h:outputLabel><h:inputText value="#{usuario.login}"></h:inputText>       
                <h:outputLabel>Contraseña</h:outputLabel><h:inputText value="#{usuario.password}"></h:inputText> 
                <h:outputLabel>Email</h:outputLabel><h:inputText value="#{usuario.email}"></h:inputText>
                <h:outputLabel>Sector</h:outputLabel>
                <h:selectOneMenu value="#{usuario.selectedSector}">
                        <f:selectItem itemLabel="Industria" itemValue="1"></f:selectItem>
                        <f:selectItem itemLabel="Comercio" itemValue="2"></f:selectItem>
                        <f:selectItem itemLabel="Agricultura" itemValue="3"></f:selectItem>
                        <f:selectItem itemLabel="Servicios" itemValue="4"></f:selectItem>
                        <f:selectItem itemLabel="Otros" itemValue="5"></f:selectItem>
                    </h:selectOneMenu> 
                <h:outputLabel>Profesión</h:outputLabel><h:inputText value="#{usuario.profesion}"></h:inputText>
                <h:outputLabel>Antiguedad</h:outputLabel><h:inputText value="#{usuario.antiguedad}"></h:inputText></h:panelGrid>
            <div class="buttonForm">
                <h:commandButton value="Grabar" action="#{usuario.nuevoUsuario()}" ></h:commandButton>
                <h:commandButton value="Volver" action="#{usuario.volver()}"></h:commandButton>
            </div>
            <div class="message">
                <h:outputText value="#{usuario.message}"></h:outputText>
            </div>
        </h:form>

Modificación en personales.xhtml

            <h:form>
                <h:commandButton class="buttonExit" value="Salir" action="#{personales.goOut()}" ></h:commandButton>
                <h1>Datos personales</h1>
                <h:panelGrid columns="2">
                    <h:outputLabel>Nombre</h:outputLabel><h:inputText value="#{personales.nombre}"></h:inputText>
                    <h:outputLabel>Usuario</h:outputLabel><h:inputText value="#{personales.login}"></h:inputText>       
                    <h:outputLabel>Contraseña</h:outputLabel><h:inputText value="#{personales.password}"></h:inputText> 
                    <h:outputLabel>Email</h:outputLabel><h:inputText value="#{personales.email}"></h:inputText>          
                </h:panelGrid>
                <div class="buttonForm">
                    <h:commandButton value="Modificación" action="#{personales.modificarUsuario()}" ></h:commandButton>
                    <h:commandButton value="Borrar" action="#{personales.borrarUsuario()}" ></h:commandButton>
                    <h:commandButton value="Profesionales" action="#{personales.goToProfesionales()}" ></h:commandButton>
                </div>
                <div class="message">
                    <h:outputText value="#{personales.message}"></h:outputText>
                </div>                
            </h:form>

Modificación en profesionales.xhtml

        <h:form>
            <h:commandButton class="buttonExit" value="Salir" action="#{profesionales.goOut()}" ></h:commandButton>
            <h1>Datos profesionales</h1>            
            <h:panelGrid columns="2">
                <h:outputLabel>Sector</h:outputLabel>
                <h:selectOneMenu value="#{profesionales.selectedSector}">
                    <f:selectItem itemLabel="Industria" itemValue="1"></f:selectItem>
                    <f:selectItem itemLabel="Comercio" itemValue="2"></f:selectItem>
                    <f:selectItem itemLabel="Agricultura" itemValue="3"></f:selectItem>
                    <f:selectItem itemLabel="Servicios" itemValue="4"></f:selectItem>
                    <f:selectItem itemLabel="Otros" itemValue="5"></f:selectItem>
                </h:selectOneMenu>               
                <h:outputLabel>Profesión</h:outputLabel><h:inputText value="#{profesionales.profesion}"></h:inputText>
                <h:outputLabel>Antiguedad</h:outputLabel><h:inputText value="#{profesionales.antiguedad}"></h:inputText>            
            </h:panelGrid>
            <div class="buttonForm">
                <h:commandButton value="Modificación" action="#{profesionales.modificarUsuario()}"></h:commandButton>
                <h:commandButton value="Borrar" action="#{profesionales.borrarUsuario()}" ></h:commandButton>
                <h:commandButton value="Personales" action="#{profesionales.goToPersonales()}" ></h:commandButton>
            </div>
            <div class="message">
                <h:outputText value="#{profesionales.message}"></h:outputText>
            </div>             
        </h:form>


RESUMEN:
Hemos enlazado nuestras páginas jsf de la capa vista, con los ManagedBeans de la capa de negocio mediante Expresion Languaje. Por lo tanto, nuestrás páginas ya están preparadas para funcionar. Solamente nos quedará realizar las pruebas de funcionamiento.


Anterior tema                                                                                         Siguiente tema