10. Application exemple-06 : rdvmedecins-pfm-spring
10.1. Le portage
Nous portons maintenant l'application précédente dans un environnement Spring / Tomcat :
![]() |
Nous allons nous appuyer sur deux applications déjà écrites. Nous allons utiliser :
- les couches [DAO] et [JPA] de la version 02 JSF / Spring,
- la couche [web] / Primefaces mobile de la version 05 PFM / EJB,
- les fichiers de configuration de Spring de la version 02
Nous refaisons là un travail analogue à celui qui avait été fait pour porter l'application JSF2 / EJB / Glassfish dans un environnement JSF2 / Spring Tomcat. Aussi donnerons-nous moins d'explications. Le lecteur peut, s'il en est besoin, se reporter à ce portage.
Nous mettons tous les projets nécessaires au portage dans un nouveau dossier [rdvmedecins-pfm-spring] [1] :
![]() |
- [mv-rdvmedecins-spring-dao-jpa] : les couches [DAO] et [JPA] de la version 02 JSF / Spring,
- [mv-rdvmedecins-spring-metier] : la couche [métier] de la version 02 JSF / Spring,
- [mv-rdvmedecins-pfmobile] : la couche [web] de la version 05 Primefaces mobile / EJB,
- en [2], nous les chargeons dans Netbeans,
- en [3], les dépendances du projet web ne sont plus correctes :
- les dépendances sur les couches [DAO], [JPA], [métier] doivent être changées pour cibler désormais les projets Spring ;
- le serveur Glassfish fournissait les bibliothèques de JSF. Ce n'est plus le cas avec le serveur Tomcat. Il faut donc les ajouter aux dépendances.
Le projet [web] évolue comme suit :
![]() |
Le fichier [pom.xml] de la couche [web] a désormais les dépendances suivantes :
<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>
Des erreurs apparaissent. Elles sont dues aux références EJB de la couche [web]. Etudions d'abord le bean [Application] :
![]() |
Nous enlevons toutes les lignes erronées à cause de paquetages manquants, nous renommons [IMetier] (c'est son nom dans la couche [métier] Spring) l'interface [IMetierLocal] et nous utilisons Spring pour l'instancier :
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 {
// couche métier
private IMetier metier;
// erreurs
private List<Erreur> erreurs = new ArrayList<Erreur>();
private Boolean erreur = false;
public Application() {
try {
// instanciation couche [métier]
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config-metier-dao.xml");
metier = (IMetier) ctx.getBean("metier");
} catch (Throwable th) {
// on note l'erreur
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;
}
}
// getters
public Boolean getErreur() {
return erreur;
}
public List<Erreur> getErreurs() {
return erreurs;
}
public IMetier getMetier() {
return metier;
}
}
- lignes 20-21 : instanciation de la couche [métier] à partir du fichier de configuration de Spring. Ce fichier est celui utilisé par la couche [métier] [1]. Nous le copions dans le projet web [2] :
![]() |
- lignes 22-31 : nous gérons une éventuelle exception et mémorisons sa pile dans le champ de la ligne 14.
Ceci fait, le bean [Application] n'a plus d'erreurs. Regardons maintenant le bean [Form] [1], [2] :
![]() |
![]() ![]() |
Nous supprimons toutes les lignes erronées (import et annotations) à cause de paquetages manquants et renommons [IMetier] l'interface [ImetierLocal]. Cela suffit pour éliminer toutes les erreurs [3].
Par ailleurs, il faut ajouter dans le code du bean [Form], le getter et le setter du champ
// bean Application
private Application application;
Certaines des annotations supprimées dans les beans [Application] et [Form] déclaraient les classes comme étant des beans avec une certaine portée. Désormais, cette configuration est faite dans le fichier [faces-config.xml] [4] suivant :
<?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>
<!-- le fichier des messages -->
<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>
<!-- le 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>
<!-- le bean form -->
<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>
Le portage est terminé. Nous pouvons tenter d'exécuter l'application web.
![]() |
Nous laissons le lecteur tester cette nouvelle application. Nous pouvons l'améliorer légèrement pour gérer le cas où l'initialisation du bean [Application] a échoué. On sait que dans ce cas, les champs suivants ont été initialisés :
// erreurs
private List<Erreur> erreurs = new ArrayList<Erreur>();
private Boolean erreur = false;
Ce cas peut être prévu dans la méthode init du bean [Form] :
@PostConstruct
private void init() {
// l'initialisation s'est-elle bien passée ?
if (application.getErreur()) {
// on récupère la liste des erreurs
erreurs = application.getErreurs();
// la vue des erreurs est affichée
setForms(false, false, true);
}
// on met les médecins et les clients en cache
...
}
- ligne 5 : si le bean [Application] s'est mal initialisé,
- ligne 7 : on récupère la liste des erreurs,
- ligne 9 : et on affiche la page d'erreur.
Ainsi, si on arrête le SGBD MySQL et qu'on relance l'application, on reçoit maintenant la page suivante :

10.2. Conclusion
Le portage de l'application Primefaces mobile/ EJB / Glassfish vers un environnement Primefaces mobile / Spring / Tomcat s'est révélé simple. Le problème de la fuite mémoire signalée dans l'étude de l'application JSF / Spring / Tomcat (paragraphe 4.3.5) demeure. On le résoudra de la même façon.
10.3. Tests avec Eclipse
Nous importons les projets Maven dans Eclipse [1] :
![]() |
Nous exécutons le projet web [2].
![]() |
Nous choisissons le serveur Tomcat [3]. La page d'accueil de l'application est alors affichée dans le navigateur interne d'Eclipse [4].
10.4. Tests avec mobile
Pour tester l'application sur un mobile, on procèdera comme il a été indiqué au paragraphe 8.5.6. Voici des photos de l'application :
![]() | ![]() |
![]() | ![]() |














