Intégration de Flex 3, BlazeDS et Spring sous Flex Builder 3
Date de publication : 04/06/2008
Par
Franck Ponchel (fponchel.developpez.com)
Ce tutoriel a pour objectif de vous aider à mettre en place un projet mixte Flex/WTP utilisant Flex 3, BlazeDS et Spring.
Introduction
I. Récupération des produits logiciels
II. Préparation de l'environnement de développement
II-a. Pré-requis
II-b. Installations
III. Création et configuration du projet
IV. Première application
IV-a. Développement de l'IHM Flex
IV-b. Premier test
IV-c. Création de WelcomeService
IV-d. Déclaration du service auprès de BlazeDS
IV-e. Tester l'application
V. Intégration de Spring
V-a. Ajout des dépendances au projet
V-b. Configuration du contexte Spring
V-c. Intégration de Spring à BlazeDS
V-d. Tester l'application finale
VI. Pour aller plus loin...
Introduction
Dans ce tutoriel, nous allons mettre en place une application RIA composée d'un client riche Flex 3 s'exécutant au sein d'un navigateur web via le plugin Flash Player et d'un serveur d'application JEE exploitant Spring et BlazeDS.

Architecture logicielle
Dans cette architecture, le client Flex réalise des appels de service s'exécutant au sein du serveur d'application JEE. Pour cela, j'ai décidé d'utiliser les appels de type RPC (Remote Procedure Call), et plus spécifiquement le composant RemoteObject de Flex, permettant d'invoquer des services Java, sans avoir à se soucier de la sérialisation/désérialisation des objets échangés entre Flex et Java.
BlazeDS est une brique open-source, fournit par Adobe, supportant les appels RPC via RemoteObject. En pratique, il s'agit d'une servlet responsable, entre autres, de :
- localiser et invoquer les services Java
- désérialiser les données Flex reçues en instances d'objets Java et vice-versa
BlazeDS s'interpose donc entre le client Flex et les services Java à la manière d'un proxy.
Enfin, nous intégrons ici le framework Spring, non par nécessité, mais parce que celui-ci est très populaire et que l'intégration entre Spring et BlazeDS est une problématique récurrente.
Dans notre architecture, Spring est utilisé comme container IoC. Spring gèrera donc le cycle de vie de nos services. BlazeDS devra s'adresser à Spring afin de localiser un service à invoquer.
Nous allons commencer par installer l'ensemble des outils nécessaires, puis nous mettrons en place un projet mixte Flex/WTP configuré pour l'utilisation de BlazeDS. Nous développerons un service Java et une IHM Flex très simple afin de valider notre travail.
Enfin, nous ajouterons Spring et adapterons la configuration de BlazeDS.
I. Récupération des produits logiciels
II. Préparation de l'environnement de développement
Nous allons installer Eclipse, le plugin Flex Builder 3 et le serveur d'application Apache Tomcat, puis les framework BlazeDS et Spring.
Pour les besoins de l'article, l'ensemble sera installé dans le répertoire c:\appl.
II-a. Pré-requis
Vous devez disposer d'un JDK 1.5 ou plus d'installé. Pour vérifier, ouvrir un invité de commande et taper :
| Vérification de la version de Java installée |
C:\>java -version
java version "1.5.0_08"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_08-b03)
Java HotSpot(TM) Client VM (build 1.5.0_08-b03, mixed mode)
|
Se reporter à la FAQ java en cas de problème :
La FAQ Java
II-b. Installations
Décompresser l'archive d'Eclipse dans le répertoire c:\appl\eclipse. Pour la suite de cet article, nous considérerons qu'Eclipse est installé dans ce répertoire.
Une fois Eclipse installé, lancer l'installation du plugin Flex Builder 3 Professional :
 | Ceci nécessite les droits d'administration sur le poste de travail. |
Choisir c:\appl\fb3 comme répertoire d'installation, et c:\appl\eclipse comme répertoire où est installé Eclipse :

Choix d'installation
Décompresser l'archive de Tomcat 6.0 dans c:\appl\tomcat, celle de Spring dans c:\appl\spring et enfin celle de BlazeDS dans c:\appl\blazeds.
 | Vous trouverez, dans c:\appl\blazeds, 2 fichiers, dont blazeds.war qui contient une webapp JEE pré-configurée pour BlazeDS. |
