miércoles, 8 de enero de 2014

- Presentación

Esta página estará dirigida para todas aquellas personas que quieran aprender tecnologías Java J2EE y los diferentes frameworks asociados tales como por ejemplo Spring, Hibernate Struts etc etc. Asi como su integración entre cada uno de ellos como por ejemplo puede ser Spring integrado con Hibernate con aplicaciones que no solo se basen en un Hola Mundo.

Las guías y tutoriales están desarrollados de manera muy práctica. Se dará una breve descripción del framework a usar, instalación y configuración de los componentes y herramientas para desarrollar las aplicaciones. Al final lo importante es que el lector aprenda y posteriormente sea capaz de desarrollar aplicaciones utilizando los frameworks ya sea en un entorno laboral o para asignaciones universitarias o de instituto.

Indice:

- JSF 2.2 integrado con EJB 3.x con Inyección de dependencias CDI

En este tutorial describiré los pasos necesarios para realizar un proyecto JSF 2.2 con anotaciones de managed beans integrado con EJB 3.1 con Inyección de dependencias CDI, que ya es posible desde la versión 2.0 de JSF puesto que CDI es parte integral de Java EE 6 todo esto sin la herramienta de gestión y construcción MAVEN, lo cual quiere decir que obtendremos nosotros mismos las librerías necesarias para nuestros proyecto así como configuraremos nuestro entorno de desarrollo para que todos los componentes sean tomadas correctamente en nuestra aplicación. Ademas estamos usando anotaciones lo cual quiere decir que no configuraremos el comportamiento de nuestra aplicación a través del fichero faces-config.xml el cual eliminaremos.

Introducción a JSF

Es un framework MVC que simplifica principalmente la interacción de las interfaces con un usuario de cualquier tipo: Ordenador, PDA, Movil, etc etc en aplicaciones con tecnología JEE.  A traves de los Managed Bean se podrá interactuar con los eventos de los controles de la interfaz del cliente y poder enviarlas a las clases que se encuentran en el servidor de aplicaciones.




  1. Se realiza una petición a través de un cliente (Ordenador, Movil, PDA, etc etc).
  2. La petición es recibida por Contrlador que en este caso es "Faces Servlet"
  3. El Faces Servlet según la petición del cliente invocara el JSP, JSF, XHTML (Vista) que visualizará posteriormente el cliente.
  4. El Faces Servlet o el JSF invocará al Managed Bean (Modelo) para realizar la lógica necesaria para mostrar los datos que se necesiten en el JSP, JSF, XHTML.
  5. El Managed Bean podrá realizar la lógica necesaria ya sea interactuando con EJB, Spring, Hibernate etc etc, y asi obtener los datos necesarios para poder realizar su trabajo que es el de obtener los datos para poder mostrarlos en la página.
  6. Posteriormente el JSP o JSF es devuelto al cliente con la data requerida para poder ser utilizado.
Introducción a EJB 3

Es un API que forma parte del estándar de construcción de aplicaciones JEE.
Los EJB proporcionan un modelo de componentes distribuido estándar del lado del servidor. El objetivo de los EJB es dotar al programador de un modelo que le permita abstraerse de los problemas generales de una aplicación empresarial (concurrencia, transacciones, persistencia, seguridad, etc.) para centrarse en el desarrollo de la lógica de negocio en sí. El hecho de estar basado en componentes permite que éstos sean flexibles y sobre todo reutilizables. Mas información aqui: https://es.wikipedia.org/wiki/Enterprise_JavaBeans



  1. El cliente que puede ser un servlet, cliente local, remoto o inclusive otro EJB se comunica por medio de JNDI para poder comunicarse con un EJB ya sea local o remoto.
  2. EL EJB de session que puede implementar un EJB remoto, local o incluso ambos se encarga de realizar la lógica basada en la petición del cliente comunicándose con la base de datos por medio de JPA para luego devolver la respuesta al cliente.
  3. Estos componentes se deben encontrar dentro de un contenedor de aplicaciones empresariales. Que por ejemplo no puede ser un contenedor WEB como es el Tomcat pero si un contenedor empresarial que por ejemplo puede ser JBOSS.
Esto es una descripción resumida. Durante la construcción del proyecto iremos explicando a detalle los tipos de EJB y forma de comunicación que podemos realizar para poder entenderlo a detalle. Primero que todo construiremos nuestro proyecto EJB y posteriormente nuestro proyecto en JSF a quien asociaremos el proyecto EJB y finalmente crearemos un proyecto Empresarial (Enterprise Application Project) para asociar ambas tecnologías. Las herramientas que usaremos serán
  1. Eclipse Kepler
  2. JBoss 7.1.1
  3. MySQL Server 5.0
  4. Mysql-connector-java

Proyecto en EJB 3.x

Como indiqué anteriormente no explicaré como se realiza la instalación del Eclipse con su respectivo JDK, ni la Base de datos MySQL por lo que se asume que ya tenéis el entorno instalado. Lo único que explicaré es la instalación del JBoss en eclipse.

Antes que nada crearemos en MySQL nuestra base de datos así como la tabla necesaria para poder trabajar con ella:

CREATE DATABASE BD_TUTORIAL;
USE BD_TUTORIAL;
grant all on BD_TUTORIAL.* to 'admin'@'localhost' identified by 'test';

CREATE TABLE COMPONENTE
(   id        INT PRIMARY KEY AUTO_INCREMENT,
    nombre    VARCHAR(30),
    version   VARCHAR(30),
    tipo      VARCHAR(15),
    extension VARCHAR(30),
    creado    TIMESTAMP DEFAULT NOW()
);
CREATE TABLE usuario
(   id        INT PRIMARY KEY AUTO_INCREMENT,
    nombre    VARCHAR(30),
    clave   VARCHAR(30),
    creado    TIMESTAMP DEFAULT NOW()
);
insert into usuario (nombre, clave) values ('victor', 'elliott');

Luego obtenemos el servidor y nuestro conector a partir de las siguientes URL's:
  1. JBoss 7.1.1
  2. Mysql-connector-java
Una vez hayamos descomprimido el archivo del jboss nos vamos a la carpeta: 
\jboss-as-7.1.1.Final\modules\com y creamos la siguiente estructura de carpetas: mysql\main
al final quedará asi:
\jboss-as-7.1.1.Final\modules\com\mysql\main
dentro de main ponemos el conector: mysql-connector-java-5.1.25
Creamos el fichero xml: module.xml y dentro escribimos y guardamos: 

<?xml version="1.0" encoding="UTF-8"?>

<module xmlns="urn:jboss:module:1.1" name="com.mysql">

    <resources>
        <resource-root path="mysql-connector-java-5.1.25.jar"/>
        <!-- Insert resources here -->
    </resources>
    <dependencies>
    <module name="javax.api"/>
    <module name="javax.transaction.api"/>
    <module name="javax.servlet.api" optional="true"/>
    </dependencies>
</module>

Luego nos vamos a la carpeta: \jboss-as-7.1.1.Final\standalone\configuration y abrimos el archivo: standalone.xml y dentro del tag <datasources> copiamos lo siguiente:


                <datasource jta="false" jndi-name="java:/mysql_ds" pool-name="mysql_ds" enabled="true" use-ccm="false">
                    <connection-url>jdbc:mysql://localhost:3306/BD_TUTORIAL</connection-url>
                    <driver-class>com.mysql.jdbc.Driver</driver-class>
                    <driver>mysql</driver>
                    <security>
                        <user-name>admin</user-name>
                        <password>test</password>
                    </security>
                    <validation>
                        <validate-on-match>false</validate-on-match>
                        <background-validation>false</background-validation>
                    </validation>
                    <statement>
                        <share-prepared-statements>false</share-prepared-statements>
                    </statement>
                </datasource>

Y dentro del tag <drivers> lo siguiente:

<driver name="mysql" module="com.mysql"/>

Guardamos y ya tenemos nuestro Servidor JBoss configurado para poder conectarnos a la Base de datos.
Ahora instalamos el plugin de JBoss en nuestro eclipse: En el menú de eclipse Help -> Eclipse Marketplace en search buscamos JBoss e instalamos JBoss Tools (Kepler). Una vez instalado ya tenemos el JBoss plugin instalado en el Eclipse.

Ahora creamos un proyecto EJB: New -> EJB Project , le ponemos el nombre: ProyectoEJBTutorial-EJB
hacemos click en New Runtime, elegimos JBoss 7.1 Runtime -> Next Le ponemos un nombre adecuado yo le puse: JBoss 7.1 Runtime 1, en Home Directory elegimos la carpeta donde descomprimimos nuestro servidor JBoss en JRE puse jr7 y luego finish. En EJB Module elegimos la 3.1en Configuration lo dejamos a Default Configuration for JBoss 7.1 Runtime 1. Tendríais que tenerlo mas o menos asi:


Ahora nos vamos a la vista del servidor damos click en create new server, elegimos JBoss AS 7.1 en server name le pones el nombre que quieras yo lo deje el que salia por defecto: JBoss 7.1 Runtime 1 Server y en runtime enviroment elegimos el que acabamos de crear JBoss 7.1 Runtime 1. Quedaría asi:


Damos click a Finish y ya tenemos nuestro servidor configurado.
Ahora vamos a nuestro proyecto EJB damos click derecho en ejbModule -> New -> Other -> EJB -> Session Bean (EJB 3.x) -> Next y escribimos lo siguiente:

  1. Java package: com.victor.elliott.humala.logica
  2. Class name: ComponenteSessionBean
  3. State type: Stateless
  4. Hacemos check en Remote: com.victor.elliott.humala.negocio.ComponenteInterfazRemota
  5. Quitamos el check de No-interface View y quedaría asi:


Se nos crearan las siguientes clases:
/ProyectoEJBTutorial-EJB/ejbModule/com/victor/elliott/humala/logica/ComponenteSessionBean.java
/ProyectoEJBTutorial-EJB/ejbModule/com/victor/elliott/humala/negocio/ComponenteInterfazRemota.java

Ahora creamos nuestra entidad Componente:
ejbModule -> New -> Class
  1. Package: com.victor.elliott.humala.entidades
  2. Name: ComponenteEntityAhora creamos las clases para el Usuario:
Vamos a nuestro proyecto EJB damos click derecho en ejbModule -> New -> Other -> EJB -> Session Bean (EJB 3.x) -> Next y escribimos lo siguiente:
  1. Java package: com.victor.elliott.humala.logica
  2. Class name: UsuarioSessionBean
  3. State type: Stateless
  4. Hacemos check en Local: com.victor.elliott.humala.negocio.UsuarioInterfazLocal
  5. Quitamos el check de No-interface View y quedaría asi:


Se nos crearan las siguientes clases:
/ProyectoEJBTutorial-EJB/ejbModule/com/victor/elliott/humala/logica/UsuarioSessionBean.java
/ProyectoEJBTutorial-EJB/ejbModule/com/victor/elliott/humala/negocio/UsuarioInterfazLocal.java

Ahora creamos nuestra entidad Usuario:
ejbModule -> New -> Class
  1. Package: com.victor.elliott.humala.entidades
  2. Name: UsuarioEntity
A continuación crearemos un cliente el cual no es necesario para nuestro proyecto pero lo haremos para realizar algunas pruebas y ver que estamos haciendo bien las cosas.
ejbModule -> New -> Class
  1. Package: com.victor.elliott.humala.cliente
  2. Name: ClienteProbador
Por ultimo una clase que nos ayudará a comunicar el cliente con nuestros EJB's a través de JNDI
ejbModule -> New -> Class
  1. Package: com.victor.elliott.humala.clienteutility
  2. Name: JNDILookupClass
Luego insertamos el siguiente código dentro de esa clase:

package com.victor.elliott.humala.clienteutility;
 
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
public class JNDILookupClass {
 
    private static Context initialContext;
 
    private static final String PKG_INTERFACES = "org.jboss.ejb.client.naming";
 
    public static Context getInitialContext() throws NamingException {
        if (initialContext == null) {
            Properties properties = new Properties();
            properties.put(Context.URL_PKG_PREFIXES, PKG_INTERFACES);
            properties.put("jboss.naming.client.ejb.context", true);
            initialContext = new InitialContext(properties);
        }
        return initialContext;
    }
}

Aquí lo único que estamos haciendo es poner las propiedades necesarias a un contexto para poder realizar las llamadas JNDI correctamente.

Ahora que ya tenemos nuestras clases necesarias creadas crearemos nuestros ficheros de configuración:
Creamos dentro de la carpeta META-INF -> New -> Other -> XML -> XML File -> persistence.xml
y colocamos el siguiente código:

<?xml version="1.0" encoding="UTF-8"?>  
<persistence version="2.0"  
 xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">  
 <persistence-unit name="ProyectoPersistencia"  
  transaction-type="JTA">  
  <jta-data-source>mysql_ds</jta-data-source>  
  <properties>  
   <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />  
   <property name="hibernate.hbm2ddl.auto" value="validate" />  
  </properties>  
 </persistence-unit>  
</persistence>  

Usamos el tipo de persistencia de Hibernate puesto que actualmente es el proveedor para persistencia en JBoss y la configuración no es nada complicada como pueden ver. Tener en cuenta que estamos usando la conección del driver que definimos algunos pasos atras en el JBoss "mysql_ds"

Ahora vamos a añadir a nuestro proyecto EJB las librerias necesarias para poder ejecutar el cliente y hacer algunas pruebas para esto vamos a crear un fichero de configuración para luego importarlo y evitar buscar los jar necesarios dentro de nuestro servidor de aplicaciones. para esto creamos un fichero en c:\ por ejemplo que se llame: clientelibrerias.userlibraries
y ponemos lo siguiente:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<eclipse-userlibraries version="2">
    <library name="EJBClientLibrerias" systemlibrary="false">
        <archive path="<JBOSS_HOME>/jboss-as-7.1.1.Final/modules/javax/transaction/api/main/jboss-transaction-api_1.1_spec-1.0.0.Final.jar"/>
        <archive path="<JBOSS_HOME>/jboss-as-7.1.1.Final/modules/javax/ejb/api/main/jboss-ejb-api_3.1_spec-1.0.1.Final.jar"/>
        <archive path="<JBOSS_HOME>/jboss-as-7.1.1.Final/modules/org/jboss/ejb-client/main/jboss-ejb-client-1.0.5.Final.jar"/>
        <archive path="<JBOSS_HOME>/jboss-as-7.1.1.Final/modules/org/jboss/marshalling/main/jboss-marshalling-1.3.11.GA.jar"/>
        <archive path="<JBOSS_HOME>/jboss-as-7.1.1.Final/modules/org/jboss/xnio/main/xnio-api-3.0.3.GA.jar"/>
        <archive path="<JBOSS_HOME>/jboss-as-7.1.1.Final/modules/org/jboss/remoting3/main/jboss-remoting-3.2.3.GA.jar"/>
        <archive path="<JBOSS_HOME>/jboss-as-7.1.1.Final/modules/org/jboss/logging/main/jboss-logging-3.1.0.GA.jar"/>
        <archive path="<JBOSS_HOME>/jboss-as-7.1.1.Final/modules/org/jboss/xnio/nio/main/xnio-nio-3.0.3.GA.jar"/>
        <archive path="<JBOSS_HOME>/jboss-as-7.1.1.Final/modules/org/jboss/sasl/main/jboss-sasl-1.0.0.Final.jar"/>
        <archive path="<JBOSS_HOME>/jboss-as-7.1.1.Final/modules/org/jboss/marshalling/river/main/jboss-marshalling-river-1.3.11.GA.jar"/>
    </library>
</eclipse-userlibraries>

Donde reemplazamos <JBOSS_HOME> por la carpeta donde se ha descomprimido el servidor JBoss.
Ahora vamos a nuestro proyecto Click Derecho ejbModule -> Properties -> Java Build Path -> Add Library -> User Library -> Next -> User Libraries -> Import -> Browser -> Elegimos el clientelibrerias.userlibraries que hemos creado y ya estará listo nuestras librerías para el cliente. Finalmente lo seleccionamos para agregarlo al proyecto y Finish.
Luego para tener configurado correctamente al cliente creamos un archivo de propiedades que es necesario cuando creamos un cliente en JBoss:
Click derecho en el proyecto -> New -> Others -> JBoss Tools Web -> Properties File -> Next:

  1. Folder:* /ProyectoEJBTutorial-EJB/ejbModule
  2. Name:* jboss-ejb-client.properties

Y Finish. Dentro del archivo de propiedades ponemos lo siguiente:

remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false

remote.connections=default

remote.connection.default.host=localhost
remote.connection.default.port = 4447
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false

Ahora ya tenemos todo el entorno EJB listo para empezar a desarrollar. EL entorno de trabajo quedará de la siguiente forma:



Primero que todo configuramos las entidades que serán mapeadas prácticamente como nuestras tablas creadas inicialmente en la Base de datos:
/ProyectoEJBTutorial-EJB/ejbModule/com/victor/elliott/humala/entidades/UsuarioEntity.java

package com.victor.elliott.humala.entidades;

import java.io.Serializable;  

import javax.persistence.*; 


@Entity  
@Table(name = "usuario") 
public class UsuarioEntity implements Serializable{
    private static final long serialVersionUID = 1L;
 
  @Id
  @Column(name="id")
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private Integer id;
  
  @Column(name="nombre")
  private String nombre;
  
  @Column(name="clave")
  private String clave;

  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 String getClave() {
   return clave;
  }

  public void setClave(String clave) {
   this.clave = clave;
  }
  
  public String toString(){
   
   return "Usuario: "+this.nombre;
  }
}

/ProyectoEJBTutorial-EJB/ejbModule/com/victor/elliott/humala/entidades/ComponenteEntity.java

package com.victor.elliott.humala.entidades;

import java.io.Serializable;
import javax.persistence.*;

@Entity
@Table(name="componente")
public class ComponenteEntity implements Serializable{
    private static final long serialVersionUID = 1L;

 
  @Id
  @Column(name="id")
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private Integer id;
  
  @Column(name="nombre")
  private String nombre;
  
  @Column(name="version")
  private String version;
  
  @Column(name="tipo")
  private String tipo;
  
  @Column(name="extension")
  private String extension;
  
  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 String getVersion() {
   return version;
  }
  public void setVersion(String version) {
   this.version = version;
  }
  public String getTipo() {
   return tipo;
  }
  public void setTipo(String tipo) {
   this.tipo = tipo;
  }
  public String getExtension() {
   return extension;
  }
  public void setExtension(String extension) {
   this.extension = extension;
  }
  
  public String toString(){
   
   return "Componente: "+this.id+", "+this.nombre+", "+this.version+", "+this.extension;
  }
 }
Si os percatáis ambas entidades implementan Serializable, esto es debido a que son objetos que viajarán via red para ser guardadas en la session Http cuando usemos el cliente servlet (posteriormente).
Ahora ya tenemos mapeadas nuestras tablas con estas dos entidades. Ahora desarrollemos las llamadas respectivas en los sessionBean:

Antes que nada indicar que la diferencia principal entre una interfaz local y remota es que una interfaz local necesita un cliente que tenga el mismo JVM (Java Virtual Machine) y una remota no. Por ejemplo el cliente que vamos a implementar en un momento es standalone lo cual quiere decir que no se va a ejecutar con nuestro proyecto. Este cliente vamos a ejecutar como una aplicación Java que se encuentra fuera del contexto de nuestro proyecto y por lo tanto tiene una diferente JVM por lo que las pruebas solo podremos hacerla con la interfaz remota. (Podéis probar con la local si deseáis pero os saldrá un error de compatibilidad)
Ahora desarrollemos nuestras interfaces y sus respectivas implementaciones.
Primero modifiquemos:

/ProyectoEJBTutorial-EJB/ejbModule/com/victor/elliott/humala/negocio/UsuarioInterfazLocal.java

package com.victor.elliott.humala.negocio;

import javax.ejb.Local;

import com.victor.elliott.humala.entidades.UsuarioEntity;

@Local
public interface UsuarioInterfazLocal {
 public boolean buscarUsuario(UsuarioEntity usuario);
}

Aqui estamos indicando que la clase es una interfaz de tipo Local declarando un método a ser implementado.

/ProyectoEJBTutorial-EJB/ejbModule/com/victor/elliott/humala/logica/UsuarioSessionBean.java

package com.victor.elliott.humala.logica;

import com.victor.elliott.humala.entidades.UsuarioEntity;
import com.victor.elliott.humala.negocio.UsuarioInterfazLocal;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 * Session Bean implementation class UsuarioSessionBean
 */
@Stateless
public class UsuarioSessionBean implements UsuarioInterfazLocal {

 @PersistenceContext  
 private EntityManager entityManager;
 
 @Override
 public boolean buscarUsuario(UsuarioEntity usuario) {
  boolean existe=false;
  String queryString = "select u from UsuarioEntity u where u.nombre = :nombre and u.clave = :clave";
  Query query = this.entityManager.createQuery(queryString);
  query.setParameter("nombre", usuario.getNombre());
        query.setParameter("clave", usuario.getClave());
        existe = !query.getResultList().isEmpty();
  return existe;
 }

}
  1. Aquí creamos nuestra clase UsuarioSessionBean que implementa UsuarioInterfazLocal.
  2. La clase está declarada como Stateless lo cual indica que el estado del SessionBean no estará dedicado a un cliente específico lo cual quiere decir que muchos cliente podrían interactuar con el y modificar su estado y/o datos. Si fuera Statefull indicaría que el estado del sessionBean solo estará reservado para el cliente que lo invoque por tanto no se perdería la data especifica para ese cliente. Y finalmente si se tratará de un Singleton su estado será compartido por toda la aplicación es decir que se instancia una sola vez al sessionBean al inicio de la aplicación y esta instancia perdurará hasta que se apague el servidor.
  3. Creamos nuestro EntityManager que es el encargado de interactuar con la Base de datos a través del Entity UsuarioEntity que definimos anteriormente.
  4. Implementamos el método buscarUsuario que me retornará true en caso que lo encuentre.
  5. Hay que percatarnos que la query se hace contra la entidad y no contra la tabla en si, me refiero que no hacemos "select u from usuario u" si no "select u from UsuarioEntity u".
Modificamos
/ProyectoEJBTutorial-EJB/ejbModule/com/victor/elliott/humala/negocio/ComponenteInterfazRemota.java

package com.victor.elliott.humala.negocio;

import java.util.List;

import javax.ejb.Remote;

import com.victor.elliott.humala.entidades.ComponenteEntity;

@Remote
public interface ComponenteInterfazRemota {
   public void agregarComponente(ComponenteEntity componente);
   public List<ComponenteEntity> mostrarComponentes();
   public void eliminarComponente(Integer id);
   public void actualizarComponente(ComponenteEntity componente);
   public ComponenteEntity mostrarComponente(Integer id);
   public boolean existeComponente(ComponenteEntity componente);
}

Aqui estamos indicando que la clase es una interfaz de tipo Remota declarando seis métodos a ser implementados.

/ProyectoEJBTutorial-EJB/ejbModule/com/victor/elliott/humala/logica/ComponenteSessionBean.java

package com.victor.elliott.humala.logica;

import java.util.List;

import com.victor.elliott.humala.entidades.ComponenteEntity;
import com.victor.elliott.humala.negocio.ComponenteInterfazRemota;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
/**
 * Session Bean implementation class ComponenteSessionBean
 */
@Stateless
public class ComponenteSessionBean implements ComponenteInterfazRemota {
 
 @PersistenceContext  
 private EntityManager entityManager;
 
 @Override
 public void agregarComponente(ComponenteEntity componente) {
  entityManager.persist(componente);
 }

 @Override
 public List<ComponenteEntity> mostrarComponentes() {
  String queryString = "select c from ComponenteEntity c";
  TypedQuery<ComponenteEntity> query = this.entityManager.createQuery(queryString,ComponenteEntity.class);
  return query.getResultList();
 }

 @Override
 public void eliminarComponente(Integer id) {
  ComponenteEntity entity=entityManager.find(ComponenteEntity.class, id);
  entityManager.remove(entity);
 }

