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

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. Si es necesario, el lector puede 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 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>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. 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: gestionamos una posible excepción y almacenamos 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) debidas a paquetes que faltan y renombramos [IMetier] como la interfaz [ImetierLocal]. Esto basta para eliminar todos los errores [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>
    <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 gestionar el caso en el 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 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

10.2. Conclusion

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

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

10.4. Pruebas con el móvil

Para probar la aplicación en un móvil, se seguirá el procedimiento indicado en el apartado 8.5.6. A continuación se muestran algunas imágenes de la aplicación: