Skip to main content

Libro JEE7 Capítulo 2. Crear aplicación Web

Capítulo 2. Crear  aplicación Web
Modelo General
Desarrollo de una aplicacion Web
Dependencias Maven
Usando el Asistente Maven del IDE
Editar el archivo pom.xml
MODELO DESARROLLO
JPA
Proceder a Crear los Entity con NetBeans
Creación de los EJB
CDI vs ManagedBeans
CREAR UN CDI PARA EL MANEJO DE MENSAJES
Código completo del CDI JSFUtil.java
FACELETS
CREAR PLANTILLA FACELETS CON <p:layout> de PRIMEFACES
Código completo de template.xhtml
Editar template.xhtml
Crear la página Index.xhtml
CREAR CDI BEANS ESTATUSCONTROLLER.java
Crear los Facelets Template Client para insertar Estatus
Editar el entity Estatus.java
Editar EstatusFacade.java
Convertidores

Crear EstatusConverter.java

















Modelo General





Desarrollo de una aplicacion Web

Este capítulo  muestra el desarrollo de la aplicación de ejemplo de Scrum usando tecnologías JEE 7. Esta aplicación  permitirá insertar registros en una tabla utilizando JPA, primefaces / JavaServer Faces, EJB, CDI.


Para ello utilizamos:
  • NetBeans IDE 8.0.1
  • Maven (como parte del IDE)
  • GlassFish 4.1
  • Base de datos MySQL

1. Crear un proyecto Maven → Web Application desde NetBeans:




2. Indicar Project Name: scrumweb
Group id: com.avbravo (Es el grupo de proyectos al que pertenece nuestro proyecto)

En Settings, seleccionamos GlassFish Server 4.1. y en Java EE Version 7
add.png


El IDE genera la estructura del proyecto:


Ahora, vamos a seleccionar Projects → Properties → Configurations → Configurations: <default config> y presionar el botón Activate.




Hacemos clic en la categoría Frameworks


Hacer clic  el botón Add, y luego seleccionar JavaServer Faces

En la pestaña Configuration verificar que esté seleccionado la opción Facelets en la opción Preferred Language:


y en la pestaña Components seleccionamos Primefaces


Dependencias Maven

Maven consta de repositorios donde se encuentran las dependencias (bibliotecas .jar) necesarias para ejecutar nuestros proyectos. La ventaja que ofrece es que no es necesario descargar  manualmente estas dependencias. Simplemente Maven se encarga de buscarlas y en los repositorios y nos permite agregarlas facilmente. Si una biblioteca depende de otra, Maven se encargará agregar estas dependencias a nuestro proyecto.


Para nuestra aplicación web utilizaremos las siguientes dependencias:
  • primefaces all-themes
  • mysql
  • primefaces  
  • itext
  • jasperreports
  • jfreechart


NetBeans nos ofrece dos alternativas para realizarlo: la primera mediante el asistente y la segunda editando el archivo pom.xml  que encontramos en Project Files.


Usando el Asistente Maven del IDE



Usaremos la alternativa del asistente del IDE. Para ello, en el nodo  “Dependencies” hacer clic derecho y seleccionar Add Dependency...


En el diálogo Add Dependency  escribiremos en el campo Query la dependencia a buscar y presionamos la tecla Intro. En ese momento se mostrará un listado con las dependencias locales y remotas y seleccionamos la que deseamos de la lista.
  • Para primefaces all-themes (Permite manejar los temas de primefaces)


  • Dependencia mysql-connector-java (Para manejar la comunicación con mysql)


  • Actualizamos la versión de primefaces a 5.1 (Última versión de primefaces community al momento de escribir este libro)
51.png



  • Dependencia itext (Utilizado para reportes)


  • Dependencia jasperreports (Utilizado para reportes)






  • Dependencia jfreechart (Generación de gráficas)


Editar el archivo pom.xml

La segunda alternativa es editar el archivo pom.xml ubicado en Project Files


Podemos escribir directamente la dependencia, o dar clic derecho Insert Code→ Dependency.
Mostrará el diálogo para buscar dependencias.


En el archivo pom.xml ingresamos directamente la dependencia indicando el groupId(generalmente es la organización o empresa que desarrolla), artifactId (nombre del jar), versión (número de versión )


<dependencies>
       <dependency>
           <groupId>org.primefaces</groupId>
           <artifactId>primefaces</artifactId>
           <version>5.1</version>
       </dependency>
       <dependency>
           <groupId>commons-fileupload</groupId>
           <artifactId>commons-fileupload</artifactId>
           <version>1.3</version>
       </dependency>
       <dependency>
           <groupId>org.primefaces.extensions</groupId>
           <artifactId>all-themes</artifactId>
           <version>1.0.8</version>
       </dependency>
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>5.1.26</version>
       </dependency>
       <dependency>
           <groupId>com.lowagie</groupId>
           <artifactId>itext</artifactId>
           <version>2.1.7</version>
       </dependency>
       <dependency>
           <groupId>net.sf.jasperreports</groupId>
           <artifactId>jasperreports</artifactId>
           <version>5.2.0</version>
       </dependency>
       <dependency>
           <groupId>jfree</groupId>
           <artifactId>jfreechart</artifactId>
           <version>1.0.13</version>
       </dependency>
       <dependency>
           <groupId>javax</groupId>
           <artifactId>javaee-web-api</artifactId>
           <version>7.0</version>
           <scope>provided</scope>
       </dependency>
   </dependencies>


y en repositories agregar
<repositories>
       <repository>
           <url>http://repository.primefaces.org/</url>
           <id>PrimeFaces-maven-lib</id>
           <layout>default</layout>
           <name>Repository for library PrimeFaces-maven-lib</name>
       </repository>

Al terminar de agregar las dependencias, hacer clic derecho sobre el ícono del proyecto, y seleccionamos “Build with  Dependencies” para descargar las dependencias del proyecto Maven.




Se observa un listado de dependencias
d.png













MODELO DESARROLLO

  • Java Server Faces ofrece un mecanismo sencillo para el desarrollo de interfaces de usuario web, el modelo será dividido en tres capas (Capa Web, Capa Negocio, Capa de Datos),








Para poder manejar la base de datos MySQL desde NetBeans  IDE, se agrega la base de datos desde la pestaña Services→ Databases→ Drivers→ MySQL




Indicar el nombre de la base de datos el usuario y password, y presionar el botón Test Connection, para comprobar que la conexión a la base de datos sea exitosa.




NetBeans IDE nos ofrece un potente editor de consultas y operaciones sobre la base de datos.




Nota: Desde este panel podemos conectarnos a cualquier base de datos, de cualquier tipo, siempre y cuando contemos con el controlador JDBC.


JPA

EL ORM(Object Relational Mapping), predeterminado en JEE7 es JPA, que ofrece un mecanismo sencillo de manejo de registros de las tablas y su equivalente en clases en Java. Generalmente POJOs(Plain Old Java  Object), que se denominan Entity, ya que a diferencia de un objeto Java tradicional, el Entity permite que el valor de sus atributos sea almacenado permanentemente en la base de datos.


Los Entity ofrecen una serie de atributos y anotaciones que facilitan el manejo de los mismos, aprovechando las ventajas de la plataforma Java EE7.


Proceder a Crear los Entity con NetBeans

  • Desde menú File, seleccione New
  • en Categories, seleccione Persistence
  • en File Types, seleccione Entity Classes from DataBase



Luego, si no existe el jdbc/scrumweb procedemos a crear el Data Source para nuestra aplicación, para ello seleccionaremos New Data Source...
Seguidamente, indicamos el  nombre JNDI que vamos a utilizar. En nuestro caso, usaremos: jdbc/scrumweb


De ahora en adelante, cada vez que queramos referirnos a la base de datos, lo haremos usando JNDI. Seleccionamos Data Source el nombre JNDI que deseamos crear jdbc/scrumweb


Continuamos con el asistente, y cuando nos pregunte que tablas vamos a importar(Available Tables):


Y como queremos importar todas las tablas, hacemos clic en Add All


Notaremos que algunos nombres de  tablas se presentarán en color gris; estas son las que dependen de otras tablas, porque tienen una clave foránea, y es necesaria importarla para que la tabla principal pueda funcionar.


Continuamos con el asistente. En el diálogo Entity Classes, muestra las columnas con el nombre de la tabla, clases y tipo de generación.


En el diálogo Mapping Options, dejamos los valores predeterminados en el campo “Collection Type” con el valor java.util.Collection y presionamos el botón “Finalizar”



Se iniciara la generación de los Entity, en base al análisis de las tablas.


En la imagen podrá apreciar los Entity generados, cada uno  corresponde a una tabla de la base de datos




Nos ubicamos en Other Sources /src/main/resources y dar clic derecho sobre persistence.xml, seleccionar Open.




se muestra la configuración del archivo persistence.xml, y comprobar que Data Source: muestra jdbc/scrumweb
si damos clic en la pestaña Source, podemos observar la configuración.


<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
 <persistence-unit name="com.avbravo_scrumweb_war_1.0-SNAPSHOTPU" transaction-type="JTA">
   <jta-data-source>jdbc/scrumweb</jta-data-source>
   <exclude-unlisted-classes>false</exclude-unlisted-classes>
   <properties/>
 </persistence-unit>
</persistence>

Creación de los EJB

Los “Enterprise Java Beans” son clases especiales en Java que se ejecutan en el Contenedor Java EE. En estos componentes se establece la lógica de negocio para nuestras aplicaciones. Esto nos permite separar limpiamente la lógica de negocio, de la vista y de la capa de datos.


NetBeans nos permite crear estos EJB con el modelo CRUD (Create-Read-Update-Delete) para nuestras Entities de una manera muy rápida de la siguiente manera.


  • Desde menú File, seleccione New
  • en Categories, seleccione Enterprise JavaBeans
  • en File Types, seleccione Session Beans For Entity Classes



Seleccionar de la lista “Available Entity Classes” y presionar el botón Add All>> para generar todos los EJB para nuestras entidades.





En el dialogo Generated Session Beans, indicar el campo  “Packagecom.avbravo.scrumweb.ejb  (Para almacenar en ese paquete los ejb que se generen) y presionar el botón “Finalizar”


Se crean en el paquete com.avbravo.scrumweb.ejb los EJB AbstractFacade.java y un EJB para cada Entity seleccionado.





CDI vs ManagedBeans

JEE7 utiliza por defecto CDI en lugar de ManagedBeans, ya que estos estan más integrados con la plataforma y permiten la inyección de dependencias.


Para utilizarla debemos importar el paquete javax.enterprise.context y deben implementar la interfaz Serializable para los SessionScoped.