III. Création et configuration du projet
- Démarrer Eclipse
- Sélectionner un répertoire pour la création d'un workspace. Par ex : c:\worspace
- Ouvrir la perspective Flex Development (Menu Windows / Open Perspective / Other… / Flex Development)
- Créer un nouveau projet Flex (Menu File / New / Flex Project) :
- project name : FBSIntegration pour Flex BlazeDS Spring Integration
- application server type : J2EE
- laisser coché “LiveCycle Data Services” et Create combined Java/Flex project using WTP
- Cliquer sur le bouton Next afin d'atteindre l'étape Configure JEE Server
- Cliquer sur le bouton New... afin de configurer une instance du serveur Tomcat dans Eclipse
- Sélectionner Apache / Tomcat v6.0 Server, puis cliquer sur Next>
- Renseigner le champ “Tomcat installation directory” pour qu'il pointe sur le répertoire d'installation de Tomcat (c:\appl\tomcat). Puis cliquer sur Finish
- De retour au wizard de configuration du projet Flex/WTP, renseigner le champ Flex WAR File pour désigner le fichier blazeds.war situé dans le répertoire d'installation de BlazeDS (c:\appl\blazeds\blazeds.war).
- Cliquer sur Next >
- L'écran suivant nous indique que les fichiers sources Flex sont situés dans flex_src/, tandis que les fichiers sources Java sont situés dans src/
- Cliquer sur Finish
Il reste un dernier paramétrage à réaliser :
- Sélectionner le projet FBSIntegration dans la vue Flex Navigator, puis afficher les propriétés du projet (menu Project / Properties / Flex Server)
- Modifier le champ Context root pour que celui-ci désigne correctement le nom du contexte de notre application, à savoir /FBSIntegration.
Enfin, il faut configurer le serveur Tomcat au sein d'Eclipse pour qu'il déploie notre application :
- Si ce n'est pas déjà fait, afficher la vue Servers (menu Windows / Show View / Other / Server / Servers)
- Ajouter le projet FBSIntegration au serveur Tomcat (Bouton droit sur le serveur “Tomcat v6.0 server at localhost, et ajouter le projet FBSIntegration à la liste des Configured Projects (menu Add and Remove Projects...)
IV. Première application
Nous allons développer une application trés simple, de type "Hello World" afin de valider le bon fonctionnement de l'ensemble.
Le scénario est le suivant :
- L'utilisateur saisit un login, et clique sur le bouton « Appel de WelcomeService »
- Ceci déclenche un appel à la méthode sayHello du service distant welcomeService
- Le message retourné par la méthode sayHello est affiché dans la zone de réponse.
- En cas d'échec de l'appel, le message d'erreur est affiché dans la zone de réponse.

Vue design
IV-a. Développement de l'IHM Flex
Le fichier flex_src/FBSIntegration.mxml contient principalement :
- le champ de saisie du login : tiLogin
- le bouton déclenchant l'appel : btnAppel
- le composant RemoteObject permettant d'effectuer l'appel distant : roWelcomService
- la zone de texte permettant d'afficher le résultat de l'appel : taReponse
| FBSIntegration.mxml |
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" width="451" height="168"
paddingBottom="0" paddingLeft="0" paddingRight="0" paddingTop="0">
<mx:Script>
<![CDATA[
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
private function doCall():void{
// Appeler le service distant
roWelcomeService.sayHello(tiLogin.text);
}
/**
* Méthode invoquée en cas de succès de l'appel RPC
*/
private function onResult(event : ResultEvent):void{
// Afficher la réponse
taReponse.text = event.result as String;
}
/**
* Méthode invoquée en cas d'échec de l'appel RPC
*/
private function onFault(event : FaultEvent):void{
// Afficher le message d'erreur
taReponse.text = event.fault.message;
}
]]>
</mx:Script>
<mx:RemoteObject id="roWelcomeService"
destination="welcomeServiceDest"
result="onResult(event)"
fault="onFault(event)"/>
<mx:Panel width="451" height="168" layout="absolute" title="Hello World">
<mx:Label x="10" y="10" text="Login : "/>
<mx:TextInput id="tiLogin" text="Guest"
x="66" y="8" />
<mx:Button id="btnAppel" label="Appel de WelcomeService"
x="234" y="8"
click="doCall()"/>
<mx:Label x="10" y="38" text="Réponse :"/>
<mx:TextArea id="taReponse"
x="81" y="37" width="327" height="81"/>
</mx:Panel>
</mx:Application>
|
IV-b. Premier test
Nous allons tester l'application en l'état. Pour cela, il faut :

Premier test...
Bien entendu, l'appel échoue, car nous n'avons pas encore développé le service "WelcomeService" appelé par l'IHM Flex, ni déclaré celui-ci auprès de BlazeDS !
IV-c. Création de WelcomeService
Dans le répertoire src/, créer la classe WelcomeService dans le package com.developpez.service :
| WelcomeService.java |
package com.developpez.service;
public class WelcomeService {
public String sayHello(String pLogin){
return "Bienvenue "+pLogin;
}
}
|
Ce service trés simple définit la méthode sayHello, qui prend en argument un login et retourne un message de bienvenue incluant le login fourni.
IV-d. Déclaration du service auprès de BlazeDS
Une fois le service Java créé, il faut configurer BlazeDS pour que celui-ci sache le localiser et l'associe à une « destination ».
- Editer le fichier remoting-service.xml, situé dans WebContent/WEB-INF/flex/
- Il faut y ajouter la destination welcomeServiceDest :
| remoting-service.xml |
<?xml version="1.0" encoding="UTF-8"?>
<service id="remoting-service"
class="flex.messaging.services.RemotingService">
<adapters>
<adapter-definition id="java-object" class="flex.messaging.services.remoting.adapters.JavaAdapter" default="true"/>
</adapters>
<default-channels>
<channel ref="my-amf"/>
</default-channels>
<destination id="welcomeServiceDest">
<properties>
<source>com.developpez.service.WelcomeService</source>
<scope>application</scope>
</properties>
</destination>
</service>
|
 |
Flex Builder ne re-compile pas l'application Flex suite à la modification de ce fichier !
Il faut donc soit faire un Project / clean, soit légèrement modifier le fichier mxml pour que celui-ci soit recompilé et intègre la déclaration de la destination.
|
IV-e. Tester l'application
Re-testons l'application afin de s'assurer que nous avons correctement configuré BlazeDS (se reporter à la section IV-b).
Cette fois, l'appel au service réussit et nous retourne le message de bienvenue ! :-)

Second test... réussi !
V. Intégration de Spring
Nous allons intégrer le framework Spring dans notre environnement, en suivant les étapes suivantes :
- Ajout des dépendances au projet
- Initialisation du context Spring
- Déclaration de WelcomeService dans le context Spring
- Configuration de BlazeDS
V-a. Ajout des dépendances au projet
Copier le fichier spring.jar, situé dans c:\appl\spring\dist dans le répertoire WebContent/WEB-INF/lib du projet, et rafraîchir le projet si nécessaire.
La librairie spring.jar doit apparaître dans les Web App Librairies de la section Java Build Path des propriétés du projet :

Ajout de spring.jar
V-b. Configuration du contexte Spring
Pour une introduction à Spring, vous pouvez consulter ce tutorial :
Introduction au framework Spring (par Erik Gollot)
Nous allons tout d'abord ajouter le fichier
webApplicationContext.xml de configuration du contexte Spring puis modifier le fichier
web.xml afin d'initialiser ce contexte.
Ajouter le fichier webApplicationContext.xml suivant à la racine du répertoire src/ :
| webApplicationContext.xml |
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
</beans>
|
Puis il faut modifier le fichier web.xml situé dans WebContent/WEB-INF.
Nous y ajoutons une section « context-param » et un « listener », comme suit :
| web.xml |
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<display-name>FBSIntegration</display-name>
<description>BlazeDS Application</description>
<context-param>
<param-name>flex.class.path</param-name>
<param-value>/WEB-INF/flex/hotfixes,/WEB-INF/flex/jars</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/webApplicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
...
</web-app>
|
Nous allons déclarer le bean welcomeServiceBean en tant qu'instance de la classe WelcomeService, en ajoutant une déclaration au fichier webApplicationContext.xml précédemment créé :
| webApplicationContext.xml |
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="welcomeServiceBean" class="com.developpez.service.WelcomeService"/>
</beans>
|
V-c. Intégration de Spring à BlazeDS
En l'état, BlazeDS n'utilise pas le context Spring pour localiser les instances du service.
Il est nécessaire de configurer, auprès de BlazeDS, une
Factory spécifique, qui s'occupera d'interroger le contexte Spring.
Cette technique a été initialement proposée par Jeff Vroom :
Spring and Flex Integration by Jeff Vroom
Il vous faut ajouter le fichier
SpringFactory.java suivant dans le package
com.developpez.web :
| SpringFactory.java |
package com.developpez.web;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import flex.messaging.FactoryInstance;
import flex.messaging.FlexFactory;
import flex.messaging.config.ConfigMap;
import flex.messaging.services.ServiceException;
@author
public class SpringFactory implements FlexFactory
{
private static final String SOURCE = "source";
public void initialize(String id, ConfigMap configMap) {}
public FactoryInstance createFactoryInstance(String id, ConfigMap properties)
{
SpringFactoryInstance instance = new SpringFactoryInstance(this, id, properties);
instance.setSource(properties.getPropertyAsString(SOURCE, instance.getId()));
return instance;
}
public Object lookup(FactoryInstance inst)
{
SpringFactoryInstance factoryInstance = (SpringFactoryInstance) inst;
return factoryInstance.lookup();
}
static class SpringFactoryInstance extends FactoryInstance
{
SpringFactoryInstance(SpringFactory factory, String id, ConfigMap properties)
{
super(factory, id, properties);
}
public String toString()
{
return "SpringFactory instance for id=" + getId() + " source=" + getSource() + " scope=" + getScope();
}
public Object lookup()
{
ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(flex.messaging.FlexContext.getServletConfig().getServletContext());
String beanName = getSource();
try
{
return appContext.getBean(beanName);
}
catch (NoSuchBeanDefinitionException nexc)
{
ServiceException e = new ServiceException();
String msg = "Spring service named '" + beanName + "' does not exist.";
e.setMessage(msg);
e.setRootCause(nexc);
e.setDetails(msg);
e.setCode("Server.Processing");
throw e;
}
catch (BeansException bexc)
{
ServiceException e = new ServiceException();
String msg = "Unable to create Spring service named '" + beanName + "' ";
e.setMessage(msg);
e.setRootCause(bexc);
e.setDetails(msg);
e.setCode("Server.Processing");
throw e;
}
}
}
}
|
Une fois la SpringFactory créée, il est nécessaire de la déclarer pour que BlazeDS sache la localiser.
Pour cela, ajouter une section <factories> au début du fichier services-config.xml, situé dans WebContent/WEB-INF/flex :
| Mise à jour de services-config.xml |
<?xml version="1.0" encoding="UTF-8"?>
<services-config>
<factories>
<factory id="SpringFactory" class="com.developpez.web.SpringFactory" />
</factories>
...
</services-config>
|
Enfin, il faut modifier la destination welcomeServiceDest dans le fichier remoting-config.xml, pour que celle-ci utilise la factory SpringFactory afin de localiser le bean Spring welcomeServiceBean.
La balise <factory> est ajoutée, afin de spécifier la SpringFactory déclarée dans le services-config.xml.
La balise <source> est modifiée afin de spécifier le nom du bean Spring à utiliser.
Enfin, la balise <scope> est supprimée, car c'est Spring qui gère dorénavant le cycle de vie du service.
| Mise à jour de remoting-config.xml |
<destination id="welcomeServiceDest">
<properties>
<factory>SpringFactory</factory>
<source>welcomeServiceBean</source>
</properties>
</destination>
|
V-d. Tester l'application finale
Démarrer le serveur d'application Tomcat
Dans la console, les traces suivantes permettent de vérifier l'initialisation correcte de Spring :
| Traces de démarrage du serveur d'application |
INFO: Initializing Spring root WebApplicationContext
...…
INFO: Loading XML bean definitions from ServletContext resource [/WEB-INF/classes/webApplicationContext.xml]
...
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@7f58ef: defining beans [welcomeServiceBean]; root of factory hierarchy
...
INFO: Root WebApplicationContext: initialization completed in 242 ms
|
VI. Pour aller plus loin...
Vous disposez maintenant d'un projet mixte WTP/Flex correctement configuré pour exploiter Flex, BlazeDS et Spring. A vous maintenant de construire sur cette base votre application !
Voici quelques ressources utiles :


Copyright © 2008 Franck Ponchel. Aucune reproduction, même partielle, ne peut être faite
de ce site et de l'ensemble de son contenu : textes, documents, images, etc.
sans l'autorisation expresse de l'auteur.
Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 €
de dommages et intérêts.
Cette page est déposée.