 @Override
 public void actualizarComponente(ComponenteEntity componente) {
  entityManager.merge(componente);
 }

 @Override
 public ComponenteEntity mostrarComponente(Integer id) {
  return entityManager.find(ComponenteEntity.class, id);
 }
 
 public boolean existeComponente(ComponenteEntity componente) {
  boolean existe=false;
  String queryString = "select c from ComponenteEntity c where c.nombre = :nombre";
  Query query = this.entityManager.createQuery(queryString);
  query.setParameter("nombre", componente.getNombre());
        existe = !query.getResultList().isEmpty();
  return existe;
 } 
}
  1. Aquí creamos nuestra clase ComponenteSessionBean que implementa ComponenteInterfazRemota.
  2. La clase está declarada como Stateless lo cual indica que el estado del SessionBean no estará dedicado a un cliente específico lo cual quiere decir que muchos cliente podrían interactuar con el y modificar su estado y/o datos. Si fuera Statefull indicaría que el estado del sessionBean solo estará reservado para el cliente que lo invoque por tanto no se perdería la data especifica para ese cliente. Y finalmente si se tratará de un Singleton su estado será compartido por toda la aplicación es decir que se instancia una sola vez al sessionBean al inicio de la aplicación y esta instancia perdurará hasta que se apague el servidor.
  3. Creamos nuestro EntityManager que es el encargado de interactuar con la Base de datos a través del Entity ComponenteEntity que definimos anteriormente.
  4. Implementamos los métodos agregarComponente, mostrarComponentes, eliminarComponente, actualizarComponente, mostrarComponente, existeComponente que me retornará true en caso que lo encuentre.
  5. Hay que percatarnos que la query se hace contra la entidad y no contra la tabla en si, me refiero que no hacemos "select c from componente c" si no "select c from ComponenteEntity c".
Ahora codificamos a nuestro cliente:

/ProyectoEJBTutorial-EJB/ejbModule/com/victor/elliott/humala/cliente/ClienteProbador.java

package com.victor.elliott.humala.cliente;

import java.util.List;

import javax.naming.Context;
import javax.naming.NamingException;

import com.victor.elliott.humala.clienteutility.JNDILookupClass;
import com.victor.elliott.humala.entidades.ComponenteEntity;
import com.victor.elliott.humala.logica.ComponenteSessionBean;
import com.victor.elliott.humala.negocio.ComponenteInterfazRemota;

public class ClienteProbador {

 public static void main(String[] args) {
  ComponenteInterfazRemota componenteIR=doLookup();
  List<ComponenteEntity> componentesLista;
  ComponenteEntity componente=new ComponenteEntity();
  boolean existe=false;

  componente.setNombre("Eclipse");
  componente.setVersion("4.3.0");
  componente.setTipo("IDE");
  componente.setExtension("exe");
  componenteIR.agregarComponente(componente);//id=1
  componente.setNombre("Hibernate");
  componente.setVersion("4.2.7");
  componente.setTipo("Framework");
  componente.setExtension("zip");
  componenteIR.agregarComponente(componente);//id=2
  componente.setNombre("EJB");
  componente.setVersion("3.1.0");
  componente.setTipo("Framework");
  componente.setExtension("zip");
  componenteIR.agregarComponente(componente);//id=3
  componente.setNombre("MySQL");
  componente.setVersion("5.0");
  componente.setTipo("BD");
  componente.setExtension("msi");
  componenteIR.agregarComponente(componente);//id=4
  componentesLista = componenteIR.mostrarComponentes();
  System.out.println(componentesLista.toString());
  componente.setId(1);
  componente.setNombre("Eclipse");
  componente.setVersion("4.3.1");
  componente.setTipo("IDE");
  componente.setExtension("exe");
  componenteIR.actualizarComponente(componente);
  System.out.println(componenteIR.mostrarComponente(1).toString());
  componenteIR.eliminarComponente(4);
  componentesLista = componenteIR.mostrarComponentes();
  System.out.println(componentesLista.toString());
  componente.setNombre("Eclipse");
  existe=componenteIR.existeComponente(componente);
  System.out.println("Componente Eclipse existe es:"+existe);
  componente.setNombre("MySQL");
  existe=componenteIR.existeComponente(componente);
  System.out.println("Componente MySQL existe es:"+existe);
 }
    private static ComponenteInterfazRemota doLookup() {
        Context context = null;
        ComponenteInterfazRemota cIR = null;
        try {
            // 1. Obtaining Context
            context = JNDILookupClass.getInitialContext();
            // 2. Generate JNDI Lookup name
            String lookupName = getLookupName();
            // 3. Lookup and cast
            System.out.println("EL lookupName es: "+lookupName);
            cIR = (ComponenteInterfazRemota) context.lookup(lookupName);
 
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return cIR;
    }
 
    private static String getLookupName() {
        /*The app name is the EAR name of the deployed EJB without .ear
        suffix. Since we haven't deployed the application as a .ear, the app
        name for us will be an empty string */
        String appName = "";
 
        /* The module name is the JAR name of the deployed EJB without the
        .jar suffix.*/
        String moduleName = "ProyectoEJBTutorial-EJB";
 
        /* AS7 allows each deployment to have an (optional) distinct name.
        This can be an empty string if distinct name is not specified.*/
        String distinctName = "";
 
        // The EJB bean implementation class name
        String beanName = ComponenteSessionBean.class.getSimpleName();
 
        // Fully qualified remote interface name
        final String interfaceName = ComponenteInterfazRemota.class.getName();
 
        // Create a look up string name
        String name = "ejb:" + appName + "/" + moduleName + "/" +
                distinctName    + "/" + beanName + "!" + interfaceName;
        return name;
    } 

}

Que realizará las siguientes tareas:
  1. Crear cuatro componentes en la base de datos con id auto-generables: 1,2,3 y 4 respectivamente.
  2. Mostrar los cuatro componentes mediante una lista.
  3. Modificar el primer componente id=1
  4. Mostrar el primer componente
  5. Eliminar el cuarto componente id=4
  6. Mostrar los 3 componentes de la base de datos que quedan.
  7. Pregunta si existe el componentes Eclipse
  8. Pregunta si exise el componente MySQL
  9. Creamos el método doLookup y getLookupName para invocar a nuestro EJB remotoa través de JNDI. Hay que percatarnos que doLookup  hace la llamada JNDILookupClass para obtener el nombre del contexto con sus respectivas propiedades y getLookupName construye el nombre como será invocado el EJB remoto.
Ahora y tenemos lista nuestra aplicación EJB para poder ser testeada. Antes que nada asegurémonos que tenemos nuestra base de datos vacía para que no haya errores al invocar los métodos. Para esto ejecutemos los siguientes comandos en la Base de datos:

DELETE FROM COMPONENTE;
ALTER TABLE COMPONENTE AUTO_INCREMENT=1;

Ahora Iniciemos el servidor Click derecho en JBoss Runtime Server -> Start
Una vez tengamos el servidor levantado hacemos click derecho -> Add and Remove
seleccionamos nuestra aplicación ProyectoEJBTutorial-EJB y presionamos ADD pafra agregarlo a nuestro servidor y poder deployarlo. Presionamos Finish y tendremos que ver lo siguiente en el log de la consola sin ningún error:

18:55:22,016 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named UsuarioSessionBean in deployment unit deployment "ProyectoEJBTutorial-EJB.jar" are as follows:

 java:global/ProyectoEJBTutorial-EJB/UsuarioSessionBean!com.victor.elliott.humala.negocio.UsuarioInterfazLocal
 java:app/ProyectoEJBTutorial-EJB/UsuarioSessionBean!com.victor.elliott.humala.negocio.UsuarioInterfazLocal
 java:module/UsuarioSessionBean!com.victor.elliott.humala.negocio.UsuarioInterfazLocal
 java:global/ProyectoEJBTutorial-EJB/UsuarioSessionBean
 java:app/ProyectoEJBTutorial-EJB/UsuarioSessionBean
 java:module/UsuarioSessionBean

18:55:22,024 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named ComponenteSessionBean in deployment unit deployment "ProyectoEJBTutorial-EJB.jar" are as follows:

 java:global/ProyectoEJBTutorial-EJB/ComponenteSessionBean!com.victor.elliott.humala.negocio.ComponenteInterfazRemota
 java:app/ProyectoEJBTutorial-EJB/ComponenteSessionBean!com.victor.elliott.humala.negocio.ComponenteInterfazRemota
 java:module/ComponenteSessionBean!com.victor.elliott.humala.negocio.ComponenteInterfazRemota
 java:jboss/exported/ProyectoEJBTutorial-EJB/ComponenteSessionBean!com.victor.elliott.humala.negocio.ComponenteInterfazRemota
 java:global/ProyectoEJBTutorial-EJB/ComponenteSessionBean
 java:app/ProyectoEJBTutorial-EJB/ComponenteSessionBean
 java:module/ComponenteSessionBean

Esto quiere decir que nuestros SessionBean; UsuarioSessionBean y ComponenteSessionBean se han inicializado correctamente. Tenemos que estar atentos a cualquier cambio que hagamos en los EJB tenemos que volver a deployar es decir hacer click derecho en el servidor -> Add and Remove seleccionamos el proyecto y presionamos Remove modificamos nuestro EJB y luego lo volvemos a añadir ADD para que se vuelva a deployar con los cambios realizados. Ojo no es necesario reiniciar ni parar el servidor para esto. Cuando hagamos un cambio a nuestro cliente ClienteProbador no es necesario volver a deployar.

Ahora que ya tenemos nuestro proyecto deployado nos disponemos a ejecutar al cliente:
Click derecho en ClienteProbador -> Run as -> Java Application
y veremos el siguiente log si es que no ocurre ningún error:

EL lookupName es: ejb:/ProyectoEJBTutorial-EJB//ComponenteSessionBean!com.victor.elliott.humala.negocio.ComponenteInterfazRemota
[Componente: 1, Eclipse, 4.3.0, exe, Componente: 2, Hibernate, 4.2.7, zip, Componente: 3, EJB, 3.1.0, zip, Componente: 4, MySQL, 5.0, msi]
Componente: 1, Eclipse, 4.3.1, exe
[Componente: 1, Eclipse, 4.3.1, exe, Componente: 2, Hibernate, 4.2.7, zip, Componente: 3, EJB, 3.1.0, zip]
Componente Eclipse existe es:true
Componente MySQL existe es:false

Lo cual lo podréis corroborar haciendo un select en la base de datos sobre la tabla componente

Ahora comenzamos son la segunda parte del tutorial.

Proyecto en JSF 2.2

  1. Eclipse Kepler
  2. JBoss 7.1.1
Como indiqué anteriormente no explicaré como se realiza la instalación del Eclipse con su respectivo JDK ni el  JBOSS por lo que se asume que ya tenéis el entorno instalado.

Primero que todo creamos un proyecto WEB en el eclipse: File -> New -> Dynamic Web Project
  1. Project Name: ProyectoJSFTutorial-WEB
  2. Target runtime: JBoss 7.1 Runtime
  3. Dynamic web module version: 3.0
  4. Configuration: JavaServer Faces v2.2 Project
Tal como se muestra:


Damos click en Modify en Configuration: y seleccionamos CDI 1.0 tal como se muestra en la pantalla:


Damos click en Ok y en Finish

Asociamos al Proyecto Web el Proyecto EJB que ya creamos en la primera parte.
Click Derecho al proyecto WEB -> Properties -> Java Build Path -> Projects -> Add  Seleccionamos ProyectoEJBTutorial-EJB -> OK -> OK Y ya tenemos nuestro proyecto WEB asociado al EJB

Por ahora como vamos a usar anotaciones e inyecciones en nuestros Managed Beans y no vamos a realizar ningun tipo de reglas en la navegación ya que nosotros controlaremos ello desde los ManagedBean eliminaremos el xml de configuración y navegación de jsf:
eliminar /ProyectoJSFTutorial-WEB/WebContent/WEB-INF/faces-config.xml.
Ahora configuramos nuestro descriptor de despliegue que si lo abrís debe estar ya configurado con los Faces Servlet(Controlador) pero agregaremos una entrada para indicar que nuestra página inicial será index.xhtml que posteriormente crearemos.y deberá quedar de la siguiente forma.

/ProyectoJSFTutorial-WEB/WebContent/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>ProyectoJSFTutorial-WEB</display-name>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>faces/index.xhtml</welcome-file>
  </welcome-file-list>
</web-app>

Ahora creamos los componentes necesarios para nuestro proyecto:
En /ProyectoJSFTutorial-WEB/src creamos el paquete

  1. com.victor.elliott.humala.controladores
Luego creamos las siguientes clases en el paquete

    1. com.victor.elliott.humala.controladores -> ComponenteControlador.java
    2. com.victor.elliott.humala.controladores -> UsuarioControlador.java
    Una vez creadas las clases creamos las paginas y css respectivos.

    1. Creamos primero que todo las carpetas pages y resources en /ProyectoJSFTutorial-WEB/WebContent/
    2. Creamos la carpeta css en /ProyectoJSFTutorial-WEB/WebContent/resources
    3. Creamos index.xhtml en /ProyectoJSFTutorial-WEB/WebContent
    4. Creamos login.xhtml en /ProyectoJSFTutorial-WEB/WebContent/pages
    5. Creamos agregarComponentes.xhtml en /ProyectoJSFTutorial-WEB/WebContent/pages
    6. Creamos mostrarComponentes.xhtml en /ProyectoJSFTutorial-WEB/WebContent/pages
    7. Creamos estiloTabla.css en /ProyectoJSFTutorial-WEB/WebContent/resources/css
    Una vez creadas nuestras clases, paginas y componentes que usaremos, la estructura de proyecto debe de quedar de la siguiente manera:


    Ahora si podemos empezar a codificar nuestro proyecto, Hay que tener en cuenta que las librerías de JSF 2.2 ya están embebidas dentro del RunTime de JBoss asi que no sera necesario descargar ninguna librería. 

    Primero que todo modificamos
    /ProyectoJSFTutorial-WEB/src/com/victor/elliott/humala/controladores/UsuarioControlador.java

    package com.victor.elliott.humala.controladores;
    
    import java.io.Serializable;
    
    import javax.ejb.EJB;
    import javax.enterprise.context.SessionScoped;
    import javax.faces.context.FacesContext;
    import javax.inject.Named;
    
    import com.victor.elliott.humala.entidades.UsuarioEntity;
    import com.victor.elliott.humala.negocio.UsuarioInterfazLocal;
    
    
    @Named
    @SessionScoped
    public class UsuarioControlador implements Serializable{
     private static final long serialVersionUID = 1L;
     @EJB
     private UsuarioInterfazLocal usuarioLocal;
     private UsuarioEntity usuarioForm=new UsuarioEntity();
     private String error;
     private String mensaje;
     
     public String verificarUsuario() {
      System.out.println("Entro a verificarUsuario");
      if(usuarioLocal.buscarUsuario(usuarioForm)){
       mensaje= "Usuario Correcto: "+usuarioForm.getNombre();
       return "agregarComponentes";   
      }
      else if("".equals(usuarioForm.getNombre())||"".equals(usuarioForm.getClave())){
       error="Los datos del usuario no pueden estar vacios";
       return "login";
      }
      else{
       error="El usuario no está registrado en el sistema";
       return "login";
      }
     }
     public String salir() {
      System.out.println("Saliendo de la sesión");
      usuarioForm=new UsuarioEntity();
      error="";
      FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
      return "login";
     }
     public UsuarioEntity getUsuarioForm() {
      return usuarioForm;
     }
     public void setUsuarioForm(UsuarioEntity usuarioForm) {
      this.usuarioForm = usuarioForm;
     }
     public String getError() {
      return error;
     }
     public void setError(String error) {
      this.error = error;
     }
     public String getMensaje() {
      return mensaje;
     }
     public void setMensaje(String mensaje) {
      this.mensaje = mensaje;
     }
    }
    


    1. Todos los import javax.faces son necesarios para la implementacion del ManagedBean con las Inyecciones de CDI
    2. Indicamos la anotación @Named para hacerle saber a la aplicación que se trata de un elemento de modelo que se encargará de gestionar los datos de las paginas que lo necesiten. Tener en cuenta que normalmente se usaría @Named(name="nombredelBean") pero al no ponerle el nombre automáticamente coge el nombre de la clase y le coloca la minúscula inicialmente es decir que @Named = @Named(name="usuarioControlador")
    3. Indicamos la anotación @SessionScoped para indicarle a la aplicación que se trata de un ManagedBean de session es decir que persistirá hasta que se termine la sesión o se cierre el browser que está utilizando el cliente. Tener en cuenta que esta anotación tiene que venir del import: javax.enterprise.context.SessionScoped; ya que si viene del javax.faces.bean.SessionScoped; no funcionará. Hacemos esto por que luego recuperaremos el nombre del usuario el cual necesitamos que persista. Existen otros tipos pero los mas importantes son @SessionScoped (persistencia en la sesión), @RequestScoped (persistencia durante el request), @ApplicationScoped (persistencia durante toda la aplicación, hasta que se para el servidor) y @Viewscoped (persistencia durante la vista, usada normalmente para peticiones AJAX).
    4. Obtenermos nuestro EJB local (usuarioLocal) a traves de la inyección de dependencia @EJB private UsuarioInterfazLocal usuarioLocal;
    5. Declaramos UsuarioEntity usuarioForm=new UsuarioEntity() con sus respectivos getter y setter puesto que será un objeto que interactuará con nuestras paginas y tenemos que inicializarlo con el constructor para que en un principio sus datos aparezcan vacíos y no haya errores de nullpointer.
    6. Los atributos error y mensaje con sus respectivos getter y setter son declarados para enviar el mensaje respectivo a la pagina en caso de error y/o éxito.
    7. Creamos el método verificarUsuario que validará los datos ingresados del usuario a través de nuestro EJB usuarioLocal.buscarUsuario(usuarioForm) y en caso de exito retornare la página a la cual me dirigiré "agregarComponentes" que la aplicación interpretará como agregarComponentes.xhtml con su respectivo mensaje de éxito y en caso de error volveré a la misma página "login" que la aplicación interpretará como "login.xhtml" con su respectivo mensaje de error.
    8. Creamos el método salir que basicamente hara que retorne a la página de login pero antes de ello cerrará la sesión a través del comando: FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
    Ahora modificamos el otro controlador:

    /ProyectoJSFTutorial-WEB/src/com/victor/elliott/humala/controladores/ComponenteControlador.java

    package com.victor.elliott.humala.controladores;
    
    import java.util.List;
    
    import javax.annotation.PostConstruct;
    import javax.ejb.EJB;
    import javax.enterprise.context.RequestScoped;
    import javax.faces.context.FacesContext;
    import javax.inject.Inject;
    import javax.inject.Named;
    
    import com.victor.elliott.humala.entidades.ComponenteEntity;
    import com.victor.elliott.humala.negocio.ComponenteInterfazRemota;
    
    @Named
    @RequestScoped
    public class ComponenteControlador {
    
     @EJB
     private ComponenteInterfazRemota componenteRemoto; 
     @Inject
     private UsuarioControlador usuarioControlador;
     private ComponenteEntity componenteForm=new ComponenteEntity();
     private List<ComponenteEntity> componenteLista;
     private String error;
     private String mensaje;
     private String accion;//Si vamos a modificar o agregar un nuevo componente y personalizar la pagina agregarComponentes.xhtml
    
     @PostConstruct
     public void init(){
      mensaje= usuarioControlador.getMensaje();
      componenteLista=componenteRemoto.mostrarComponentes();
      accion=FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("accion");
     }
     public String registrarComponente() {
      if("".equals(componenteForm.getNombre())||"".equals(componenteForm.getTipo())||"".equals(componenteForm.getVersion())||"".equals(componenteForm.getExtension())){
       error="Los datos del componente no pueden estar vacios";
       return "agregarComponentes";
      }
      else if(componenteRemoto.existeComponente(componenteForm)){
       error="El componente ya existe agregar otro";
       return "agregarComponentes";
      }
      else{
       componenteRemoto.agregarComponente(componenteForm);
       System.out.println("Componente guardado");
       componenteLista=componenteRemoto.mostrarComponentes();
       return "mostrarComponentes";
      }
     }
     public String eliminarComponente(Integer id) {
      componenteRemoto.eliminarComponente(id);
      System.out.println("Componente eliminado");
      componenteLista=componenteRemoto.mostrarComponentes();
      return "mostrarComponentes";
     }
     public String modificarComponente(ComponenteEntity componenteForm) {
      componenteRemoto.actualizarComponente(componenteForm);
      System.out.println("Componente actualizado");
      componenteLista=componenteRemoto.mostrarComponentes();
      return "mostrarComponentes";
     }
     public String volverModificarComponente(Integer id) {
      componenteForm=componenteRemoto.mostrarComponente(id);
      System.out.println("Vuelve a modificar componente");
      accion="modificar";
      return "agregarComponentes";
     }
     public String volverComponente() {
      componenteForm=new ComponenteEntity();
      System.out.println("Volver Componente");
      accion="registrar";
      return "agregarComponentes";
     }
     public String verListaComponentes(){
      componenteLista=componenteRemoto.mostrarComponentes();
      return "mostrarComponentes";
     }
     public ComponenteEntity getComponenteForm() {
      return componenteForm;
     }
     public void setComponenteForm(ComponenteEntity componenteForm) {
      this.componenteForm = componenteForm;
     }
     public List<ComponenteEntity> getComponenteLista() {
      return componenteLista;
     }
     public void setComponenteLista(List<ComponenteEntity> componenteLista) {
      this.componenteLista = componenteLista;
     }
     public String getError() {
      return error;
     }
     public void setError(String error) {
      this.error = error;
     }
     public String getMensaje() {
      return mensaje;
     }
     public void setMensaje(String mensaje) {
      this.mensaje = mensaje;
     }
     public String getAccion() {
      return accion;
     }
     public void setAccion(String accion) {
      this.accion = accion;
     }
    }
    

