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:

  • las capas [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

En este caso, 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 ello, daremos menos explicaciones. El lector puede, si lo considera necesario, 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. Este ya no es el caso con el servidor Tomcat. Por lo tanto, hay que añadirlas a las dependencias.

El proyecto [web] evoluciona de la siguiente manera:

El archivo [pom.xml] de la capa [web] tiene ahora 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. 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: gestionamos 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 erróneas (import y anotaciones) debido a paquetes que faltan. Esto basta para eliminar todos los errores de [3].

Además, hay que añadir en el código del bean [Form] los métodos getter y 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 ámbito. 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 ha finalizado. 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 gestionar el caso en el que haya fallado la inicialización del bean [Application]. 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 ha realizado 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 ha inicializado incorrectamente,
  • línea 7: se recupera la lista de errores,
  • línea 9: y se muestra la página de error.

Así, si se detienen los beans SGBD y MySQL y se reinicia 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 ha resultado sencilla. El problema de la fuga de memoria señalado en el estudio de la aplicación JSF / Spring / Tomcat (apartado 4.3.5) persiste.

Se resolverá de la misma manera.

7.3. Pruebas con Eclipse

Importamos los proyectos 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].