por ejemplo


import javax.annotation.ManagedBean;
import javax.enterprise.context.SessionScoped;


los paquetes que corresponden  a ManagedBeans ya no se usarán


import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

CDI define los alcances
  • @Application Scoped: Se mantiene durante toda la ejecución de la aplicacion.
  • @SessionScoped:       Se mantiene durante la sesion de un unico usuario.
  • @RequestScoped:      Corresponde a una unica solicitud HTTP o la invocación de un  
                                           método. El beans solo persiste mientras el método es
                                           invocado.
  • @ConversationScoped: Se mantiene entre multiples invocaciones.
  • @Dependent:             Es el mismo ciclo que el de un cliente. Un bean dependiente
 es creado cada vez que se inyecta y la referencia es removida cuando la inyección es removida.


Utilizamos la anotación  @Named para hacer referencia desde las páginas xhtml , se utiliza la siguiente estandarización: si el CDI se llama JSFUtil y se utiliza @Named este se usará en las páginas xhtml como jSFUtil, con la primera letra en minúsculas.









CREAR UN CDI PARA EL MANEJO DE MENSAJES

1. Crear el CDI JSFUtil
  • Desde menú File, seleccione New
  • en Categories, seleccione Java Server Faces
  • en File Types, seleccione JSF ManagedBeans
  • Class Name: JSFUtil
  • Package com.avbravo.scrumweb.generales
  • Scope: request



Se permite seleccionar el Scope (Alcance) en este ejemplo utilizamos request, indicar el paquete generales donde se almacenará.
Código generado por el IDE

Se procede a  eliminar la anotación  @ManagedBean y será reemplazada por @Named, la importación javax.faces.bean.ManagedBean y javax.faces.bean.RequestScoped se deben eliminar. Ya que estas en depreciadas para usar en su lugar CDI.


Dar Clic derecho-> Fix import y seleccionar javax.inject.Named y javax.enterprise.context.RequestScoped

























Se mostrará el código de la siguiente manera:


package com.avbravo.scrumweb.generales;


import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;


/**
*
* @author avbravo
*/
@Named
@RequestScoped
public class JSFUtil  {

   /**
    * Creates a new instance of JSFUtil
    */
   public JSFUtil() {
   }


}



En el código usaremos métodos para enviar mensajes a los componentes  <p:growl> y <h:messages>, y tambien se usara para desplegar diálogos utilizando Dialog Framework.


Por ejemplo el método addSuccessMessage() actualiza el <p:growl> y <h:messages> de la pagina xhtml.






Mientras el método infoDialog() muestran un diálogo con los mensajes utilizando Dialog Framework de Primefaces implementado en la versión 4.0, y no actualiza <p:growl> ni <h:messages> de la pagina xhtml.

Código completo del CDI JSFUtil.java



import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UISelectItem;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.model.SelectItem;
import javax.inject.Named;
import javax.servlet.http.HttpSession;
import org.primefaces.context.RequestContext;


/**
*
* @author avbravo
*/
@Named
@RequestScoped
public class JSFUtil {


  
   public static SelectItem[] getSelectItems(List<?> entities, boolean selectOne) {
       int size = selectOne ? entities.size() + 1 : entities.size();
       SelectItem[] items = new SelectItem[size];
       int i = 0;
       if (selectOne) {
           items[0] = new SelectItem("", "­­­");
           i++;
       }
       for (Object x : entities) {
           items[i++] = new SelectItem(x, x.toString());
       }
       return items;
   }
   /*
    * logout
    */


   public String logout() {
       HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
       if (session != null) {
           session.invalidate();
       }
       return "/index";
   }


   public static void addErrorMessage(Exception ex, String defaultMsg) {
       String msg = ex.getLocalizedMessage();
       if (msg != null && msg.length() > 0) {
           addErrorMessage(msg);
       } else {
           addErrorMessage(defaultMsg);
       }
   }


   public static void addErrorMessages(List<String> messages) {
       for (String message : messages) {
           addErrorMessage(message);
       }
   }


   public static void addErrorMessage(String msg) {
       FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR,
               msg, msg);
       FacesContext.getCurrentInstance().addMessage(null, facesMsg);
   }


    public static void testMessage(String msg) {
       FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR,
               msg, msg);
       FacesContext.getCurrentInstance().addMessage(null, facesMsg);
   }
   public static void addSuccessMessage(String msg) {
       FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg,
               msg);
       FacesContext.getCurrentInstance().addMessage("successInfo", facesMsg);
   }


   public static void addWarningMessage(String msg) {
       FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, msg, ""));
   }


   public static void addFatalMessage(String msg) {
       FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, msg, ""));
   }


   public static String getRequestParameter(String key) {
       return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(key);
   }


   public static Object getObjectFromRequestParameter(String requestParameterName,
           Converter converter, UIComponent component) {
       String theId = JSFUtil.getRequestParameter(requestParameterName);
       return converter.getAsObject(FacesContext.getCurrentInstance(), component, theId);
   }


   public static void infoDialog(String titulo, String texto) {
       FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, titulo,
               texto);
       RequestContext.getCurrentInstance().showMessageInDialog(message);
   }


   public static void warningDialog(String titulo, String texto) {
       FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN, titulo,
               texto);
       RequestContext.getCurrentInstance().showMessageInDialog(message);
   }


   public static void fatalDialog(String titulo, String texto) {
       FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_FATAL, titulo,
               texto);
       RequestContext.getCurrentInstance().showMessageInDialog(message);
   }


   public static void errorDialog(String titulo, String texto) {
       FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
               titulo, texto);
       RequestContext.getCurrentInstance().showMessageInDialog(message);
   }


   public static java.sql.Date converterDate(java.util.Date fecha) {
       try {
           long lfecha = fecha.getTime();
           java.sql.Date dtfecha = new java.sql.Date(lfecha);
           return dtfecha;
       } catch (Exception e) {
           addErrorMessage("converterDate() " + e.getLocalizedMessage());
       }
       return null;
   }


   public static java.util.Date getFechaActual() {
       java.util.Calendar ca = java.util.Calendar.getInstance();
       java.sql.Date mydate = new java.sql.Date(ca.getTimeInMillis());
       return new java.sql.Date(mydate.getTime());


   }


   public static Integer getAnioActual() {
       java.util.Calendar ca = java.util.Calendar.getInstance();
       java.sql.Date mydate = new java.sql.Date(ca.getTimeInMillis());
       return ca.get(Calendar.YEAR);
   }


   public static Integer getMesActual() {
       java.util.Calendar ca = java.util.Calendar.getInstance();
       java.sql.Date mydate = new java.sql.Date(ca.getTimeInMillis());
       return ca.get(Calendar.MONTH);
   }


   public static Integer getMesDeUnaFecha(Date date) {
       Calendar calendar = Calendar.getInstance();
       calendar.setTime(date);


       int anio = calendar.get(Calendar.YEAR);
       int mes = calendar.get(Calendar.MONTH) + 1;
       int dia = calendar.get(Calendar.DAY_OF_MONTH);
       return mes;
   }
public static Integer getAnioDeUnaFecha(Date date) {
       Calendar calendar = Calendar.getInstance();
       calendar.setTime(date);


       int anio = calendar.get(Calendar.YEAR);
       int mes = calendar.get(Calendar.MONTH) + 1;
       int dia = calendar.get(Calendar.DAY_OF_MONTH);
       return anio;
   }
 public static Integer getDiaDeUnaFecha(Date date) {
       Calendar calendar = Calendar.getInstance();
       calendar.setTime(date);


       int anio = calendar.get(Calendar.YEAR);
       int mes = calendar.get(Calendar.MONTH) + 1;
       int dia = calendar.get(Calendar.DAY_OF_MONTH);
       return dia;
   }
   public static Integer getDiaActual() {
       java.util.Calendar ca = java.util.Calendar.getInstance();
       java.sql.Date mydate = new java.sql.Date(ca.getTimeInMillis());
       return ca.get(Calendar.DATE);
   }


   public static boolean isValidationFailed() {
       return FacesContext.getCurrentInstance().isValidationFailed();
   }


   public static boolean isDummySelectItem(UIComponent component, String value) {
       for (UIComponent children : component.getChildren()) {
           if (children instanceof UISelectItem) {
               UISelectItem item = (UISelectItem) children;
               if (item.getItemValue() == null && item.getItemLabel().equals(value)) {
                   return true;
               }
               break;
           }
       }
       return false;
   }


   public static String getComponentMessages(String clientComponent, String defaultMessage) {
       FacesContext fc = FacesContext.getCurrentInstance();
       UIComponent component = UIComponent.getCurrentComponent(fc).findComponent(clientComponent);
       if (component instanceof UIInput) {
           UIInput inputComponent = (UIInput) component;
           if (inputComponent.isValid()) {
               return defaultMessage;
           } else {
               Iterator<FacesMessage> iter = fc.getMessages(inputComponent.getClientId());
               if (iter.hasNext()) {
                   return iter.next().getDetail();
               }
           }
       }
       return "";
   }


   public static Throwable getRootCause(Throwable cause) {
       if (cause != null) {
           Throwable source = cause.getCause();
           if (source != null) {
               return getRootCause(source);
           } else {
               return cause;
           }
       }
       return null;
   }
   }












FACELETS

Facelets nos permite manejar un sistema de plantillas y componentes de manera facil.


CREAR PLANTILLA FACELETS CON <p:layout> de PRIMEFACES

Primefaces nos ofrece el componente <p:layout>  que nos permite una disposición adecuada de los componentes. A continuación se mostrará una forma sencilla de integrar facelets con <p:layout> para crear una plantilla dinámica  para nuestra aplicación web.


  • Desde menú File, seleccione New
  • en Categories, seleccione Java Server Faces
  • en File Types, seleccione Facelets Template




colocar  el nombre File Name: template



El IDE genera el archivo templates.xhtml y en la carpeta resources los css


Eliminamos el código que genera y agregamos el código para implementar el layout de primefaces.
Integramos facelets con el componente <p:layout> de primefaces. Teniendo presente que <p:layout> utiliza    <p:layoutUnit position="north”> para definir las areas y facelets necesitamos  definir el área mediante <ui:insert name="top"> .
Tabla comparativa
Primefaces
Facelets
north
top
south
bottom
west
left
east
Right
center
center


Indicamos que será pagina completa.
 <p:layout fullPage="true">
usamos <p:layoutUnit de primefaces y dentro de el <ui:insert>
<p:layoutUnit position="north" size="100" resizable="true" closable="true" collapsible="true">
        <ui:insert name="top">
         Header
        </ui:insert>
</p:layoutUnit>







Si deseamos incluir menú en la parte superior y que estos se muestran en sobre otras áreas y no solo sobre la parte superior incluir el css donde se modifica .ui-layout-north y .ui-layout-unit-content


<style type="text/css">
               .ui-layout-north {
                   z-index:20 !important;
                   overflow:visible !important;;
               }
               .ui-layout-north .ui-layout-unit-content {
                   overflow:visible !important;
               }
           </style>





Cambiar
Por
<title>Facelets Template</title>
<title><h:outputText value="Scrum web"/></title>





Agregar dentro del <h:head> el <f:facet name=”first”>, lo usamos para reordenar el contenido en Primefaces. Indicando lo primero que debe cargarse.
<f:facet name="first">
           <meta content='text/html; charset=UTF­8'  http-equiv="Content­Type"/>
           <title><h:outputText value="Scrum web"/></title>
       </f:facet>





Código completo de template.xhtml



<?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:ui="http://java.sun.com/jsf/facelets"
     xmlns:h="http://java.sun.com/jsf/html"
     xmlns:p="http://primefaces.org/ui"
     xmlns:f="http://xmlns.jcp.org/jsf/core">
   <f:view contentType="text/html">

    <h:head>
       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
       <h:outputStylesheet name="./css/default.css"/>
       <h:outputStylesheet name="./css/cssLayout.css"/>
       <f:facet name="first">
           <meta content='text/html; charset=UTF­8'  http-equiv="Content­Type"/>
           <title><h:outputText value="Scrum web"/></title>
       </f:facet>


       <style type="text/css">
               .ui-layout-north {
                   z-index:20 !important;
                   overflow:visible !important;;
               }
               .ui-layout-north .ui-layout-unit-content {
                   overflow:visible !important;
               }
           </style>


   </h:head>

   <h:body>
       <p:layout fullPage="true">
           <p:layoutUnit position="north" size="100" resizable="true" closable="true" collapsible="true">
               <ui:insert name="top">
         Header
               </ui:insert>
           </p:layoutUnit>
          <p:layoutUnit position="south" size="50" closable="true" collapsible="true">
               <ui:insert name="bottom">
                   Footer
               </ui:insert>
           </p:layoutUnit>
    <p:layoutUnit position="west" size="175" header="Left" collapsible="true">
               <ui:insert name="left">
                   Left
               </ui:insert>
           </p:layoutUnit>
           
           <p:layoutUnit position="center">
               <ui:insert name="center"></ui:insert>
           </p:layoutUnit>
       </p:layout>
   </h:body>
       </f:view>
</html>





















Eliminar los archivos index.html e index.xhtml


Crear menu.xhtml
Crear una página Java Server Faces que contendrá las opciones del Menú separadas del template que luego la incluiremos dentro.
  • Desde menú File, seleccione New
  • en Categories, seleccione Java Server Faces
  • en File Types, seleccione JSF Page

Se utiliza el componente <p:megamenu> de primefaces debe estar incluido dentro de un <h:form>.
Utilizaremos menuitem  para indicar las opciones a desplegar en el menu.
 <p:menuitem value="Insertar"  url="/faces/page/estatus/estatusinsert.xhtml" />
la ruta /faces/pages/estatus/ indica que se debe crear la carpeta /page/estatus dentro de Web Pages.






Código completo de menu.xhtml
<?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"
     xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
     xmlns:p="http://primefaces.org/ui">


   <h:body>
       <ui:composition>
           <h:form id="menuForm" >
             <p:megaMenu>  
              <p:submenu label="Registros" icon="ui-icon-check">  
               <p:column>  
                   <p:submenu label="Estatus">  
                      <p:menuitem value="Insertar"  url="/faces/page/estatus/estatusinsert.xhtml" />  
                      <p:menuitem value="Listar"   url="/faces/page/estatus/estatuslist.xhtml"/>  
                   </p:submenu>  
               </p:column>  
             </p:submenu>  
          
           </p:megaMenu>  
         </h:form>
       </ui:composition>


   </h:body>
</html>














Editar template.xhtml

en el top, colocamos el <ui:include src=”menu.xhtml”/>, mediante el include incluimos en la parte superior de la plantilla el menú que tenemos en menu.xhtml
 <p:layout fullPage="true">
           <p:layoutUnit position="north" size="100" resizable="true" closable="true"
                         collapsible="true">
               <ui:insert name="top">
                   <ui:include src="menu.xhtml"/>
               </ui:insert>
           </p:layoutUnit>

Crear la página Index.xhtml

Ahora creamos un Facelets Template Client
  • Desde menú File, seleccione New
  • en Categories, seleccione Java Server Faces
  • en File Types seleccione Facelets Template Client



en File Name : index
Presionar el botón Browse de Template:


seleccionamos el  Template  template.xhtml


Se genera el código de la página y  colocamos en comentario top,bottom, left. Utilizando
 <!-- --> ,de esta manera el área top, bottom,left serán reemplazadas por la definición en el template, y nosotros editamos el área center, donde  escribimos los componentes java server faces que deseamos mostrar. En este caso escribimos BIENVENIDOS A SCRUMWEB

Ejecutamos el proyecto  


se carga en el browser, podemos observar el layout con el menú y el mensaje de la página index.xhtml que es la primera en cargarse al ejecutar el proyecto.


CREAR CDI BEANS ESTATUSCONTROLLER.java

Estos CDI los utilizamos invocar las diversas operaciones sobre los Entity y asociar los componentes con las páginas Java Server Faces.


  • Desde menú File, seleccione New
  • en Categories, seleccionamos Java Server Faces
  • en File Types, seleccionamos JSF ManagedBeans
  • Class Name: EstatusController
  • Package: com.avbravo.scrumweb.controller
  • Scope: request

Agregamos las anotaciones @Named, @RequestScoped.
Nota:  Recordar utilizar javax.enterprise.context.RequestScoped.


Agregamos el EJB inyectandolo mediante @Inject
@Inject
EstatusFacade estatusFacade;


Agregamos el Entity
Estatus estatus = new Estatus();


creamos los get/set del entity estatus clic derecho Insert Code-->Generated set/get y seleccionamos estatus

Implementamos el método save() donde haremos persistentes los entity en la base de datos,  en este método buscaremos por la llave primaria mediante estatusFacade.find(), y si no existe invocamos estatusFacade.create(), para guardarlo.
Si deseamos limpiar la vista escribimos estatus = new Estatus(), de manera que al actualizarse la página xhtml, esta mostrará los atributos limpios.
JSFUtil.infoDialog(), mostrará el mensaje en un diálogo. Si queremos que se muestre en el growl usamos JSFUtil.addSuccessMessage().
Crear métodos edit() y delete(),  crear atributo encontrado con los métodos get/set. Recordar cambiar
public Boolean isEncontrado() {
       return encontrado;
   }


por
public Boolean getEncontrado() {
       return encontrado;
   }


































Código completo de CDI Beans EstatusController.java


import com.avbravo.scrumweb.Estatus;
import com.avbravo.scrumweb.ejb.EstatusFacade;
import com.avbravo.scrumweb.generales.JSFUtil;
import com.avbravo.scrumweb.generales.ResourcesFiles;
import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;


/**
*
* @author avbravo
*/
@Named
@RequestScoped
public class EstatusController  {
   @Inject
   EstatusFacade estatusFacade;
   Estatus estatus = new Estatus();
   private Boolean encontrado = false;
   private List<Estatus> items;


   public Estatus getEstatus() {
       return estatus;
   }


   public void setEstatus(Estatus estatus) {
       this.estatus = estatus;
   }


   public Boolean getEncontrado() {
       return encontrado;
   }


   public void setEncontrado(Boolean encontrado) {
       this.encontrado = encontrado;
   }


   /**
    * Creates a new instance of EstatusController
    */
   public EstatusController() {
   }


   public String save() {
       try {
           if (estatusFacade.find(estatus.getIdestatus()) != null) {
               JSFUtil.infoDialog("Mensaje", "Existe un registro con ese id");
               return null;
           }
           estatusFacade.create(estatus);
           JSFUtil.addSuccessMessage("Guardado");
           estatus = new Estatus();
       } catch (Exception e) {
           JSFUtil.addErrorMessage(e.getLocalizedMessage());
       }
       return null;
   }


   public String edit() {
       try {
           estatusFacade.edit(estatus);
           JSFUtil.addSuccessMessage("Guardado");
       } catch (Exception e) {
           JSFUtil.addErrorMessage(e.getLocalizedMessage());
       }
       return null;
   }


   public String delete() {
       try {
           estatusFacade.remove(estatus);
           JSFUtil.addSuccessMessage("Eliminado");
           encontrado = false;
           estatus = new Estatus();


       } catch (Exception e) {
           JSFUtil.addErrorMessage(e.getLocalizedMessage());
       }
       return null;
   }
//Devuelve eln list para un selectOneMenu
public List<Estatus> getItems() {
       if (items == null) {
           items = estatusFacade.findAll();
       }
       return items;
   }

}




Crear los Facelets Template Client para insertar Estatus

Ahora creamos un Facelets Template Client
  • Desde menú File, seleccione New
  • en Categories, seleccione Java Server Faces
  • en File Types, seleccione Facelets Template Client
  • En File Name: estatusinsert
  • Folder colocamos /page/estatus/
  • Template seleccionamos template.xhtml

Se crea el Facelets client  estatusinsert.xhtml en la carpeta page/estatus



De la misma manera que hicimos con la página index, colocamos en comentario top, button,left, mediante <!-- →.
      
Nos ubicamos en la palabra  center. En esta parte vamos a reemplazarlo con un formulario generado por el IDE..


           <ui:define name="center">
               center
           </ui:define>

Una vez seleccionado, hacemos clic sobre el texto y seleccionamos  Insert Code




Luego, hacemos clic en JSF Form From Entity




Seleccionar el Entity: com.avbravo.scrumweb.Estatus
y el Managed Bean Property: estatusController.estatus






Genera el código con los componentes JSF asociado a los atributos del entity
Indicamos el id del panel esto se utiliza para identificar el componente por el id respectivo
<h:panelGrid id="panel" columns="2">


Colocamos la etiqueta <p:growl id="growl" /> y <p:messages autoUpdate=”true”  para que nos muestre los mensajes del aplicativo.


Ahora vemos que la etiqueta   <p:growl id="growl" /> muestra un error . Esto se debe a que  no está agregado el taglib de primefaces. Para agregarlo, seleccionamos el icono  de la sugerencia y seleccionamos que agregue la biblioteca respectiva


Agregamos el componente para mensajes que se mantendrán en la página.
 <p:messages autoUpdate="true"/>


Creamos la  sección footer en el panelGrid y agregar el boton Guardar, para invocar el método save() del CDI y en  la propiedad update utilizamos  panel y growl, de manera que el guardar un registro se actualice el panel y se muestre los mensajes en el growl. Si no lo colocamos en el update los mensajes no se mostraran, ya que el <p:commandButton> por defecto tiene Ajax habilitado en true.


<f:facet name="footer">
  <p:commandButton value="Guardar" update="panel,growl" action="#{estatusController.save()}"/>
</f:facet>






Vista final de la página estatusinsert.xhtml, con los componentes y el botón Guardar.

Guardamos el archivo, y volvemos a ejecutar la aplicación para mostrar los cambios


Ingresamos los datos y al dar clic en el boton Guardar se almacenan en la base de datos los atributos que estan en el Entity y se envía el mensaje en el growl y en messages.



si ingresamos un idestatus que ya existe nos enviará el mensaje.


Si no usaramos la validación para determinar si existe un registro con esa llave primaria obtendremos el mensaje Transaction aborted, y no sería muy explicativo para el usuario
Si deseamos usar icono en el botón, agregamos el atributo icon="ui-icon-disk" a <p:commandButton>.


En el siguiente enlace podemos encontrar la lista de iconos jquery disponibles para los componentes primefaces, que usaremos mediante icon="nombre del icono”
colocamos el cursor sobre el icono y se despliega el mensaje con el nombre.


Editar el entity Estatus.java

Agregar el @NamedQuery findByEstatusLike que nos permitirá realizar búsquedas por coincidencias en el atributo estatus.
   @NamedQuery(name = "Estatus.findByEstatusLike", query = "SELECT e FROM Estatus e WHERE lower(e.estatus) like :estatus"),



Segmento del código Entidad.java donde se agrega el @NamedQuery


@Entity
@Table(name = "estatus")
@XmlRootElement
@NamedQueries({
   @NamedQuery(name = "Estatus.findAll", query = "SELECT e FROM Estatus e"),
   @NamedQuery(name = "Estatus.findByIdestatus", query = "SELECT e FROM Estatus e WHERE e.idestatus = :idestatus"),
   @NamedQuery(name = "Estatus.findByEstatus", query = "SELECT e FROM Estatus e WHERE e.estatus = :estatus"),
   @NamedQuery(name = "Estatus.findByEstatusLike", query = "SELECT e FROM Estatus e WHERE lower(e.estatus) like :estatus"),
   @NamedQuery(name = "Estatus.findByEsinicial", query = "SELECT e FROM Estatus e WHERE e.esinicial = :esinicial")})
public class Estatus implements Serializable {
   private static final long serialVersionUID = 1L;

Editar EstatusFacade.java

Agregar el método  findById , que nos devolverá un objeto de tipo Estatus.
El método find, el cual buscará el entity por la llave primaria.
El método findByEsinicial() que recibe un parámetro correspondiente al valor del atributo esinicial(si/no).


El Entity Estatus findByEsinicial es el  @NamedQuery(name = "Estatus.findByEsinicial", usaremos un Query que implementa la búsqueda y devolverá un list.
El método  getEstatusList() para que devuelva todos los entity , al invocar Estatus.findAll. y elmétodoo  findByEsinicial().
agregar los métodos findByEstatus(), findByIdEstatusList() y  findByEstatusLike()


Editar EstatusFacade.java


public Estatus findById(String id) {
       return em.find(Estatus.class, id);
}


public List<Estatus> getEstatusList() {
       return em.createNamedQuery("Estatus.findAll").getResultList();
   }


public List<Estatus>  findByEsinicial(String value){
           Query query = em.createNamedQuery("Estatus.findByEsinicial");
           return  query.setParameter("esinicial", value).getResultList();
   }


public List<Estatus> findByEstatus(String value){
       Query query = em.createNamedQuery("Estatus.findByEstatus");
       return query.setParameter("estatus",value).getResultList();
   }


       public List<Estatus>  findByIdEstatusList(String value){
     Query query = em.createNamedQuery("Estatus.findByIdestatus");
     return  query.setParameter("idestatus", value).getResultList();
   }


public List<Estatus>  findByEstatusLike(String value){
     Query query = em.createNamedQuery("Estatus.findByEstatusLike");
     value = "%" +value.trim() +"%";
     return  query.setParameter("estatus", value).getResultList();
   }


Convertidores

Convierten los objetos en el tipo de datos necesario. Por ejemplo si usamos un selectOneMenu con una lista de objetos, el converter devolverá el objeto seleccionado.

Crear EstatusConverter.java

Crear EstatusConverter.java
  • Desde menú File, seleccione New
  • en Categories, seleccione Java Server Faces
  • en File Types, seleccione JSF ManagedBeans
  • Class Name: EstatusConverter
  • Package com.avbravo.scrumweb.converter

import com.javscaz.rigemjsf.Usuarios;
import com.javscaz.rigemjsf.ejb.UsuariosFacade;
import com.javscaz.rigemjsf.generales.JSFUtil;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;


@FacesConverter(value = "estatusConverter")
public class EstatusConverter implements Converter {


   @Inject
   private EstatusFacade ejbFacade;


   @Override
   public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
       if (value == null || value.length() == 0 || JSFUtil.isDummySelectItem(component, value)) {
           return null;
       }
       return this.ejbFacade.find(getKey(value));
   }


   java.lang.String getKey(String value) {
       java.lang.String key;
       key = value;
       return key;
   }


   String getStringKey(java.lang.String value) {
       StringBuffer sb = new StringBuffer();
       sb.append(value);
       return sb.toString();
   }


   @Override
   public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
       if (object == null
               || (object instanceof String && ((String) object).length() == 0)) {
           return null;
       }
       if (object instanceof Estatus) {
           Estatus o = (Estatus) object;
           return getStringKey(o.getUsername());
       } else {
           Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "object {0} is of type {1}; expected type: {2}", new Object[]{object, object.getClass().getName(), Estatus.class.getName()});
           return null;
       }
   }


}