    1. Todos los import javax.faces son necesarios para la implementacion del ManagedBean con CDI.
    2. Indicamos la anotación @Named para hacerle saber a la aplicación que se trata de un elemento de modelo que se encargará de gestionar los datos de las paginas que lo necesiten. Tener en cuenta que normalmente se usaría @Named(name="nombredelBean") pero al no ponerle el nombre automáticamente coge el nombre de la clase y le coloca la minúscula inicialmente es decir que @Named = @Named(name="componenteControlador")
    3. Indicamos la anotación @RequestScoped para indicarle a la aplicación que se trata de un ManagedBean de request es decir que persistirá hasta que se termine el request y ante un nuevo request se creará otro. Hacemos esto por que los datos del componente solo se utilizarán para guardarlos y luego no me interesa que persista. Existen otros tipos pero los mas importantes son @SessionScoped (persistencia en la sesión), @RequestScoped (persistencia durante el request), @ApplicationScoped (persistencia durante toda la aplicación, hasta que se para el servidor) y @Viewscoped (persistencia durante la vista, usada normalmente para peticiones AJAX).
    4. Obtenermos nuestro EJB local (componenteRemoto) a traves de la inyección de dependencia @EJB private ComponenteInterfazRemota componenteRemoto;
    5. Declaramos ComponenteEntity componenteForm=new ComponenteEntity(); con sus respectivos getter y setter puesto que será un objeto que interactuará con nuestras paginas y tenemos que inicializarlo con el constructor para que en un principio sus datos aparezcan vacíos y no haya errores de nullpointer.
    6. Declaramos la lista private List<ComponenteEntity> componenteLista; con sus respectivos getter y setter para poder interactuar con la página que mostrará la lista de componentes.
    7. Los atributos error, mensaje y accion con sus respectivos getter y setter son declarados para enviar el mensaje respectivo a la pagina en caso de error y/o éxito ademas de saber la acción que tendrá que hace (Registrar o Modificar).
    8. La anotación @PostConstruct me sirve para determinar algunos valores antes que se invoque a la clase a través del método init donde tendremoss llenar el mensaje que aparecerá al inicio de los componentes a traves del managed bean de session usuarioControlador.getMensaje(). Si no hacemos esto el mensaje aparecerá vacio puesto que no se habrá invocado a ningun metodo inicialmente para tener el mensaje definido. También obtenemos la lista para poder mostrarla en la página ya que de otra forma podriamos perderla ya que al hacer un Request se reinician todos los valores. De la misma forma obtenemos la acción que se está realizando por el mismo criterio del punto anterior y no perderla en el Request de la siguiente forma: accion=FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("accion"); para esto desde la página tenemos que haber enviado como parámetro el valor de "accion".
    9. Creamos el método registrarComponente que validará los datos ingresados del componente y en caso de exito guardaré el componente en la Base de datos a traves del EJB componenteRemoto.agregarComponente(componenteForm); y luego recuperare la lista con el EJB componenteLista=componenteRemoto.mostrarComponentes();, luego retornare la página a la cual me dirigiré "mostrarComponentes" que la aplicación interpretará como mostrarComponentes.xhtml y en caso de error por ejemplo que el componente ya exista validandolo con el EJB componenteRemoto.existeComponente(componenteForm) volveré a la misma página "agregarComponentes" que la aplicación interpretará como "agregarComponentes.xhtml" con su respectivo mensaje de error.
    10. Creamos el método eliminarComponente que eliminará el componente que se pasa como parámetro en el método, luego recupero la lista con el componente eliminado y vuelvo a la misma página mostrarComponentes.xhtml a traves del return "mostrarComponentes".
    11. Creamos el método modificarComponente que modificará el componente que se pasa como parámetro en el método, luego recupero la lista con el componente eliminado y voy a la pagina de la lista de componentes mostrarComponentes.xhtml a traves del return "mostrarComponentes".
    12. Creamos el método volverModificarComponente que me mostrará el componente que voy a modificar a través del id que se pasa como parámetro, luego indico que esta acción se trata de una edición indicando accion="modificar"; y voy a la pagina de crear componentes agregarComponentes.xhtml a traves del return "agregarComponentes".
    13. Creamos el método volverComponente que retorna a la página de agregar componentes indicando que esta acción se trata de una creacion indicando accion="registrar"; y voy a la pagina de crear componentes agregarComponentes.xhtml a traves del return "agregarComponentes".
    14. Creamos el método verListaComponentes que lo único que hará será obtener la lista de componentes a través del EJB componenteLista=componenteRemoto.mostrarComponentes(); y luego ir a la página mostrarComponentes.xhtml a traves del return "mostrarrComponentes".
    Una vez listos nuestros controladores modifiquemos las páginas:
    /ProyectoJSFTutorial-WEB/WebContent/index.xhtml

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <meta http-equiv="Refresh" content= "0; URL=faces/pages/login.xhtml"/>
    

    Donde básicamente le indicamos al index.xhtml que es nuestra página inicial que se dirija a la página principal login.xhtml a través de la etiqueta META.
    • /ProyectoJSFTutorial-WEB/WebContent/pages/login.xhtml

    <!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:f="http://java.sun.com/jsf/core">
    
    <h:head>
     <title>Tutorial JSF by Victor Elliott Humala</title>
    </h:head>
    <h:body>
     <h:outputText style="color:red" value="#{usuarioControlador.error}" />
     <h:form>
      <h:panelGrid columns="2">
       <h:outputLabel value="Nombre" for="nombre" />
       <h:inputText value="#{usuarioControlador.usuarioForm.nombre}" id="nombre" />
       <h:outputLabel value="Clave" for="clave" />
       <h:inputText value="#{usuarioControlador.usuarioForm.clave}" id="clave" />   
       <h:commandButton value="Ingresar" action="#{usuarioControlador.verificarUsuario}"/>
      </h:panelGrid>
     </h:form>
    </h:body>
    </html>
    

    1. Declaramos la librería para nuestros tags de jsf (:ui, :h y :f)
    2. Mostramos en rojo el error usuarioControlador.error en caso que exista.
    3. Finalmente agregamos un form con los tag de jsf para que puedas llenarse los datos necesarios del usuario (usuarioForm) y al hacer submit vaya al controlador respectivo usuarioControlador.verificarUsuario.
    Modificamos
    • /ProyectoJSFTutorial-WEB/WebContent/pages/agregarComponentes.xhtml
    <!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:f="http://java.sun.com/jsf/core"
     xmlns:c="http://java.sun.com/jsp/jstl/core">
    
    <h:head>
     <title>Tutorial JSF by Victor Elliott Humala</title>
    </h:head>
    <h:body>
    
     <h4><h:outputText style="color:blue" value="#{componenteControlador.mensaje}" />    <h:form><h:commandLink value="Salir" action="#{usuarioControlador.salir}"/></h:form></h4> 
     
    
    
    <h2><h:outputText style="color:black" value="Modificar Componente" rendered="#{componenteControlador.accion == 'modificar'}" /></h2>
    <h2><h:outputText style="color:black" value="Agregar Componente" rendered="#{componenteControlador.accion != 'modificar'}" /></h2>
    
     <h4><h:outputText style="color:red" value="#{componenteControlador.error}" /></h4>
     <h:form>
    
      <h:inputHidden value="#{componenteControlador.componenteForm.id}" rendered="#{componenteControlador.accion == 'modificar'}" />
      <h:panelGrid columns="2">
       <h:outputLabel value="Nombre" for="nombre" />
       <h:inputText value="#{componenteControlador.componenteForm.nombre}" id="nombre" />
       <h:outputLabel value="Version" for="version" />
       <h:inputText value="#{componenteControlador.componenteForm.version}" id="version" /> 
       <h:outputLabel value="Tipo" for="tipo" />
       <h:inputText value="#{componenteControlador.componenteForm.tipo}" id="tipo" />   
       <h:outputLabel value="Extension" for="extension" />
       <h:inputText value="#{componenteControlador.componenteForm.extension}" id="extension" />    
      </h:panelGrid>
       <h:commandButton value="Modificar" action="#{componenteControlador.modificarComponente(componenteControlador.componenteForm)}" rendered="#{componenteControlador.accion == 'modificar'}">
        <f:param name="accion" value="#{componenteControlador.accion}" />
       </h:commandButton>
       <h:commandButton value="Registrar" action="#{componenteControlador.registrarComponente}" rendered="#{componenteControlador.accion != 'modificar'}"/>
       <br />
       <h:commandLink value="Ver Lista de componentes" action="#{componenteControlador.verListaComponentes}" />
     </h:form>
    </h:body>
    </html>
    

    1. En esta página mostraremos la bienvenida al usuario donde al hacer #{componenteControlador.mensaje} con sus respectivos tags de jsf 
    2. El link para poder salir: (usuarioControlador.salir)
    3. Mostramos el título de la página dependiendo si lo que queremos hacer es Agregar o modificar un componente a traves de la propiedad rendered , si componenteControlador.accion == 'modificar' muestro el título de Modificar y caso contrario la de Agregar.
    4. Con #{componenteControlador.error} mostramos los errores en el caso que existan de color rojo.
    5. Finalmente agregamos un formulario para que puedan llenarse los datos necesarios del componente a registrar (componenteForm) y al hacer submit vaya al action respectivo #{componenteControlador.registrarComponente que posteriormente me enviará a la página respectiva de error o éxito según los datos ingresados. Tener en cuenta que en el caso que queramos modificar el componente necesitamos el id pero no queremos que se muestre en la página, entonces insertamos de modo oculto dependiendo si se trata de una modificación o no validad por el rendered con el comnado tag inputHidden. En el botón de modificar tenemos que pasarle el parámetro de la acción que se está haciendo ya que el controlador ser de tipo Request probablemente haya perdido los datos y/o reiniciado por lo que pasaremos el parametro de la acción que se está haciendo a partir de: <f:param name="accion" value="#{componenteControlador.accion}" /> dentro del comando commandButton.
    Modificamos:
    /ProyectoJSFTutorial-WEB/WebContent/resources/css/estiloTabla.css

    .componenteTable{   
     border-collapse:collapse;
     border:1px solid #000000;
    }
     
    .componenteTableHeader{
     text-align:center;
     background:none repeat scroll 0 0 orange;
     border-bottom:1px solid #BBBBBB;
     padding:16px;
    }
     
    .componenteTableOddRow{
     text-align:center;
     background:none repeat scroll 0 0 #FFFFFFF;
     border-top:1px solid #BBBBBB;
    }
     
    .componenteTableEvenRow{
     text-align:center;
     background:none repeat scroll 0 0 #F9F9F9;
     border-top:1px solid #BBBBBB;
    }
    

    Que nos servirá para darle formato a nuestras tablas. Tener en cuenta que con los tags de jsf es mas facil definir css's para dar formato a algunos objeto como las tablas que darles formato directamente con el style.
    Normalmente los ficheros css que definamos en las páginas se buscarán dentro de la carpeta WebContent/resource/css motivo por el cual las incluimos en la estructura del proyecto.

    Finalmente editamos nuestra página para visualizar la lista de componentes:

    /ProyectoJSFTutorial-WEB/WebContent/pages/mostrarComponentes.xhtml

    <!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:f="http://java.sun.com/jsf/core">
    
    <h:head>
     <h:outputStylesheet library="css" name="estiloTabla.css" />
     <title>Tutorial JSF by Victor Elliott Humala</title>
    </h:head>
    <h:body>
     <h2>Lista de componentes</h2>
     <h:form>
      <h:dataTable value="#{componenteControlador.componenteLista}"
       var="componente" styleClass="componenteTable"
       headerClass="componenteTableHeader"
       rowClasses="componenteTableOddRow,componenteTableEvenRow">
     
       <h:column>
        <!-- column header -->
        <f:facet name="header">Nombre</f:facet>
             #{componente.nombre}
          </h:column>
       <h:column>
        <f:facet name="header">Version</f:facet>
             #{componente.version}
          </h:column>      
       <h:column>
        <f:facet name="header">Tipo</f:facet>
             #{componente.tipo}
          </h:column>
       <h:column>
        <f:facet name="header">Extensión</f:facet>
             #{componente.extension}
          </h:column>
       <h:column>
        <f:facet name="header">Modificar</f:facet>
               <h:commandLink value="Modificar" action="#{componenteControlador.volverModificarComponente(componente.id)}" />
          </h:column>
       <h:column>
        <f:facet name="header">Eliminar</f:facet>
             <h:commandLink value="Eliminar" action="#{componenteControlador.eliminarComponente(componente.id)}" />
          </h:column>          
      </h:dataTable> 
      <h:commandLink value="Agregar otro componente" action="#{componenteControlador.volverComponente}" />
     </h:form>
    </h:body>
    </html>
    

    1. Indicamos que vamos a usar los estilos del css: estiloTabla.css que como indiqué tienen que ser ubicados en: WebContent/resource/css
    2. Definimos la tabla a usar con sus respectivos estilos.
    3. Nos recorremos la lista #{componenteControlador.componenteLista} y pintamos los datos con sus respectivos links para modificar o eliminar (percatarse como pasamos los parametros de id).
    4. Creamos una referencia h:commandLink para poder volver al Action: #{componenteControlador.volverComponente}. Tener en cuenta que solo nos redirigirá a una página y h:commandLink debe estar dentro de un form así no haya datos para ingresar. Existen otras opciones para poder hacer esto sin utilizar h:commandLink pero lo uso por que me resulta interesante este tipo de link por que si quisiera podría hacer otras cosas antes de ir a la página que deseo, por lo pronto servirá para nuestro objetivo final.
    Ahora ya tenemos nuestros 2 proyectos principales pero aun necesitamos un proyecto para poder hacerlos funcionar, ya que independientemente no son nada y no se podrán ejecutar.

    Creamos un EAP File -> New -> Enterprise Application Project:
    1. Project Name: ProyectoEJBTutorial-Enterprise
    2. Target runtime: JBoss 7.1 Runtime
    3. EAR version: 6.0
    4. Configuration: Default
    Tal como podemos ver en la imagen:


    Damos Next y en la siguiente pantalla seleccionamos nuestros proyectos ProyectoEJBTutorial-EJB y ProyectoJSFTutorial-WEB y damos click en Finish.
    Ahora ya estamos listos para deployar nuestro proyecto. Vamos al servidor: click derecho -> Add and Remove -> Nos aseguramos que los proyectos EJB ni WEB se encuentren agregados y agregamos el proyecto ProyectoEJBTutorial-Enterprise y Finish.
    Si hemos hecho todo bien no debería salir ningun error en el log de la consola solo que se han generado correctamente nuestros EJB:

    17:38:26,555 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named UsuarioSessionBean in deployment unit subdeployment "ProyectoEJBTutorial-EJB.jar" of deployment "ProyectoEJBTutorial-Enterprise.ear" are as follows:
    
     java:global/ProyectoEJBTutorial-Enterprise/ProyectoEJBTutorial-EJB/UsuarioSessionBean!com.victor.elliott.humala.negocio.UsuarioInterfazLocal
     java:app/ProyectoEJBTutorial-EJB/UsuarioSessionBean!com.victor.elliott.humala.negocio.UsuarioInterfazLocal
     java:module/UsuarioSessionBean!com.victor.elliott.humala.negocio.UsuarioInterfazLocal
     java:global/ProyectoEJBTutorial-Enterprise/ProyectoEJBTutorial-EJB/UsuarioSessionBean
     java:app/ProyectoEJBTutorial-EJB/UsuarioSessionBean
     java:module/UsuarioSessionBean
    
    17:38:26,564 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named ComponenteSessionBean in deployment unit subdeployment "ProyectoEJBTutorial-EJB.jar" of deployment "ProyectoEJBTutorial-Enterprise.ear" are as follows:
    
     java:global/ProyectoEJBTutorial-Enterprise/ProyectoEJBTutorial-EJB/ComponenteSessionBean!com.victor.elliott.humala.negocio.ComponenteInterfazRemota
     java:app/ProyectoEJBTutorial-EJB/ComponenteSessionBean!com.victor.elliott.humala.negocio.ComponenteInterfazRemota
     java:module/ComponenteSessionBean!com.victor.elliott.humala.negocio.ComponenteInterfazRemota
     java:jboss/exported/ProyectoEJBTutorial-Enterprise/ProyectoEJBTutorial-EJB/ComponenteSessionBean!com.victor.elliott.humala.negocio.ComponenteInterfazRemota
     java:global/ProyectoEJBTutorial-Enterprise/ProyectoEJBTutorial-EJB/ComponenteSessionBean
     java:app/ProyectoEJBTutorial-EJB/ComponenteSessionBean
     java:module/ComponenteSessionBean
    

    Finalmente hacemos click derecho en ProyectoEJBTutorial-Enterprise -> Run As -> Run on server y veremos las siguientes pantallas: 





    El código de los proyecto os lo podéis bajar del siguiente link

    ProyectosEJBJSFTutorial

    domingo, 5 de enero de 2014

    - JSF 2.2 con migración de anotaciones de managed beans a anotaciones con CDI

    En este tutorial describiré los pasos necesarios para realizar un proyecto JSF 2.2 con anotaciones de managed beans y luego como migrarlo a las anotaciones con CDI que ya es posible desde la versión 2.0 de JSF puesto que CDI es parte integral de Java EE 6 todo esto sin la herramienta de gestión y construcción MAVEN, lo cual quiere decir que obtendremos nosotros mismos las librerías necesarias para nuestros proyecto así como configuraremos nuestro entorno de desarrollo para que todos los componentes sean tomadas correctamente en nuestra aplicación. Ademas estamos usando anotaciones lo cual quiere decir que no configuraremos el comportamiento de nuestra aplicación a través del fichero faces-config.xml el cual eliminaremos.

    Introducción a JSF

    Es un framework MVC que simplifica principalmente la interacción de las interfaces con un usuario de cualquier tipo: Ordenador, PDA, Movil, etc etc en aplicaciones con tecnología JEE.  A traves de los Managed Bean se podrá interactuar con los eventos de los controles de la interfaz del cliente y poder enviarlas a las clases que se encuentran en el servidor de aplicaciones.




    1. Se realiza una petición a través de un cliente (Ordenador, Movil, PDA, etc etc).
    2. La petición es recibida por Contrlador que en este caso es "Faces Servlet"
    3. El Faces Servlet según la petición del cliente invocara el JSP, JSF, XHTML (Vista) que visualizará posteriormente el cliente.
    4. El Faces Servlet o el JSF invocará al Managed Bean (Modelo) para realizar la lógica necesaria para mostrar los datos que se necesiten en el JSP, JSF, XHTML.
    5. El Managed Bean podrá realizar la lógica necesaria ya sea interactuando con EJB, Spring, Hibernate etc etc, y asi obtener los datos necesarios para poder realizar su trabajo que es el de obtener los datos para poder mostrarlos en la página.
    6. Posteriormente el JSP o JSF es devuelto al cliente con la data requerida para poder ser utilizado.

    Proyecto en JSF 2.2

    1. Eclipse Kepler
    2. JBoss 7.1.1
    Como indiqué anteriormente no explicaré como se realiza la instalación del Eclipse con su respectivo JDK ni el  JBOSS por lo que se asume que ya tenéis el entorno instalado.

    Primero que todo creamos un proyecto WEB en el eclipse: File -> New -> Dynamic Web Project

    1. Project Name: ProyectoJSFTutorial
    2. Target runtime: JBoss 7.1 Runtime
    3. Dynamic web module version: 3.0
    4. Configuration: JavaServer Faces v2.2 Project
    Tal como se muestra: 



    Damos click en Finish y se habrá creado nuestro proyecto.
    Por ahora como vamos a usar anotaciones en nuestros Managed Beans y no vamos a realizar ningun tipo de reglas en la navegación ya que nosotros controlaremos ello desde los ManagedBean eliminaremos el xml faces-config.xml:
    eliminar /ProyectoJSFTutorial/WebContent/WEB-INF/faces-config.xml.
    Ahora configuramos nuestro descriptor de despliegue que si lo abrís debe estar ya configurado con los Faces Servlet(Controlador) pero agregaremos una entrada para indicar que nuestra página inicial será index.xhtml que posteriormente crearemos.y deberá quedar de la siguiente forma.

    /ProyectoJSFTutorial/WebContent/WEB-INF/web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
      <display-name>ProyectoJSFTutorial</display-name>
      <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
      </servlet-mapping>
      <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
      </welcome-file-list>
    </web-app>
    

    Ahora creamos los componentes necesarios para nuestro proyecto:
    En /ProyectoJSFTutorial/src creamos los paquetes

    1. com.victor.elliott.humala.controladores
    2. com.victor.elliott.humala.dao
    3. com.victor.elliott.humala.formulario
    Luego creamos las siguientes clases en los paquetes respectivos

      1. com.victor.elliott.humala.controladores -> ComponenteControlador.java
      2. com.victor.elliott.humala.controladores -> UsuarioControlador.java
      3. com.victor.elliott.humala.dao -> ComponenteDAO.java
      4. com.victor.elliott.humala.dao -> ComponenteDAOImpl.java
      5. com.victor.elliott.humala.formulario -> ComponenteForm.java
      6. com.victor.elliott.humala.formulario -> UsuarioForm.java
      Una vez creadas las clases creamos las paginas y css respectivos.

      1. Creamos primero que todo las carpetas pages y resources en /ProyectoJSFTutorial/WebContent/
      2. Creamos la carpeta css en /ProyectoJSFTutorial/WebContent/resources
      3. Creamos index.xhtml en /ProyectoJSFTutorial/WebContent
      4. Creamos login.xhtml en /ProyectoJSFTutorial/WebContent/pages
      5. Creamos agregarComponentes.xhtml en /ProyectoJSFTutorial/WebContent/pages
      6. Creamos mostrarComponentes.xhtml en /ProyectoJSFTutorial/WebContent/pages
      7. Creamos estiloTabla.css en /ProyectoJSFTutorial/WebContent/resources/css
      Una vez creadas nuestras clases, paginas y componentes que usaremos, la estructura de proyecto debe de quedar de la siguiente manera:


      Ahora si podemos empezar a codificar nuestro proyecto, Hay que tener en cuenta que las librerías de JSF 2.2 ya están embebidas dentro del RunTime de JBoss asi que no sera necesario descargar ninguna librería. 

      Primero que todo modificamos com.victor.elliott.humala.formulario.UsuarioForm que básicamente contendrá los atributos nombre y clave sus getter y setter respectivos y dos constructores.

      /ProyectoJSFTutorial/src/com/victor/elliott/humala/formulario/UsuarioForm.java

      package com.victor.elliott.humala.formulario;
      
      public class UsuarioForm{
      
       private String nombre;
       private String clave;
       
       
       public UsuarioForm(){
        this.nombre = "";
        this.clave = "";
       }
       public UsuarioForm(String nombre, String clave){
        this.nombre = nombre;
        this.clave = clave;
       }
       public String getNombre() {
        return nombre;
       }
       public void setNombre(String nombre) {
        this.nombre = nombre;
       }
       public String getClave() {
        return clave;
       }
       public void setClave(String clave) {
        this.clave = clave;
       }
      }
      

      Ahora modificamos
      /ProyectoJSFTutorial/src/com/victor/elliott/humala/controladores/UsuarioControlador.java

      package com.victor.elliott.humala.controladores;
      
      import javax.faces.bean.ManagedBean;
      import javax.faces.bean.SessionScoped;
      import com.victor.elliott.humala.formulario.UsuarioForm;
      
      @ManagedBean
      @SessionScoped
      public class UsuarioControlador {
       private UsuarioForm usuario=new UsuarioForm("Victor", "Elliott");
       private UsuarioForm usuarioForm=new UsuarioForm();
       private String error;
       private String mensaje;
       
       public String verificarUsuario() {
        System.out.println("Entro a verificarUsuario");
        if(usuario.getNombre().equals(usuarioForm.getNombre())&&usuario.getClave().equals(usuarioForm.getClave())){
         mensaje= "Usuario Correcto: "+usuarioForm.getNombre();
         return "agregarComponentes";   
        }
        else if("".equals(usuarioForm.getNombre())||"".equals(usuarioForm.getClave())){
         error="Los datos del usuario no pueden estar vacios";
         return "login";
        }
        else{
         error="El usuario no está registrado en el sistema";
         return "login";
        }
       }
       public UsuarioForm getUsuarioForm() {
        return usuarioForm;
       }
       public void setUsuarioForm(UsuarioForm usuarioForm) {
        this.usuarioForm = usuarioForm;
       }
       public String getError() {
        return error;
       }
       public void setError(String error) {
        this.error = error;
       }
       public String getMensaje() {
        return mensaje;
       }
       public void setMensaje(String mensaje) {
        this.mensaje = mensaje;
       }
      }
      


      1. Todos los import javax.faces son necesarios para la implementacion del ManagedBean
      2. Indicamos la anotación @ManagedBean para hacerle saber a la aplicación que se trata de un elemento de modelo que se encargará de gestionar los datos de las paginas que lo necesiten. Tener en cuenta que normalmente se usaría @ManagedBean(name="nombredelBean") pero al no ponerle el nombre automáticamente coge el nombre de la clase y le coloca la minúscula inicialmente es decir que @ManagedBean = @ManagedBean(name="usuarioControlador")
      3. Indicamos la anotación @SessionScoped para indicarle a la aplicación que se trata de un ManagedBean de session es decir que persistirá hasta que se termine la sesión o se cierre el browser que está utilizando el cliente. Hacemos esto por que luego recuperaremos el nombre del usuario el cual necesitamos que persista. Existen otros tipos pero los mas importantes son @SessionScoped (persistencia en la sesión), @RequestScoped (persistencia durante el request), @ApplicationScoped (persistencia durante toda la aplicación, hasta que se para el servidor) y @Viewscoped (persistencia durante la vista, usada normalmente para peticiones AJAX)
      4. Declaramos UsuarioForm usuario para determinar cual será el único usuario con el que se podrá ingresar al sistema.
      5. Declaramos UsuarioForm usuarioForm=new UsuarioForm() con sus respectivos getter y setter puesto que será un objeto que interactuará con nuestras paginas y tenemos que inicializarlo con el constructor para que en un principio sus datos aparezcan vacíos y no haya errores de nullpointer.
      6. Los atributos error y mensaje con sus respectivos getter y setter son declarados para enviar el mensaje respectvio a la pagina en caso de error y/o éxito.
      7. Creamos el método verificarUsuario que validará los datos ingresados del usuario y en caso de exito retornare la página a la cual me dirigiré "agregarComponentes" que la aplicación interpretará como agregarComponentes.xhtml con su respectivo mensaje de éxito y en caso de error volveré a la misma página "login" que la aplicación interpretará como "login.xhtml" con su respectivo mensaje de error.
      Ahora modifiquemos las páginas:
      /ProyectoJSFTutorial/WebContent/index.xhtml

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <meta http-equiv="Refresh" content= "0; URL=faces/pages/login.xhtml"/>
      

      Donde básicamente le indicamos al index.xhtml que es nuestra página inicial que se dirija a la página principal login.xhtml a través de la etiqueta META.


      • /ProyectoJSFTutorial/WebContent/pages/login.xhtml


      <!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:f="http://java.sun.com/jsf/core">
      
      <h:head>
       <title>Tutorial JSF by Victor Elliott Humala</title>
      </h:head>
      <h:body>
       <h:outputText style="color:red" value="#{usuarioControlador.error}" />
       <h:form>
        <h:panelGrid columns="2">
         <h:outputLabel value="Nombre" for="nombre" />
         <h:inputText value="#{usuarioControlador.usuarioForm.nombre}" id="nombre" />
         <h:outputLabel value="Clave" for="clave" />
         <h:inputText value="#{usuarioControlador.usuarioForm.clave}" id="clave" />   
         <h:commandButton value="Ingresar" action="#{usuarioControlador.verificarUsuario}"/>
        </h:panelGrid>
       </h:form>
      </h:body>
      </html>
      

      1. Declaramos la librería para nuestros tags de jsf (:ui, :h y :f)
      2. Mostramos en rojo el error usuarioControlador.error en caso que exista.
      3. Finalmente agregamos un form con los tag de jsf para que puedas llenarse los datos necesarios del usuario (usuarioForm) y al hacer submit vaya al action respectivo usuarioControlador.verificarUsuario.

      • /ProyectoJSFTutorial/WebContent/pages/agregarComponentes.xhtml


      <!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:f="http://java.sun.com/jsf/core">
      
      <h:head>
       <title>Tutorial JSF by Victor Elliott Humala</title>
      </h:head>
      <h:body>
       <h4><h:outputText style="color:blue" value="#{usuarioControlador.mensaje}" /></h4>
      </h:body>
      </html>
      

      Ahora ya estamos listos para ejecutar nuestro proyecto en el servidor JBoss, antes de ello verificar que no haya ningún error de compilación y una vez ejecutado en el servidor ningún error de ejecución. Si todo esta bien podrán visualizar las siguientes páginas:




      Ahora continuo con la segunda parte del tutorial.
      Una vez que ya tenemos el login realizado, nos disponemos a crear una lista de componentes que cargaremos una a una para luego poder verlas todas juntas.

      /ProyectoJSFTutorial/src/com/victor/elliott/humala/formulario/ComponenteForm.java

      package com.victor.elliott.humala.formulario;
      
      public class ComponenteForm {
       private String nombre;
       private String version;
       private String tipo;
       private String extension;
       
       public String getNombre() {
        return nombre;
       }
       public void setNombre(String nombre) {
        this.nombre = nombre;
       }
       public String getVersion() {
        return version;
       }
       public void setVersion(String version) {
        this.version = version;
       }
       public String getTipo() {
        return tipo;
       }
       public void setTipo(String tipo) {
        this.tipo = tipo;
       }
       public String getExtension() {
        return extension;
       }
       public void setExtension(String extension) {
        this.extension = extension;
       }
      
      }
      
      Clase que contiene todos los datos que deseo guardar de un componente. Finalmente modifico los action:
      /ProyectoJSFTutorial/src/com/victor/elliott/humala/dao/ComponenteDAO.java

      package com.victor.elliott.humala.dao;
      
      import com.victor.elliott.humala.formulario.ComponenteForm;
      import java.util.List;
      
      public interface ComponenteDAO {
       public void addComponente(ComponenteForm componente);
       public List<ComponenteForm> getComponente();
      }
      

      Aqui simplemente estamos creando un DAO de tipo Interface donde solo declaramos dos métodos addComponente para agregar el componente y getComponente para recuperar todos los componentes.
      Ahora creamos su implementación respectiva modificando:

      /ProyectoJSFTutorial/src/com/victor/elliott/humala/dao/ComponenteDAOImpl.java

      package com.victor.elliott.humala.dao;
      
      import java.util.ArrayList;
      import java.util.List;
      import com.victor.elliott.humala.formulario.ComponenteForm;
      
      public class ComponenteDAOImpl implements ComponenteDAO {
       private static List<ComponenteForm> listaComponentes=new ArrayList<ComponenteForm>();
       @Override
       public void addComponente(ComponenteForm componente) {
        listaComponentes.add(componente);
       }
      
       @Override
       public List<ComponenteForm> getComponente() {
        return listaComponentes;
       }
      }
      

      De esta forma implementamos los métodos de la interface primero declarando un atributo estático List<ComponenteForm> listaComponentes que me guardará todos los datos que ingrese en mi lista y no se perderá y luego con los metodos addComponente agrego un componente a la lista y con getComponente recupero toda la lista estática.
      Modificamos:

      /ProyectoJSFTutorial/src/com/victor/elliott/humala/controladores/ComponenteControlador.java

      package com.victor.elliott.humala.controladores;
      
      import java.util.List;
      
      import javax.annotation.PostConstruct;
      import javax.faces.bean.ManagedBean;
      import javax.faces.bean.ManagedProperty;
      import javax.faces.bean.RequestScoped;
      
      import com.victor.elliott.humala.dao.ComponenteDAO;
      import com.victor.elliott.humala.dao.ComponenteDAOImpl;
      import com.victor.elliott.humala.formulario.ComponenteForm;
      
      @ManagedBean
      @RequestScoped
      public class ComponenteControlador {
       private ComponenteForm componenteForm=new ComponenteForm();
       private ComponenteDAO componenteDAO= new ComponenteDAOImpl();
       private List<ComponenteForm> componenteLista;
       @ManagedProperty("#{usuarioControlador}")
       private UsuarioControlador usuarioControlador;
       private String error;
       private String mensaje;
       
       @PostConstruct
       public void init(){
        mensaje= usuarioControlador.getMensaje();
       }
       public String registrarComponente() {
        if("".equals(componenteForm.getNombre())||"".equals(componenteForm.getTipo())||"".equals(componenteForm.getVersion())||"".equals(componenteForm.getExtension())){
         error="Los datos del componente no pueden estar vacios";
         return "agregarComponentes";
        }
        else{
         componenteDAO.addComponente(componenteForm);
         System.out.println("Componente guardado");
         componenteLista=componenteDAO.getComponente();
         System.out.println("Obtiene la lista");
         return "mostrarComponentes";
        }
       }
       
       public String volverComponente() {
        System.out.println("Volver Componente");
        return "agregarComponentes";
       }
       public ComponenteForm getComponenteForm() {
        return componenteForm;
       }
       public void setComponenteForm(ComponenteForm componenteForm) {
        this.componenteForm = componenteForm;
       }
      
       public UsuarioControlador getUsuarioControlador() {
        return usuarioControlador;
       }
       public void setUsuarioControlador(UsuarioControlador usuarioControlador) {
        this.usuarioControlador = usuarioControlador;
       }
       public List<ComponenteForm> getComponenteLista() {
        return componenteLista;
       }
       public void setComponenteLista(List<ComponenteForm> componenteLista) {
        this.componenteLista = componenteLista;
       }
       public String getError() {
        return error;
       }
       public void setError(String error) {
        this.error = error;
       }
       public String getMensaje() {
        return mensaje;
       }
       public void setMensaje(String mensaje) {
        this.mensaje = mensaje;
       }
      }
      

      1. Todos los import javax.faces son necesarios para la implementacion del ManagedBean
      2. Indicamos la anotación @ManagedBean para hacerle saber a la aplicación que se trata de un elemento de modelo que se encargará de gestionar los datos de las paginas que lo necesiten. Tener en cuenta que normalmente se usaría @ManagedBean(name="nombredelBean") pero al no ponerle el nombre automáticamente coge el nombre de la clase y le coloca la minúscula inicialmente es decir que @ManagedBean = @ManagedBean(name="usuarioControlador")
      3. Indicamos la anotación @RequestScoped para indicarle a la aplicación que se trata de un ManagedBean de request es decir que persistirá hasta que se termine el request y ante un nuevo request se creará otro. Hacemos esto por que los datos del componente solo se utilizarán para guardarlos y luego no me interesa que persista. Existen otros tipos pero los mas importantes son @SessionScoped (persistencia en la sesión), @RequestScoped (persistencia durante el request), @ApplicationScoped (persistencia durante toda la aplicación, hasta que se para el servidor) y @Viewscoped (persistencia durante la vista, usada normalmente para peticiones AJAX)
      4. Declaramos ComponenteForm componenteForm=new ComponenteForm() con sus respectivos getter y setter puesto que será un objeto que interactuará con nuestras paginas y tenemos que inicializarlo con el constructor para que en un principio sus datos aparezcan vacíos y no haya errores de nullpointer.
      5. Declaramos ComponenteDAO componenteDAO que se encargará de gestionar mi lista de componentes y hacer que persista.
      6. Declaramos la lista private List<ComponenteForm> componenteLista con sus respectivos getter y setter para poder interactuar con la página que mostrará la lista de componentes.
      7. Con la anotación @ManagedProperty("#{usuarioControlador}") estamos indicando que vamos a recuperar el ManagedBean usuarioControlador (recordais que era de session por lo que las propiedades que contiene deberían persistir) y asignarselo a la propiedad usuarioControlador que deberá tener sus respectivos getter y setter, si no los ponen tendrán un error a la hora de deployar.
      8. Los atributos error y mensaje con sus respectivos getter y setter son declarados para enviar el mensaje respectivo a la pagina en caso de error y/o éxito.
      9. La anotación @PostConstruct me sirve para determinar algunos valores antes que se invoque a la clase a través del método init donde lo único que hacemos es llenar el mensaje que aparecerá al inicio de los componentes. Si no hacemos esto el mensaje aparecerá vacio puesto que no se habrá invocado a ningun metodo inicialmente para tener el mensaje definido.
      10. Creamos el método registrarComponente que validará los datos ingresados del componente y en caso de exito guardaré el componente en la lista y luego recuperare la lista con el DAO, luego retornare la página a la cual me dirigiré "mostrarComponentes" que la aplicación interpretará como mostrarComponentes.xhtml y en caso de error volveré a la misma página "agregarComponentes" que la aplicación interpretará como "agregarComponentes.xhtml" con su respectivo mensaje de error.
      11. Creamos el método volverComponente que lo único que hará será ir a la página agregarComponentes.xhtml a traves del return "agregarComponentes".
      Modificamos ahora las páginas:
      /ProyectoJSFTutorial/WebContent/pages/agregarComponentes.xhtml

      <!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:f="http://java.sun.com/jsf/core">
      
      <h:head>
       <title>Tutorial JSF by Victor Elliott Humala</title>
      </h:head>
      <h:body>
       <h4><h:outputText style="color:blue" value="#{componenteControlador.mensaje}" /></h4> 
       <h2><h:outputText style="color:black" value="Agregar Componente" /></h2>
       <h4><h:outputText style="color:red" value="#{componenteControlador.error}" /></h4>
       <h:form>
        <h:panelGrid columns="2">
         <h:outputLabel value="Nombre" for="nombre" />
         <h:inputText value="#{componenteControlador.componenteForm.nombre}" id="nombre" />
         <h:outputLabel value="Version" for="version" />
         <h:inputText value="#{componenteControlador.componenteForm.version}" id="version" /> 
         <h:outputLabel value="Tipo" for="tipo" />
         <h:inputText value="#{componenteControlador.componenteForm.tipo}" id="tipo" />   
         <h:outputLabel value="Extension" for="extension" />
         <h:inputText value="#{componenteControlador.componenteForm.extension}" id="extension" />    
        </h:panelGrid>
        <h:commandButton value="Agregar" action="#{componenteControlador.registrarComponente}"/>
       </h:form>
      </h:body>
      </html>
      

      1. En esta página mostraremos la bienvenida al usuario donde al hacer #{componenteControlador.mensaje} con sus respectivos tags de jsf 
      2. Con #{componenteControlador.error} mostramos los errores en el caso que existan de color rojo.
      3. Finalmente agregamos un formulario para que puedan llenarse los datos necesarios del componente a registrar (componenteForm) y al hacer submit vaya al action respectivo #{componenteControlador.registrarComponente que posteriormente me enviará a la página respectiva de error o éxito según los datos ingresados.
      Modificamos:
      /ProyectoJSFTutorial/WebContent/resources/css/estiloTabla.css

      .componenteTable{   
       border-collapse:collapse;
       border:1px solid #000000;
      }
       
      .componenteTableHeader{
       text-align:center;
       background:none repeat scroll 0 0 orange;
       border-bottom:1px solid #BBBBBB;
       padding:16px;
      }
       
      .componenteTableOddRow{
       text-align:center;
       background:none repeat scroll 0 0 #FFFFFFF;
       border-top:1px solid #BBBBBB;
      }
       
      .componenteTableEvenRow{
       text-align:center;
       background:none repeat scroll 0 0 #F9F9F9;
       border-top:1px solid #BBBBBB;
      }
      

      Que nos servirá para darle formato a nuestras tablas. Tener en cuenta que con los tags de jsf es mas facil definir css's para dar formato a algunos objeto como las tablas que darles formato directamente con el style.
      Normalmente los ficheros css que definamos en las páginas se buscarán dentro de la carpeta WebContent/resource/css motivo por el cual las incluimos en la estructura del proyecto.

      Finalmente creamos nuestra página para visualizar la lista de componentes:

      /ProyectoJSFTutorial/WebContent/pages/mostrarComponentes.xhtml

      <!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:f="http://java.sun.com/jsf/core">
      
      <h:head>
       <h:outputStylesheet library="css" name="estiloTabla.css"  />
       <title>Tutorial JSF by Victor Elliott Humala</title>
      </h:head>
      <h:body>
      <h2>Lista de componentes</h2>
       <h:dataTable value="#{componenteControlador.componenteLista}" var="componente" 
        styleClass="componenteTable"
             headerClass="componenteTableHeader"
             rowClasses="componenteTableOddRow,componenteTableEvenRow">
      
        <h:column>
         <!-- column header -->
         <f:facet name="header">Nombre</f:facet>
              #{componente.nombre}
           </h:column>
        <h:column>
         <f:facet name="header">Tipo</f:facet>
              #{componente.tipo}
           </h:column>
        <h:column>
         <f:facet name="header">Version</f:facet>
              #{componente.version}
           </h:column>
        <h:column>
         <f:facet name="header">Extensión</f:facet>
              #{componente.extension}
           </h:column>
       </h:dataTable>
       <h:form><h:commandLink value="Agregar otro componente" action="#{componenteControlador.volverComponente}" /></h:form>
      </h:body>
      </html>
      

      1. Indicamos que vamos a usar los estilos del css: estiloTabla.css que como indiqué tienen que ser ubicados en: WebContent/resource/css
      2. Definimos la tabla a usar con sus respectivos estilos.
      3. Nos recorremos la lista #{componenteControlador.componenteLista} y pintamos los datos respectivos
      4. Creamos una referencia h:commandLink para poder volver al Action: #{componenteControlador.volverComponente}. Tener en cuenta que que solo nos redirigirá a una página y debe estar dentro de un form asi no haya datos para ingresar. Existen otras opciones para poder hacer esto si utilizar h:commandLink pero lo uso por que me resulta interesante este tipo de botón por que si quisiera podría hacer otras cosas antes de ir a la página que deseo, por lo pronto servirá para nuestro objetivo final.
      Si has compilado todo bien y no hay problemas de ejecución te deberían salir las siguientes páginas después del Login y después de haber agregado varios componentes.




      Ahora migraremos nuestra aplicación JSF 2.2 creada con anotaciones de ManageBean por anotaciones e inyecciones de CDI (Contexts and Dependency Injection).

      Proyecto en JSF 2.2 con CDI

      Primero que todo creamos un proyecto WEB en el eclipse: File -> New -> Dynamic Web Project
      1. Project Name: ProyectoJSF-CDI-Tutorial
      2. Target runtime: JBoss 7.1 Runtime
      3. Dynamic web module version: 3.0
      4. Configuration: JavaServer Faces v2.2 Project
      Tal como se muestra:


      Damos click en Modify en Configuration: y seleccionamos CDI 1.0 tal como se muestra en la pantalla:


      Damos click en Ok y en Finish

      Veremos que a diferencia del proyecto anterior se ha creado un nuevo fichero de configuración en WEB-INF llamado beans.xml, este fichero a pesar de que no lo vamos a utilizar en este tutorial no podemos borrarlo por que es un componente imprescindible en CDI, sin embargo faces-config.xml si lo eliminaremos por que no crearemos reglas de navegación ya que lo haremos manualmente y con anotaciones dentro de nuestros ManagedBeans.

      Ahora como el propósito es migrar la aplicación a CDI, primero que todo copiamos todas las clases con sus paquetes respectivos y páginas xhtml, asi como el css asociado en nuestro nuevo proyecto. Ademas no olviden modificar el descriptor de depliegue para indicar que nuestra página inicial será index.xhtml y deberá de quedar de la siguiente manera:

      /ProyectoJSFTutorial/WebContent/WEB-INF/web.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
        <display-name>ProyectoJSF-CDI-Tutorial</display-name>
        <servlet>
          <servlet-name>Faces Servlet</servlet-name>
          <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
          <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
          <servlet-name>Faces Servlet</servlet-name>
          <url-pattern>/faces/*</url-pattern>
        </servlet-mapping>
        <welcome-file-list>
          <welcome-file>faces/index.xhtml</welcome-file>
        </welcome-file-list>
      </web-app>
      


       Finalmente la estructura del proyecto deberá quedar de la siguiente forma:


      Para verificar que vamos a empezar bien la migración ejecutemos nuestra aplicación y debe de funcionar exactamente como la anterior. Una vez hayan comprobado que todo va correctamente nos dispondremos a modificar los controladores (ManagedBean) que finalmente será lo único que que modificaremos para este tipo de migración:

      La clase UsuarioControlador:

      1. Tendremos que reemplazar import javax.faces.bean.SessionScoped; por import javax.enterprise.context.SessionScoped;
      2. Reemplazar @ManagedBean por @Named eliminando import javax.faces.bean.ManagedBean; e importando: import javax.inject.Named;
      3. Como ahora la anotación @SessionScoped proviene de javax.enterprise ese necesita que la clase sea serializable por lo que hacemos el implement respectivo UsuarioControlador implements Serializable.
      Para este controlador es lo único que necesitamos cambiar, al final deberá quedar:

      /ProyectoJSF-CDI-Tutorial/src/com/victor/elliott/humala/controladores/UsuarioControlador.java

      package com.victor.elliott.humala.controladores;
      
      import java.io.Serializable;
      import javax.enterprise.context.SessionScoped;
      import javax.inject.Named;
      
      import com.victor.elliott.humala.formulario.UsuarioForm;
      
      @Named
      @SessionScoped
      public class UsuarioControlador implements Serializable{
       private static final long serialVersionUID = 1L;
       private UsuarioForm usuario=new UsuarioForm("Victor", "Elliott");
       private UsuarioForm usuarioForm=new UsuarioForm();
       private String error;
       private String mensaje;
       
       public String verificarUsuario() {
        System.out.println("Entro a verificarUsuario");
        if(usuario.getNombre().equals(usuarioForm.getNombre())&&usuario.getClave().equals(usuarioForm.getClave())){
         mensaje= "Usuario Correcto: "+usuarioForm.getNombre();
         return "agregarComponentes";   
        }
        else if("".equals(usuarioForm.getNombre())||"".equals(usuarioForm.getClave())){
         error="Los datos del usuario no pueden estar vacios";
         return "login";
        }
        else{
         error="El usuario no está registrado en el sistema";
         return "login";
        }
       }
       public UsuarioForm getUsuarioForm() {
        return usuarioForm;
       }
       public void setUsuarioForm(UsuarioForm usuarioForm) {
        this.usuarioForm = usuarioForm;
       }
       public String getError() {
        return error;
       }
       public void setError(String error) {
        this.error = error;
       }
       public String getMensaje() {
        return mensaje;
       }
       public void setMensaje(String mensaje) {
        this.mensaje = mensaje;
       }
      }
      

      Modificamos la clase ComponenteControlador
      1. Tendremos que reemplazar import javax.faces.bean.RequestScoped; por import javax.enterprise.context.RequestScoped;
      2. Reemplazar @ManagedBean por @Named eliminando import javax.faces.bean.ManagedBean; e importando: import javax.inject.Named;
      3. Reemplazar @ManagedProperty("#{usuarioControlador}") por simplemente @Inject eliminando los getter y setter de private UsuarioControlador usuarioControlador que ya no serán necesarios para esta aplicación. En consecuencia eliminar el import import javax.faces.bean.ManagedProperty; e importar import javax.inject.Inject;
      Al final deberá quedar:
      /ProyectoJSF-CDI-Tutorial/src/com/victor/elliott/humala/controladores/ComponenteControlador.java


      package com.victor.elliott.humala.controladores;
      
      import java.util.List;
      
      import javax.annotation.PostConstruct;
      import javax.enterprise.context.RequestScoped;
      
      import javax.inject.Inject;
      import javax.inject.Named;
      
      import com.victor.elliott.humala.dao.ComponenteDAO;
      import com.victor.elliott.humala.dao.ComponenteDAOImpl;
      import com.victor.elliott.humala.formulario.ComponenteForm;
      
      @Named
      @RequestScoped
      public class ComponenteControlador {
       private ComponenteForm componenteForm=new ComponenteForm();
       private ComponenteDAO componenteDAO= new ComponenteDAOImpl();
       private List<ComponenteForm> componenteLista;
       @Inject
       private UsuarioControlador usuarioControlador;
       private String error;
       private String mensaje;
       
       @PostConstruct
       public void init(){
        mensaje= usuarioControlador.getMensaje();
       }
       public String registrarComponente() {
        if("".equals(componenteForm.getNombre())||"".equals(componenteForm.getTipo())||"".equals(componenteForm.getVersion())||"".equals(componenteForm.getExtension())){
         error="Los datos del componente no pueden estar vacios";
         return "agregarComponentes";
        }
        else{
         componenteDAO.addComponente(componenteForm);
         System.out.println("Componente guardado");
         componenteLista=componenteDAO.getComponente();
         System.out.println("Obtiene la lista");
         return "mostrarComponentes";
        }
       }
       
       public String volverComponente() {
        System.out.println("Volver Componente");
        return "agregarComponentes";
       }
       public ComponenteForm getComponenteForm() {
        return componenteForm;
       }
       public void setComponenteForm(ComponenteForm componenteForm) {
        this.componenteForm = componenteForm;
       }
       public List<ComponenteForm> getComponenteLista() {
        return componenteLista;
       }
       public void setComponenteLista(List<ComponenteForm> componenteLista) {
        this.componenteLista = componenteLista;
       }
       public String getError() {
        return error;
       }
       public void setError(String error) {
        this.error = error;
       }
       public String getMensaje() {
        return mensaje;
       }
       public void setMensaje(String mensaje) {
        this.mensaje = mensaje;
       }
      }
      

      Ahora cuando deployen el proyecto verán en los log que a diferencia del anterior proyecto sin CDI aparecerá: Starting Services for CDI deployment: ProyectoJSF-CDI-Tutorial.war

      Ahora cuando ejecutemos el proyecto deberá funcionar perfectamente como en el caso anterior.

      El código de los proyecto os lo podéis bajar del siguiente link

      ProyectosJSFTutorial