Skip to content

10. Aplicación de ejemplo-06: rdvmedecins-pfm-spring

10.1. La migración

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

Nos basaremos en dos aplicaciones ya desarrolladas. Utilizaremos:

  • las capas [DAO] y [JPA] de la versión 02 JSF / Spring,
  • la capa [web] / PrimeFaces Mobile de la versión 05 PFM / 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-pfm-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-pfmobile]: la capa [web] de la versión 05 de PrimeFaces Mobile / 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 de 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>org.primefaces</groupId>
      <artifactId>primefaces</artifactId>
      <version>3.2</version>
      <type>jar</type>
    </dependency>
    <dependency>
      <groupId>org.primefaces</groupId>
      <artifactId>mobile</artifactId>
      <version>0.9.1</version>
      <type>jar</type>
    </dependency>
    <dependency>
      <groupId>com.sun.faces</groupId>
      <artifactId>jsf-api</artifactId>
      <version>2.1.8</version>
    </dependency>
    <dependency>
      <groupId>com.sun.faces</groupId>
      <artifactId>jsf-impl</artifactId>
      <version>2.1.8</version>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>mv-rdvmedecins-spring-dao-jpa</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>mv-rdvmedecins-spring-metier</artifactId>
      <version>${project.version}</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) a 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 en el campo de la línea 14.

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

3
4

Eliminamos todas las líneas erróneas (importaciones y anotaciones) debido a paquetes que faltan y renombramos [IMetier] a la interfaz [ImetierLocal]. 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>
    <default-render-kit-id>PRIMEFACES_MOBILE</default-render-kit-id>
  </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>

La migración ha finalizado. 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 falle 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 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 se detienen los beans SGBD y MySQL y se reinicia la aplicación, ahora se muestra la siguiente página:

Image

10.2. Conclusion

La migración de la aplicación PrimeFaces Mobile / EJB / GlassFish a un entorno PrimeFaces Mobile / 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.

10.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].

10.4. Pruebas con dispositivos móviles

Para probar la aplicación en un celular, se seguirá el procedimiento indicado en el párrafo 8.5.6. A continuación se muestran algunas fotos de la aplicación: