Skip to content

7. Aplicación de ejemplo-04: rdvmedecins-pf-spring

7.1. La migración

Ahora vamos a portar la aplicación anterior a un entorno Spring / Tomcat:

Nos basaremos en dos aplicaciones ya escritas. Utilizaremos:

  • los componentes [DAO] y [JPA] de la versión 02 JSF / Spring,
  • la capa [web] / Primefaces de la versión 03 PF / EJB,
  • los archivos de configuración de Spring de la versión 02

Aquí estamos realizando un trabajo similar al que se llevó a cabo para portar la aplicación JSF2 / EJB / Glassfish a un entorno JSF2 / Spring Tomcat. Por lo tanto, daremos menos explicaciones. El lector puede, si lo necesita, consultar esa adaptación.

Colocamos todos los proyectos necesarios para la adaptación en una nueva carpeta [rdvmedecins-pf-spring] [1]:

  • [mv-rdvmedecins-spring-dao-jpa]: las capas [DAO] y [JPA] de la versión 02 JSF / Spring,
  • [mv-rdvmedecins-spring-metier]: la capa [métier] de la versión 02 JSF / Spring,
  • [mv-rdvmedecins-pf]: la capa [web] de la versión 03 de PrimeFaces / EJB,
  • en [2], las cargamos en NetBeans,
  • en [3], las dependencias del proyecto web ya no son correctas:
    • las dependencias de las capas [DAO], [JPA] y [métier] deben modificarse para que ahora apunten a los proyectos Spring;
    • el servidor Glassfish proporcionaba las bibliotecas de JSF. Esto ya no ocurre con el servidor Tomcat. Por lo tanto, es necesario agregarlas a las dependencias.

El proyecto [web] evoluciona de la siguiente manera:

El archivo [pom.xml] de la capa [web] cuenta ahora con las siguientes dependencias:


<dependencies>    
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>mv-rdvmedecins-spring-metier</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>com.sun.faces</groupId>
      <artifactId>jsf-api</artifactId>
      <version>2.1.7</version>
    </dependency>
    <dependency>
      <groupId>com.sun.faces</groupId>
      <artifactId>jsf-impl</artifactId>
      <version>2.1.7</version>
    </dependency>
    <dependency>  
      <groupId>org.primefaces</groupId>  
      <artifactId>primefaces</artifactId>  
      <version>3.3</version>  
    </dependency>
  </dependencies>

Aparecen errores. Estos se deben a las referencias EJB de la capa [web]. Analicemos primero el bean [Application]:

Eliminamos todas las líneas erróneas debido a paquetes que faltan, renombramos [IMetier] (ese es su nombre en la capa [métier] de Spring) como la interfaz [IMetierLocal] y utilizamos Spring para instanciarla:


package beans;

import java.util.ArrayList;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import rdvmedecins.metier.service.IMetier;

public class Application {

  // capa de negocio
  private IMetier metier;
  // errores
  private List<Erreur> erreurs = new ArrayList<Erreur>();
  private Boolean erreur = false;

  public Application() {
    try {
      // instanciación de la capa [métier]
      ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config-metier-dao.xml");
      metier = (IMetier) ctx.getBean("metier");
    } catch (Throwable th) {
      // se registra el error
      erreur = true;
      erreurs.add(new Erreur(th.getClass().getName(), th.getMessage()));
      while (th.getCause() != null) {
        th = th.getCause();
        erreurs.add(new Erreur(th.getClass().getName(), th.getMessage()));
      }
      return;
    }
  }

  // getter
  public Boolean getErreur() {
    return erreur;
  }

  public List<Erreur> getErreurs() {
    return erreurs;
  }

  public IMetier getMetier() {
    return metier;
  }
}
  • líneas 20-21: instanciación de la capa [métier] a partir del archivo de configuración de Spring. Este archivo es el que utilizan las capas [métier] y [1]. Lo copiamos en el proyecto web [2]:
  • líneas 22-31: manejamos una posible excepción y guardamos su pila.

Una vez hecho esto, el bean [Application] ya no presenta errores. Veamos ahora los beans [Form], [1] y [2]:

Eliminamos todas las líneas con errores (import y anotaciones) debido a paquetes que faltan. Esto es suficiente para eliminar todos los errores de [3].

Además, hay que agregar en el código del bean [Form] el getter y el setter del campo


  // bean de la aplicación
private Application application;

Algunas de las anotaciones eliminadas en los beans [Application] y [Form] declaraban las clases como beans con un determinado alcance. Ahora, esta configuración se realiza en el siguiente archivo [faces-config.xml] [4]:


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

<!-- =========== FULL CONFIGURATION FILE ================================== -->

<faces-config version="2.0"
              xmlns="http://java.sun.com/xml/ns/javaee" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">

  <application>
    <!-- el archivo de mensajes -->
    <resource-bundle>
      <base-name>
        messages
      </base-name>
      <var>msg</var>
    </resource-bundle>
    <message-bundle>messages</message-bundle>
  </application>
    <!-- el bean applicationBean -->
  <managed-bean>
    <managed-bean-name>applicationBean</managed-bean-name>
    <managed-bean-class>beans.Application</managed-bean-class>
    <managed-bean-scope>application</managed-bean-scope>
  </managed-bean>
    <!-- el bean de formulario -->
  <managed-bean>
    <managed-bean-name>form</managed-bean-name>
    <managed-bean-class>beans.Form</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
      <property-name>application</property-name>
      <value>#{applicationBean}</value>
    </managed-property>
  </managed-bean>
</faces-config>

Normalmente, la migración ya está terminada. Sin embargo, aún nos quedan algunos detalles por resolver. Podemos intentar ejecutar la aplicación web.

Dejamos que el lector pruebe esta nueva aplicación. Podemos mejorarla ligeramente para manejar el caso en que la inicialización del bean [Application] haya fallado. Sabemos que, en ese caso, se han inicializado los siguientes campos:


  // errores
  private List<Erreur> erreurs = new ArrayList<Erreur>();
private Boolean erreur = false;

Este caso se puede prever en el método init del bean [Form]:


@PostConstruct
  private void init() {

    // ¿Se realizó correctamente la inicialización?
    if (application.getErreur()) {
      // se recupera la lista de errores
      erreurs = application.getErreurs();
      // se muestra la vista de errores
      setForms(false, false, true);
    }

    // se almacenan en caché los médicos y los clientes
    ...
  }
  • línea 5: si el bean [Application] se inicializó incorrectamente,
  • línea 7: se recupera la lista de errores,
  • línea 9: y se muestra la página de error.

Así, si detenemos el SGBD y el MySQL y reiniciamos la aplicación, ahora aparece la siguiente página:

Image

7.2. Conclusion

La migración de la aplicación Primefaces / EJB / Glassfish a un entorno Primefaces / Spring / Tomcat resultó sencilla. El problema de la fuga de memoria señalado en el análisis de la aplicación JSF / Spring / Tomcat (párrafo 4.3.5) persiste.

Se resolverá de la misma manera.

7.3. Pruebas con Eclipse

Importamos los proyectos de Maven a Eclipse [1]:

Ejecutamos el proyecto web [2].

Seleccionamos el servidor Tomcat [3]. A continuación, se muestra la página de inicio de la aplicación en el navegador interno de Eclipse [4].