Nota:
Si la llave primaria es de tipo integer, utilizar el tipo de datos java.lang.Integer
java.lang.Integer getKey(String value) {
       java.lang.Integer key;
       key = Integer.valueOf(value);
       return key;
   }


   String getStringKey(java.lang.Integer value) {
       StringBuffer sb = new StringBuffer();
       sb.append(value);
       return sb.toString();
   }

Comments

Zuly said…
Amigo, si no es molestia, podrias poner un pdf al final que contenga todo lo que has expuesto, es porque las imagenes se pierden, y no se visualizan todas. Muchas gracias, esta muy buena e importante la informacion. Me ha servido de mucho.
En este enlace están los pdf de los diversos capitulos
HERE said…
Quisiera saber como puedo obtener el script scrumweb.sql para generar la Base de Datos
claudia est said…
Antes que nada muchas gracias, tu blog esta excelente, estoy siguiendo tu libro, pero me atore al crear la base de datos, ¿donde puedo descargar el archivo sql?

gracias de antemano
claudia est said…
Antes que nada muchas gracias, tu blog esta excelente, estoy siguiendo tu libro, pero me atore al crear la base de datos, ¿donde puedo descargar el archivo sql?

gracias de antemano
claudia est said…
Antes que nada muchas gracias, tu blog esta excelente, estoy siguiendo tu libro, pero me atore al crear la base de datos, ¿donde puedo descargar el archivo sql?

gracias de antemano
claudia est said…
Antes que nada muchas gracias, tu blog esta excelente, estoy siguiendo tu libro, pero me atore al crear la base de datos, ¿donde puedo descargar el archivo sql?

gracias de antemano

Popular posts from this blog

FileUpload con Primefaces

FileUpload con Primefaces

Si queremos subir imagenes a nuestra aplicación usaremos el componente FileUpload Debemos realizar los siguientes pasos:
Agregar al archivo web.xml

   <filter>        <filter-name>PrimeFaces FileUpload Filter</filter-name>        <filter-class>            org.primefaces.webapp.filter.FileUploadFilter        </filter-class>    </filter>    <filter-mapping>        <filter-name>PrimeFaces FileUpload Filter</filter-name>        <servlet-name>Faces Servlet</servlet-name>    </filter-mapping>



Crear dentro de resources el directorio donde deseamos almacenar las imagenes En este ejemplo: resources/fotos/clinicas y agregue una imagen llamada fotos.png que se usará como imagen inicial.



En JSFUtil u otro @Named Beans que usemos agregamos tres métodos uno para obtener el path de la aplicación web , otro para obtener el path relativo a /fotos/clinicas y el otro para copiar los archivos. /*

Apache NetBeans

Apache NetBeans
https://wiki.apache.org/incubator/NetBeansProposal

Si, algo que se esperaba desde hace muchos años, una liberación de NetBeans, para convertirlo en un IDE más abierto, y que permita mayor contribución de la comunidad y de otras empresas, ya inicio su primera etapa en la incubadora de la Fundación Apache.
Las implicaciones que esto conlleva son múltiples por una parte esta la evolución de NetBeans, al permitir que más contribuyentes puedan aportar a sus mejoras, también garantiza que aquellas instituciones no sientan que es una sola organización la que controla la evolución. A las comunidades les permite sentirse que participan de un proyecto con todas las garantías que ofrece la Fundación Apache.

Muchos pensaran que Oracle esta dejando morir el proyecto, la realidad es diferente, hay muchos ingenieros que están participando del proyecto en la fundación Apache.
Es una noticia excelente para los desarrolladores, instituciones, empresas que utilizan NetBeans , se estima qu…

Un ejemplo sencillo de Refactorización y Genericos

Un ejemplo sencillo de Refactorización y Genericos

public class Refactorizador<K, V> {

    public V copyFromBeans(K k, V v) {
        try {
            Class claseK = k.getClass();
            Class claseV = v.getClass();

            Method[] metodosK = claseK.getMethods();

            for (Method method : metodosK) {
                if (isGetter(method)) {
                    Method metodoGetK = claseK.getDeclaredMethod(method.getName());
                    Method metodoSetV = claseV.getDeclaredMethod(changeGetBySet(method.getName()), method.getReturnType());
                    metodoSetV.invoke(v, metodoGetK.invoke(k));
                }

            }

        } catch (Exception e) {
            System.out.println("refactorizador() " + e.getLocalizedMessage());
        }
        return v;
    }

     public  boolean isGetter(Method method) {

        if (!method.getName().startsWith("get")) {
            return false;
        }
        if (method.getName().startsWith("getCla…