Associer Spring et GWT

Demander un devis
Je souhaite télécharger le programme ou imprimer le programme
  • Imprimer
tutoriel_vers_formation

Info : Le projet de ce tutoriel a été développé pendant une formation GWT 2 de Juin 2011.

 

Quel intérêt ?

GWT (Google Web Toolkit) permet de créer des interfaces riches en Java qui seront ensuite, via un compilateur, générées en JavaScript. Afin d'architecturer notre application GWT, il existe un pattern poussé par Google, le MVP : Model View Presenter. Ce modèle nous permet de résoudre le problème côté client (navigateur) cependant nous avons toujours les mêmes problèmes d'architectures inhérents au Java EE : architecturer la partie serveur.


Afin de nous aider dans la mise en place cette architecture (que nous vous avons proposée dans le tutoriel JEE), il est courant d'utiliser le framework opensource Spring. La manière d'utiliser Spring est la suivante, induite de l'injection de dépendances : tous les liens de mon application sont faits par Spring et le point d'entrée (contrôleur principal de l'application) est Spring.


Or, dans une application GWT, pour communiquer entre le client et le serveur, nous utilisons très fréquemment GWT-RPC permettant de ne pas avoir à gérer la sérialisation d'objets clients/serveur. Côté serveur cependant, le fichier web.xml définit directement l'appel de classes GWT. C'est un problème, nous nous voulons que ce soit Spring le point d'entrée de notre application et qu'il appelle ensuite les classes GWT (en leur injectant d'autres classes dont nos classes serveur GWT auront besoin).


C'est pour faire le lien entre Spring et GWT que le projet opensource GWTRPC-Spring a été créé. Vous trouverez leur site officiel ici : . http://code.google.com/p/gwtrpc-spring/. Le projet date maintenant un peu mais il marche très bien pour intégrer Spring 3.0 avec GWT 2.3, dernières versions au moment où nous écrivons ces lignes.


L'objectif de ce tutoriel est simple : partir d'un appel de services simple en GWT et faire en sorte d'y intégrer Spring via GWTRPC-Spring.

 

Si vous ne souhaitez pas lire tout le tutoriel, vous trouverez le code source en cliquant sur ce lien Télécharger le projet final.

 

Mise en place de GWT avec un échange RPC

Prenons un exemple simple : récupération du montant d'une somme avec calcul de la somme côté serveur.
Commençons par créer le projet et définir l'interface utilisateur.

nouveau projet gwt

 

arborescence nouveau projet gwt

extrait nouveau projet gwt

 

 

package fr.mistra.gwtrpcspring.client;
 
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
 
public class Gwtrpcspring implements EntryPoint {
                KeyUpHandler keyHandler ;
                private TextBox tboxChiffre1;
                private TextBox tboxChiffre2;
                private Label lblResultat;
 
                public void onModuleLoad() {
                               HorizontalPanel hPanel1 = new HorizontalPanel();
                               HorizontalPanel hPanel2 = new HorizontalPanel();
 
                               tboxChiffre1 = new TextBox();
                               tboxChiffre2 = new TextBox();
                               lblResultat = new Label("0");
                               hPanel1.add(tboxChiffre1);
                               hPanel1.add(tboxChiffre2);
                               hPanel2.add(new Label("Resultat: "));
                               hPanel2.add(lblResultat);
                               keyHandler = new KeyUpHandler() {
 
                                               @Override
                                               public void onKeyUp(KeyUpEvent event) {
                                                               // Appel du service
                                               }
                               };
                               RootPanel.get().add(hPanel1);
                               RootPanel.get().add(hPanel2);
                }
}

 

 

Créons maintenant les appels de service :

  • SumService : l'interface déclarant l'échange (côté client)
  • SumServiceAsync : l'interface déclarant le retour de l'échange (côté client)
  • SumServiceImpl : implémentation côté serveur

 

SumService :

package fr.mistra.gwtrpcspring.client;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

@RemoteServiceRelativePath("sum")
public interface SumService extends RemoteService {
    Integer sum(Integer nb1, Integer nb2) throws IllegalArgumentException;
}

 

SumServiceAsync :

package fr.mistra.gwtrpcspring.client;

import com.google.gwt.user.client.rpc.AsyncCallback;

public interface SumServiceAsync {
    void sum(Integer nb1, Integer nb2, AsyncCallback<Integer> callback);
}

 

SumServiceImpl (côté serveur) :

package fr.mistra.gwtrpcspring.server;

import fr.mistra.gwtrpcspring.client.SumService;

public class SumServiceImpl implements SumService{
    
    @Override
    public Integer sum(Integer nb1, Integer nb2)
            throws IllegalArgumentException {
        return nb1+nb2;
    }

}

 

Maintenant, appelons notre service depuis notre interfae, de manière asynchrone :

package fr.mistra.gwtrpcspring.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;

public class Gwtrpcspring implements EntryPoint {
    KeyUpHandler keyHandler ;
    private TextBox tboxChiffre1;
    private TextBox tboxChiffre2;
    private Label lblResultat;
    SumServiceAsync sumService = GWT.create(SumService.class);
    
    public void onModuleLoad() {
        HorizontalPanel hPanel1 = new HorizontalPanel();
        HorizontalPanel hPanel2 = new HorizontalPanel();
        
        tboxChiffre1 = new TextBox();
        tboxChiffre2 = new TextBox();
        lblResultat = new Label("0");
        hPanel1.add(tboxChiffre1);
        hPanel1.add(tboxChiffre2);
        hPanel2.add(new Label("Resultat: "));
        hPanel2.add(lblResultat);
        keyHandler = new KeyUpHandler() {
            
            @Override
            public void onKeyUp(KeyUpEvent event) {
                Integer nb1 = 0;
                if (!"".equals(tboxChiffre1.getValue())) nb1 = Integer.valueOf(tboxChiffre1.getValue());
                
                Integer nb2 = 0;
                if (!"".equals(tboxChiffre2.getValue())) nb2 =Integer.valueOf(tboxChiffre2.getValue());
                
                // Appel du service
                sumService.sum(nb1, nb2, new AsyncCallback<Integer>() {
                    
                    @Override
                    public void onSuccess(Integer result) {
                        lblResultat.setText(result.toString());
                    }
                    
                    @Override
                    public void onFailure(Throwable caught) {
                        lblResultat.setText("Probleme echange serveur");
                    }
                });
                
            }
        };
        tboxChiffre1.addKeyUpHandler(keyHandler);
        tboxChiffre2.addKeyUpHandler(keyHandler);
        RootPanel.get().add(hPanel1);
        RootPanel.get().add(hPanel2);
    }
}

 

Relancez l'application, elle fonctionne : nous sommes capables de faire une addition (génial !).

Vous pouvez télécharger ce qui a été développé jusqu'ici au format "Projet Eclipse" à l'adresse suivante: projet Eclipse.

 

Installation et Configuration de Spring 3 avec GWT 2

Librairies nécessaires

Commençons par télécharger l’archive de gwtrpcspring. Pour s’assurer d’avoir toutes les librairies nécessaires, nous vous avons fait une archive, disponible ici : … Copiez collez les dans le répertoire war/WEB-INF/lib/

Configuration du Web.xml (Tomcat, JEE) pour Spring GWT RPC

Dans le fichier web.xml, il ne faut plus que le serveur d’applications instancie directement notre classe pour le RPC mais plutôt instancier Spring pour que ce dernier instancie notre classe avec les bonnes dépendances.
Nous allons aussi utiliser le fichier web.xml pour indiquer au filtre Spring de charger le contexte : ContextLoaderListener.
Fichier web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
                </listener-class>
    </listener>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>
            org.gwtrpcspring.RemoteServiceDispatcher
                </servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/gwtrpcspring/sum</url-pattern>
    </servlet-mapping>

    <!-- Default page to serve -->
    <welcome-file-list>
        <welcome-file>Gwtrpcspring.html</welcome-file>
    </welcome-file-list>

</web-app>

 

Configurations du contexte Spring pour GWT

Maintenant que nous redirigeons toutes nos requêtes au serveur vers Spring, il faut indiquer à ce dernier de charger notre classe.
Ici, deux manières de fonctionner : par annotations ou par déclaration XML. Nous vous proposerons les deux.

 

Configuration par annotations :

Fichier applicationContext.xml (dans war/WEB-INF/) :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <context:annotation-config />
    <context:component-scan base-package="fr.mistra.gwtrpcspring.server" />

</beans>


Ceci nous permet ensuite de modifier notre classe de service en enlevant sa dépendance à un serveur d’applications et la rendant simple POJO :

package fr.mistra.gwtrpcspring.server;

import org.springframework.stereotype.Service;

import fr.mistra.gwtrpcspring.client.SumService;

@Service("sumService")
public class SumServiceImpl implements SumService{

    private static final long serialVersionUID = 1L;

    @Override
    public Integer sum(Integer nb1, Integer nb2)
            throws IllegalArgumentException {
        return nb1+nb2;
    }

}


Configuration par déclarations

Fichier applicationContext.xml (dans war/WEB-INF/) :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <bean id="sumService" class="fr.mistra.gwtrpcspring.server.SumServiceImpl"/>
    
</beans>


Nous pouvons maintenant modifier notre classe de service côté serveur, qui n’a plus besoin de dépendre d’un serveur d’applications. Elle devient une simple POJO.

package fr.mistra.gwtrpcspring.server;

import fr.mistra.gwtrpcspring.client.SumService;

public class SumServiceImpl implements SumService{

    private static final long serialVersionUID = 1L;

    @Override
    public Integer sum(Integer nb1, Integer nb2)
    throws IllegalArgumentException {
        return nb1+nb2;
    }

}

 

Testons notre code GWT avec Spring

rendu projet gwt final

 

Tout marche parfaitement. Nous avons donc remis Spring en point d'entrée de notre architecture serveur tout en utilisant la force de la communication client-serveur qu'est le RPC de GWT.


Vous pouvez télécharger le projet final ici : Télécharger le projet final.

 

tutoriel_vers_formation
.
X
 
 
 
 
 

You havecharacters left.