SlideShare une entreprise Scribd logo
1  sur  76
Présentation de
Google Web Toolkit
Présentation de
        Google Web Toolkit
•   GWT (version 2.4)
•   Celinio Fernandes
•   juin 2012
Sommaire
•   Introduction                                  • Design pattern
•   Historique                                      MVP
•   Principe
•   Création d’un projet
•   Mode développement                            • Bonnes pratiques
                                                  • L’EventBus
• Les widgets
• Widget composite                                • L’API Activities and
• UiBinder                                          Places
                                                  • Le code splitting
• Events et handlers

• Les services distants RPC                       • Conclusion

                              Celinio Fernandes
Introduction
Historique
– Créé en 2006 par Bruce Johnson et Joel Webber
– Rachat par Google de la startup créée par Bruce Johnson
– Version 1.0 en 2006
– Version 1.5 en 2008
– Version 2.0 en 2009
– Version 2.1 en 2010 (Activities and Places, Request Factory – une alternative à GWT RPC)
– Version 2.2 en 2011 (update du widget CellTable)
– Version 2.4 en septembre 2011
– Version 2.5 prévue en 2012 (un SuperDevMode ?)


– Release notes : https://developers.google.com/web-toolkit/release-notes

                                                  Celinio Fernandes                          No. 5
Chronologie des frameworks




Source : https://github.com/mraible/history-of-web-frameworks-timeline

                           Celinio Fernandes
A quelle catégorie de
 frameworks appartient GWT ?
• Catégorisation possible :
  – basés sur des requêtes :
      • Struts, Spring MVC, Wicket
  – basés sur des composants :
      • JSF, Tapestry, Vaadin
  – RIA :
      • Flex, JavaFX

  GWT un mix des deux dernières catégories ?
      • génère du code qui tourne côté client donc basé sur des
        composants ?
      • utilise des widgets donc RIA ?


                                Celinio Fernandes                 No. 7
Principe
•   Un framework qui propose d’écrire une application en Java et de compiler ce code Java vers
    du HTML et du JavaScript nativement interprétable par les navigateurs web.



Client                       Java                                        JavaScript
                                           Compilateur GWT
                                                                       Services RPC


Serveur
                           Services                                         Java


Partie cliente : le code Java qui est au final compilé en JavaScript et qui est exécuté dans un
browser.
• N’utilisé, côté client, que des librairies de l’API Java qui peuvent être
compilées en JavaScript
• Emulation partielle de JRE (java.lang.*, java.util.*, etc…)

                                            Celinio Fernandes                                     No. 8
Plugin GWT pour Eclipse (1/3)
                              • Renommé Google
                                Plugin
                              • Installation facile
                                via l’URL
                              •   http://dl.google.com/eclipse/plugin/3.7
                              •   (Eclipse 3.7 Indigo)
                              •    Permet de créer un projet GWT sous Eclipse
                              •    Permet de lancer une application en mode
                                  « developpement »




          Celinio Fernandes                                          No. 9
Plugin GWT pour Eclipse (2/3)
Application sample (1)                  Application sample (2)




                         Celinio Fernandes
Plugin GWT pour Eclipse (3/3)
Application sample (3)                Application sample (4)




                         Celinio Fernandes
Structure d’un projet / module GWT
•Fichier de configuration du module :
LabGWT.gwt.xml

•Package client : code Java compilé en
JavaScript (si spécifié par le tag <source> du
fichier de configuration)

•Package server : code Java non compilé en
JavaScript

•Package shared : code Java commun au client
et au serveur. Compilé en JavaScript (si spécifié
par le tag <source> du fichier de configuration)

•Point d’entrée : LabGWT.java
public void onModuleLoad() équivalent du
main() en C/C++/Java.

•Page HTML d’accueil : LabGWT.html. Elle inclut
le fichier JavaScript généré,
<module>.nocache.js, dans un tag <script> :
<script type="text/javascript" language="javascript"
src="labgwt/labgwt.nocache.js"></script>

                                         Celinio Fernandes   No. 12
Fichiers JavaScript générés
•   Les fichiers JavaScript générés sont présent dans le classpath.
•   Ils sont par défaut obfuscated. C’est un format compressé (pas de retour à la ligne, pas
    d’espace, noms des fonctions changés, etc) qui accélère les temps de chargement.




                                    Celinio Fernandes
Création d’un projet GWT avec Maven
                (1/2)
Le plugin gwt-maven-plugin permet de générer un squelette de projet GWT




                              Celinio Fernandes
Création d’un projet GWT avec Maven
                              (2/2)
• Problème :                                                                  • Archétype :
•   Classes non trouvées. Faire un mvn install d’abord.                       •      mvn archetype:generate 
    Puis copier-coller des classes générées suivantes :                       •      -DarchetypeRepository=repo1.maven.org 
•   /target/generated-                                                        •      -DarchetypeGroupId=org.codehaus.mojo 
    sources/gwt/foo/client/GreetingServiceAsync.java                          •      -DarchetypeArtifactId=gwt-maven-plugin 
•   /target/generated-                                                        •       -DarchetypeVersion=2.4.0
    sources/gwt/foo/client/Messages.java
•   vers /src/main/java/foo/client                                            •   http://mojo.codehaus.org/gwt-maven-
                                                                                  plugin/user-guide/archetype.html

•

                                                              Dépendances Maven :
                                                  <dependency>
                                                       <groupId>com.google.gwt</groupId>
                                                  <artifactId>gwt-servlet</artifactId>
                                                  <version>2.4</version>
                                                  <scope>runtime</scope>
                                              </dependency>
                                              <dependency>
                                                      <groupId>com.google.gwt</groupId>
                                                 <artifactId>gwt-user</artifactId>
                                                 <version>2.4</version>
                                                 <scope>provided</scope>
                                              </dependency>


                                                          Celinio Fernandes
Création d’un projet GWT avec Spring
                     Roo (1/3)
• Version standalone de Roo. Pas besoin de SpringSource
  Tool Suite (STS).
• Un exemple standard, Expenses, intègre GWT :
• Roo> script expenses.roo




• Roo > exit

                             Celinio Fernandes            No. 16
Création d’un projet GWT avec Spring
              Roo (2/3)




             Celinio Fernandes   No. 17
Création d’un projet GWT avec Spring
                             Roo (3/3)
• Projet importable dans Eclipse.
• L’exemple Expenses utilise « Activities and Places ».

• Autre commande Roo :
• Roo > web gwt setup




• Documentation officielle :
•   http://static.springsource.org/spring-roo/reference/html/base-gwt.html




                                                            Celinio Fernandes
Mode développement (1/3)
• Le mode developpement permet de
tester l’application dans le browser sans
avoir besoin de compiler en JavaScript.

• Apporte une plus grande productivité.
Les modifications au niveau de l’UI sont
visibles immédiatement, après refresh.

• Requiert l’installation du plugin GWT
Developer pour le browser (Firefox,
Internet Explorer, Chrome …).

• URL se termine avec
gwt.codesvr=127.0.0.1:9997. Par
exemple :
http://127.0.0.1:8888/LabGWT.html?gwt.cod
esvr=127.0.0.1:9997




                                   Celinio Fernandes   No. 19
Mode développement (2/3)
•   Mode développement ou hosted                                 •   Mode web ou production


                                                                 •    Le code Java est traduit en
•    Utilisé dans la phase de                                        JavaScript
    développement                                                •    Déploiement sur le serveur
•    Le code client n’est pas traduit en                         •    Application plus rapide
    JavaScript
•    Possibilité de debugger
•    Les messages de log sont affichés
    dans une fenêtre de log
•    Utilise par défaut un serveur
    embarqué : Jetty
•    Evite la compilation de l’application
    et le déploiement sur le serveur




                                             Celinio Fernandes
Mode developpement (3/3)
•   Pour lancer le mode
    developpement avec le
    plugin Maven :
                            <plugin>
                                    <groupId>org.codehaus.mojo</groupId>
                                    <artifactId>gwt-maven-plugin</artifactId>
     • goal gwt:run                 <version>2.4.0</version>
                                    <executions>
     • goal gwt:debug                         <execution>
                                               <goals>
                                                     <goal>compile</goal>
                                                     <goal>test</goal>
                                                     <goal>i18n</goal>
                                                     <goal>generateAsync</goal>
                                         </goals>
                                        </execution>
                                    </executions>
                               <!-- Plugin configuration. There are many available options, see
                                gwt-maven-plugin documentation at codehaus.org -->
                               <configuration>
                                <runTarget>labGWT2.html</runTarget>
                                <hostedWebapp>${webappDirectory}</hostedWebapp>
                                <i18nMessagesBundle>foo.client.Messages</i18nMessagesBundle>
                               </configuration>
                            </plugin>




                                Celinio Fernandes                                                 No. 21
Les widgets
Les widgets (1/7)
•   Widget = composant graphique
•   Les composants graphiques générés sont du code HTML.
•   On peut utiliser l’arbre DOM directement, même s’il vaut mieux utiliser les widgets et leurs
    propriétés :



       Button button= new Button();
       DOM.setStyleAttribute(button.element, " backgroundColor", "blue");
       DOM.setStyleAttribute(button.element, " border", " 1px solid ");



•   Dans la hiérarchie des classes des Widgets, la classe mère est
    com.google.gwt.user.client.ui.UIObject.
•   http://google-web-toolkit.googlecode.com/svn/javadoc/2.4/com/google/gwt/user/client/ui/UIObject.html
•   Sous-classes directes de UIObject :
             •   MenuItem
             •   MenuItemSeparator
             •   TreeItem
             •   Widget




                                                               Celinio Fernandes                           No. 23
Les widgets (2/7)
•   Sous-classes directes de com.google.gwt.user.client.ui.Widget :
           •   AbstractNativeScrollbar : classe parente abstraite pour les scrollbars
           •   CellWidget
           •   Composite : pour créer des widgets personnalisés
           •   FileUpload : widget qui wrap le tag HTML <input type="type">
           •   FocusWidget
           •   Frame
           •   Hidden
           •   Hyperlink
           •   Image
           •   LabelBase
           •   MenuBar
           •   Panel : classe abstraite de base pour les panels (widgets qui contiennent d’autres widgets)
           •   Tree : contient une hiérarchie de TreeItems




                                         Celinio Fernandes                                         No. 24
Les widgets (3/7)
•     Quelques widgets de position (layout) :

    HorizontalPanel



    FlowPanel



    DisclosurePanel




                                                                    VerticalPanel
    TabLayoutPanel




                                                Celinio Fernandes              No. 25
Les widgets (4/7)
•    Quelques widgets de saisie :



    CheckBox




    RadioButton


                                                            DatePicker



    FileUpload




                                        Celinio Fernandes                No. 26
Les widgets (5/7)
•     Autres widgets :



    CellTable




    CellTree                                     Tree




                             Celinio Fernandes          No. 27
Les widgets (6/7)
•    Le showcase officiel : une
    gallerie de widgets avec code
    source disponible à l’URL
    http://gwt.google.com/samples/Sh
    owcase/Showcase.html



•    Disponible également dans le
    répertoire samples du SDK.




                                           Celinio Fernandes
Les widgets (7/7)
•   Possibilité de créer un widget personnalisé soit en :
          • sous-classant un widget existant
                                 public class DynamicSelectionCell extends SelectionCell { … }

          • héritant com.google.gwt.user.client.ui.Composite (recommandé)
                                  public class MultiSelect extends Composite {
                                     public Label lab = new Label();
                                     public TextBox textBox = new TextBox();
                                     public ListBox listBox = new ListBox();
                                                  ...
                                     public MultiSelect(String caption) {
                                                  HorizontalPanel panel = new HorizontalPanel();
                                                  panel.add(lab);
                                                  panel.add(listBox);
                                                  …
                                     // All composites must call initWidget() in their constructors.
                                     initWidget(panel);
                                     }
                                     ...
                   }




                                                        Celinio Fernandes                              No. 29
L’interface UiBinder (1/5)
– Façon déclarative de créer des layouts (vues, widgets …)

     • Un template avec l’extension ui.xml : RapportViewImpl.ui.xml
          • Code XML
          – Ne contient pas de logique
          – Décrit le layout

     • Une Owner classe de même nom : RapportViewImpl.java
         • Annotations : @UiField, @UiHandler, @UiTemplate (pour un nom de template différent
            et/ou avec plusieurs templates), etc…
         • Utilise UiBinder pour charger le layout
         • Relie les évènements au code




                                             Celinio Fernandes                                  No. 30
L’interface UiBinder (2/5)
• Owner classe :
•         public class RapportViewImpl extends Composite implements RapportView {
•                          private static RapportViewImplUiBinder uiBinder = GWT.create(RapportViewImplUiBinder.class);
•                          interface RapportViewImplUiBinder extends UiBinder<Widget, RapportViewImpl>
•                          {
•                          }

•                         @UiField Label lab;
•                         @UiField TabPanel TableauNotes;
•                         @UiField DockPanel monDockPanel;
•                         @UiField Label PremiereNote;
•                         @UiField Label DeuxiemeNote;
•                         @UiField Button boutonHello;

                          …
•                         @UiHandler("boutonHello")
•                         void onBoutonHelloClick(ClickEvent event) {
•                                        presenter.goTo(new HelloPlace(nom));
•                         }
•                         …
•          }




                                                                 Celinio Fernandes                                        No. 31
L’interface UiBinder (3/5)
• Template XML:
•        <!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
•        <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
•         xmlns:g="urn:import:com.google.gwt.user.client.ui">
•         ...
•        <g:HTMLPanel>
•                         Hello,
•                         <span class="{style.important}" ui:field="nameSpan" />
•                         <g:DockPanel height="281px" width="448px" ui:field="monDockPanel">
•                                           <g:Dock direction="WEST">
•                                             <g:Label ui:field="lab" text="Rapport a faire" width="120px"></g:Label>
•                                           </g:Dock>
•                                           <g:Dock direction="SOUTH">
•                                              <g:TabPanel ui:field="TableauNotes"> … </g:TabPanel>
•                                           </g:Dock>
•                                           <g:Dock direction="WEST">
•                                              <g:Button ui:field="boutonHello" text="Retour à l&apos;accueil"/>
•                                           </g:Dock>
•                         </g:DockPanel>
•        </g:HTMLPanel>
•         </ui:UiBinder>




                                                                  Celinio Fernandes                                     No. 32
L’interface UiBinder (4/5)
• Wizard de création sous Eclipse




                                    Celinio Fernandes   No. 33
L’interface UiBinder (5/5)
• GWT Designer pour le template




                                  Celinio Fernandes   No. 34
Events et
handlers
Events et handlers (1/4)
–   Un évènement (event) peut être :
      • un clic de bouton (ClickEvent)
      • un changement dans une listbox (ChangeEvent)
      • une touche de clavier pressée (KeyDownEvent)
      • un passage de souris dans une zone (MouseOverEvent)
      • un défilement (ScrollEvent)
      • etc…

–   La classe de base est com.google.gwt.event.shared.GwtEvent




                                             Celinio Fernandes   No. 36
Events et handlers (2/4)
• Pour gérer ces évènements, on ajoute des handlers aux widgets. Avec plusieurs possibilités de
  faire:
  • en passant par une classe anonyme
  • en implémentant l’interface du Handler
  • etc …


• Exemples d’interfaces d’handlers : ClickHandler, ChangeHandler, KeyDownHandler, MouseOverHandler,
  FocusHandler, ValueChangeHandler, SelectionHandler, OpenHandler …


• L’interface de base est com.google.gwt.event.shared.EventHandler




                                   Celinio Fernandes                                                  No. 37
Events et handlers (3/4)
•   Classe Handler anonyme :


                   public void anonClickHandlerExample() {

                       Button b = new Button("Click Me");

                       b.addClickHandler(new ClickHandler() {
                         public void onClick(ClickEvent event) {
                           // handle the click event
                         }
                       });

                   }




                                                        Celinio Fernandess   No. 38
Events et handlers (4/4)
•   Implémentation de l’interface du Handler :
           public class HandlerExample extends Composite implements ClickHandler {
            private FlowPanel fp = new FlowPanel();
            private Button b1 = new Button("Button 1");

               public HandlerExample() {
                initWidget(fp);
                fp.add(b1);
                b1.addClickHandler(this);
           }

               public void onClick(ClickEvent event) {
                            Widget sender = (Widget) event.getSource();
                            …
               }
           }




    – Adéquat pour des handlers complexes (plusieurs boutons, design complexe ..)


                                                                   Celinio Fernandes   No. 39
Les services
distants (RPC)
Les services RPC (1/6)
•    Les services RPC (Remote Procedure Call) permettent de faire des appels d’objets entre la
     partie cliente et la partie serveur.
•    GWT utilise des services RPC asynchrones pour rendre les applications Web plus interactives.
     Que veut dire asynchrone ?
             •   Le programme n’attend pas la fin de l’exécution de la méthode pour passer la suite (principe
                 même d’Ajax). Si un service est long, il ne faut pas attendre la réponse et il faut laisser la main
                 au browser.
•     GWT prend en charge la sérialisation et la désérialisation des objets Java.
•     GWT utilise des interfaces pour créer un service RPC :
              • Une interface synchrone qui hérite de com.google.gwt.user.client.rpc.RemoteService,
    côté client
              • Une interface asynchrone, côté client
              • Une classe, côté serveur (= package serveur), qui implémente l’interface synchrone et les
                méthodes RPC qu’on veut mettre à disposition côté client
       •   Pourquoi des services RPC dans GWT ?
             • Permettre l’exécution de méthodes côté serveur et qui ne sont pas exécutables côté client
               (compilation impossible en JavaScript, problème de sécurité …)



                                                         Celinio Fernandes                                             No. 41
Les services RPC (2/6)
•   Etapes
1. Créer les classes et interfaces RPC côté client
2. Créer l’implémentation côté serveur du service RPC. C’est une servlet qui implémente
   l’interface synchrone et qui étend RemoteServiceServlet.
3. Faire l’appel du service RPC dans le code
4. Ne pas oublier de modifier le fichier web.xml pour y déclarer la servlet et faire le mapping !




                                                Celinio Fernandes                                   No. 42
Les services RPC (3/6)
•   Diagramme de la plomberie RPC




•   Source : https://developers.google.com/web-toolkit/doc/latest/DevGuideServerCommunication#DevGuidePlumbingDiagram
•
                                                             Celinio Fernandes                                          No. 43
Les services RPC (4/6)
                 • L’interface synchrone (côté client) :
    @RemoteServiceRelativePath("manageVille")
    public interface ManageVilleService extends RemoteService {
                  public long getCodePostalVille (String nom) throws VilleNonTrouveeExceptionDto;
    }
                 • L’interface asynchrone (côté client) :
    public interface ManageVilleServiceAsync {
                  void getCodePostalVille (String nom, AsyncCallback<long> callback);
    }
                 • L’implémentation du service (côté serveur) :
    @RemoteServiceRelativePath("manageVille")
    public class ManageVilleDelegate extends SpringBeanInjectionRemoteServiceServlet implements ManageVilleService {
    @Autowired
    private ManageVille manageVilleApplication;

    public long getCodePostalVille (String nom) throws VilleNonTrouveeExceptionDto {
    // appels de services des autres couches / de modules non GWT …
    …
    }



•       Note : @RemoteServiceRelativePath associe le service à un chemin relatif




                                                                           Celinio Fernandes                           No. 44
Les services RPC (5/6)
•   Appel du service RPC depuis une activity (côte client), par exemple :

         public class VilleActivity extends AbstractActivity implements VilleView.Presenter {
           // RPC service proxy
           private final ManageVille ServiceAsync manageVilleServiceProxy;
             …
             manageVilleServiceProxy.getCodePostalVille(String nom, new AsyncCallback<long> () {
                  public void onFailure(Throwable caught) {
                      Window.alert("Problème !!");
                  }
                  public void onSuccess(long codePostal){
                     view.setCodePostal(codePostal);
                  }
             });
         ….
     }




•   Création d’une classe AsyncCallback anonyme, en paramètre de la méthode asynchrone
    appelée.



                                                                              Lab GWT              No. 45
Les services RPC (6/6)
•   Important : les objets transportés doivent être sérialisables. Les règles de sérialisation
    diffèrent un peu de celles de l’API Java standard.
•   https://developers.google.com/web-toolkit/doc/latest/DevGuideServerCommunication?hl=fr-
    FR#DevGuideSerializableTypes

•   Problème des entités :
•    Les entités JPA sont transformées au runtime par Hibernate, pour les rendre persistantes. Hibernate les
     instrumente en modifiant le bytecode, ce qui pose problème pour l’échange des données entre le client et
     le serveur à l’aide de la sérialisation.
              • Solution :
•    Utiliser le pattern DTO. Les objets de transfert (avec la même structure ou non que les objets persistés) ne
     sont pas instrumentés et peuvent être rendus sérialisables.
•    Et utiliser Dozer pour la transformation.




             Entité                                  Dozer                                         DTO


                                                       Celinio Fernandes                                            No. 46
Design
      pattern MVP
•   Model View Presenter
Le design pattern MVP (1/5)
•    Qui connait MVP ?
•    Permet d’éviter du code spaghetti




                                                                                     MVP




•
•   Modèle : les DTOs, les données qui sont affichées
•   Vue : l’interface graphique
•   Presenter : équivalent du contrôleur de MVC. Implémente l’accès à la logique métier et au modèle
    de données. Réagit aux évènements de l’utilisateur et qui sont transmis par la Vue.


                                                  Celinio Fernandes                                    No. 48
Le design pattern MVP (2/5)
•   Avantages :

          • Séparation claire entre la partie présentation et la logique métier

          • Plus grande maintenabilité puisqu’il n’y a presque pas de dépendance avec la logique métier
            (couplage faible).

          • Plus facile à tester. On peut mocker la Vue, le Presenter … (Mockito).




                                                    Celinio Fernandes                                     No. 49
Le design pattern MVP (3/5)
•   Un pattern conceptualisé par Martin Fowler :
•   http://martinfowler.com/eaaDev/ModelViewPresenter.html
•   Permet de séparer la logique métier de l’UI.
•   Deux variantes : Passive View et Supervising Controller




•   Source : http://msdn.microsoft.com/en-us/library/ff647543.aspx


                                                  Celinio Fernandes   No. 50
Le design pattern MVP (4/5)
•    Dans GWT, c’est plutôt la variante Passive View qui est appliquée.
•    Sens unidirectionnel (dans l’idéal, la Vue est totalement passive)


             Vue                            Presenter                           Modèle

•
•   Le Presenter met à jour la Vue.
•    Sens bidirectionnel


             Vue                            Presenter                           Modèle

•   Le Presenter communique avec la Vue et la Vue communique avec le Presenter. Il existe un
    lien étroit.
•   Dans les deux sens, il n’y a pas de communication directe entre le Modèle et la Vue.



                                                Celinio Fernandes                              No. 51
Le design pattern MVP (5/5)
•    Différences avec MVC ?


               Vue                                                                Modèle


                                                         Contrôleur



•   Le Contrôleur gère les actions de l’utilisateur.
•   La Vue peut accéder au Modèle directement.



                 Vue                                       Presenter               Modèle


•   La Vue gère les actions de l’utilisateur (via le Presenter).
•   La Vue n’interagit pas avec le Modèle.



                                                              Celinio Fernandes             No. 52
Bonnes
pratiques
L’EventBus (1/5)
       •   Le but du bus d’évènements est de permettre à des objets de « souscrire » à certains évènements du
           bus.
•    C’est un singleton. On peut créer plusieurs bus, par fonctionnalité.
•    Par exemple un bus pour traiter les évènements liés à la navigation seulement, un autre bus pour
     transmettre des messages …

•    Pour créer un bus, on peut étendre la classe com.google.gwt.event.shared.EventBus.SimpleEventBus

•    Permet un couplage lâche puisqu’il permet aux objets d’interagir sans avoir de dépendances directes les
     uns envers les autres.

• Est utilisé par l’API Activities and Places.

•    Exemples d’utilisation :
           •   Affichage d’une barre de notification lorsqu’un traitement démarre ou se termine.
           •   Redirection vers un écran de login lors d’un timeout de session, après un appel à un service RPC




                                                               Celinio Fernandes                                  No. 54
L’EventBus (2/5)
• Une instance unique d’un EventBus est transmise aux composants qui interagissent avec.




                    Composant 1                   Composant 2                   Composant 3




                 Event                 Event                  Event
                   +                     +                      +                   etc…
                Handler               Handler                Handler
                                                    EventBus



                 Composant 4                     Composant 5                    Composant 6


                                                    Celinio Fernandes                         No. 55
L’EventBus (3/5)
•   Création d’un évènement
     import com.google.gwt.event.shared.GwtEvent;
     public class MessageEvent extends GwtEvent<MessageEventHandler> {
              public static final Type<MessageEventHandler> TYPE = new Type<MessageEventHandler>();
              private final String message;

             public MessageEvent(final String pMessage) {
                             super();
                             message = pMessage;
             }

             @Override
             protected void dispatch(MessageEventHandler handler) {
                              handler.onMessageRecu(this);
             }

             @Override
             public Type<MessageEventHandler> getAssociatedType() {
                             return TYPE;
             }

             public String getMessage() {
                               return message;
             }
     }




                                                                      Celinio Fernandes               No. 56
L’EventBus (4/5)
•   Création d’un handler d’évènement
           import com.google.gwt.event.shared.EventHandler;
           import com.google.gwt.event.shared.GwtEvent.Type;
           import com.google.gwt.user.client.Window;

           public class MessageEventHandler implements EventHandler {
             public static final Type<MessageEventHandler> TYPE = new Type<MessageEventHandler>();

                public MessageEventHandler() {
                }
                /**
                * Affichage d'une alerte lors de la réception d'un message
                *
                * @param messageEvent
               */
               public void onMessageRecu(final MessageEvent messageEvent) {
                               Window.alert(messageEvent.getMessage());
               }
           }




                                              Celinio Fernandes                                      No. 57
L’EventBus (5/5)
•   Classe com.google.gwt.event.shared.EventBus
•   2 méthodes principales :
     •    <H> HandlerRegistration addHandler(Event.Type<H> type, H handler)
     Ajoute un handler (à l’EventBus) pour recevoir des évènements de ce type de toutes les sources.

     private void ecouterEvents() {
          GWT.log("attachement des events");
          this.eventBus.addHandler(MessageEvent.TYPE, new MessageEventHandler());
     }


     •    abstract void fireEvent(GwtEvent<?> event)
     Déclenche l'évènement passé en paramètre, pour les handlers qui écoutent ce type d'évènement


     private final MessageEvent messageEvent = new MessageEvent(« ATTENTION !!!");
     …
     eventBus.fireEvent(messageEvent);


     Cet EventBus est par exemple passé en paramètre à la méthode start() d’une activity.




                                               Celinio Fernandes                                       No. 58
Activities and Places (1/8)
• Une API pour la navigation et pour la gestion de l’historique. Apparu dans la version 2.1.
• Adéquat pour mettre en place une architecture basée sur le design pattern MVP.
• Ne pas confondre « Activities and Places » avec MVP :
 on peut implémenter MVP sans « Activities and Places » et on peut utiliser « Activities and
  Places » sans MVP.

• Explications officielles :
  http://code.google.com/webtoolkit/doc/latest/DevGuideMvpActivitiesAndPlaces.html



• API complexe

• Bonne façon de commencer :
http://code.google.com/p/google-web-toolkit/downloads/detail?name=Tutorial-hellomvp-2.1.zip




                                         Celinio Fernandes                                     No. 59
Activities and Places (2/8)
–Les objets concernés
          • La vue : La partie graphique associée à une activité.
          • L’activité : c’est le presenter. L’interface du presenter est définie dans l’interface de la vue qui
             lui est associée.
          • La place : un objet Java qui représente un état bookmarkable de l’application. Utilisée pour
             l’historique. C’est l’endroit (la page) où l’on se trouve dans l’application.
          • Un PlaceHistoryMapper pour déclarer les places qu’on souhaite historiser (boutons Précédent
             et Suivant) dans l’application. Est lié à PlaceHistoryHandler qui permet le mapping bi-
             directionnel entre les places et l’URL (qui contient le token de la Place appelée).
          • Un PlaceController : gère le changement de places.
          • Un ActivityManager : détermine l’activité à lancer pour une place donnée. Il utilise un
             ActivityMapper. Un ActivityManager par zone est une bonne idée.
          • L’EventBus : est passé dans les activities et les vues. Il dispatche des évènements vers les
             parties intéressées.
          • Une ClientFactory : non requis mais bonne pratique. Utilisée pour l’injection
  d’objets tels que l’EventBus, le PlaceController, les vues …




                                                     Celinio Fernandes                                             No. 60
Activities and Places (3/8)
– La vue
   public interface HelloView extends IsWidget
   {
     void setName(String helloName);
      void setPresenter(Presenter listener);

       public interface Presenter
       {
                  void goTo(Place place);
       }
   }


   • Hérite de IsWidget
   • Généralement une vue est mappée à un presenter. Les vues
     complexes peuvent avoir plusieurs presenters.
   • setPresenter(…) permet une communication bi-
     directionnelle


                                                 Celinio Fernandes   No. 61
Activities and Places (4/8)
– L’activity (presenter)

  public class HelloActivity extends AbstractActivity implements
  HelloView.Presenter {
    …
    public void goTo(Place place) {
                 clientFactory.getPlaceController().goTo(place);
    }
  }



    • Elle étend AbstractActivity
    • Elle implémente l’interface déclarée dans la vue
    • Le PlaceController est injecté dans l’activité


                                             Celinio Fernandes     No. 62
Activities and Places (5/8)
– Méthodes du cycle de vie d’une activity
   • public void start(AcceptsOneWidget containerWidget, EventBus
     eventBus)
       – est appelée lors du retour de l’activity par l’ActivityMapper
       – seule méthode obligatoire si on étend AbstractActivity


   • public String mayStop()
       – est appelée avant que l’utilisateur quitte l’activity
       – retourne un message pour prévenir l’utilisateur, sinon rien


   • public void onCancel()
       • est appelée si l’utilisateur change d’activity avant le retour de la méthode
         start(…)

   • public void onStop()
       • est appelée lorsque l’activity se termine (quand on quitte la page ou qu’une
         autre activity la remplace)


                                      Celinio Fernandes                                 No. 63
Activities and Places (6/8)
    – La place
•      public class GoodbyePlace extends Place {
         private String goodbyeName;

           public GoodbyePlacetoken) {
             this.goodbyeName = token;
           }

           public String getGoodbyeName() {
             return goodbyeName;
           }

           public static class Tokenizer implements PlaceTokenizer< GoodbyePlace > {
             @Override
             public String getToken(GoodbyePlace place) {
               return place.getGoodbyeName();
             }

               @Override
               public GoodbyePlace getPlace(String token) {
                 return new GoodbyePlace token);
               }
           }
       }


       •       Une place hérite de com.google.gwt.place.shared.Place

                                                              Celinio Fernandes        No. 64
Activities and Places (7/8)
– Par défaut l’URL est de la forme
http://127.0.0.1:8888/HelloMVP.html#{NomPlace}:T
  oken
où
     • {NomPlace} : par défaut le nom de la classe de la place.
       Peut être changé à l’aide de l’annotation @Prefix

     • Token : le token retourné par PlaceTokenizer

http://127.0.0.1:8888/HelloMVP.html#GoodbyePlace:World!



                                      Celinio Fernandes           No. 65
Activities and Places (8/8)
– PlaceHistoryMapper

 @WithTokenizers( {
    HelloPlace.Tokenizer.class,
    GoodbyePlace.Tokenizer.class,
    RapportPlace.Tokenizer.class
 })
 public interface AppPlaceHistoryMapper extends PlaceHistoryMapper {
 }



   • Non obligatoire. Si une place n’est pas déclarée, il n’y a
     pas d’historique pour cette place et le bouton
     « Précédent » du navigateur est désactivé.



                                                 Celinio Fernandes     No. 66
Optimisation avec le code splitting
                                      (1/2)
– Chargement à la demande
               • Par défaut, tout le code JavaScript est compilé en un seul fichier qui est téléchargé au
                 chargement de la page. Ce chargement initial peut être long.
               • Le code splitting consiste à splitter ce fichier JS en plusieurs fichiers JS qui seront téléchargés
                 quand ceux-ci seront appelés.
               • On insère des « split points » dans le code.

  GWT.runAsync(new RunAsyncCallback() {
   @Override
   public void onFailure(Throwable caught) {
     //En cas d'échec du téléchargement du nouveau code
     Window.alert("Echec du téléchargement du JavaScript");
   }

    @Override
    public void onSuccess() {
       //Ce code est téléchargé au moment où il est appelé
      Window.alert("Chargement à la demande ");
    }
  });




                                                              Celinio Fernandes                                        No. 67
Optimisation avec le code splitting
                               (2/2)
– Les fichiers JavaScript générés sont placés dans le répertoire defferedjs

– Il convient de placer les split points à des endroits judicieux.

– Avec Activities and Places, on peut par exemple faire du code splitting au niveau de
  l’ActivityManager en créant un wrapper autour de la classe AbstractActivity, avec l’interface
  AsyncProvider<T,F>.
  Ce wrapper renvoie une activité quand elle est appelée. Son code n’est donc pas chargé au
  démarrage de l’application.




                                                 Celinio Fernandes                                No. 68
Autres bonnes pratiques (1/2)
• Ne pas mélanger GWT avec d’autres frameworks, pour la partie présentation.
• GWT ne doit pas être utilisé que pour créer des widgets mais aussi pour gérer la
  navigation, l’historique, l’internationalisation, la validation etc.
• Créer des composants personnalisés réutilisables
• Packager les ressources avec un client bundle




                                         Celinio Fernandes                           No. 69
Autres bonnes pratiques (2/2)
         • Créer des classes chargées de gérer les callbacks (allège le code, permet de réutiliser les
           callbacks …) des services RPC.
•   public class FindAllVillesCallBack implements AsyncCallback<List<VilleRechercheDto>> {
•        ...
•        public void onFailure(Throwable caught) {
•                            eventBus.fireEvent(finishSearchVillesEvent);
•                            if (caught instanceof AccesInterditExceptionDto) {
•                                               view.accesDenied();
•                            }
•                            else if (caught instanceof InvocationException) {
•                                               GWT.log("FindAllVillesCallBack : InvocationException *****" + caught.getMessage());
•                                               return;
•                            }
•                            else if (caught instanceof NotFoundExceptionDto) {
•                                               view.noData();
•                            } else {
•                                               GWT.log("FindAllVillesCallBack: une erreur technique s'est produite : " + caught);
•                            }
•        }
•        public void onSuccess(List<VilleRechercheDto> result) {
•                            GWT.log("FindAllVillesCallBack : onSuccess****************");
•                            view.setData(result);
•                            eventBus.fireEvent(finishSearchVillesEvent);
•        }
•     }

•        private final ManageVilleServiceAsync manageVilleServiceProxy;
•        manageVilleServiceProxy.findAllVilles(new FindAllDVillesCallBack(view, eventBus, finishSearchVillesEvent));



                                                                    Celinio Fernandes                                                 No. 70
Non couvert
•   Request Factory : alternative à GWT RPC
•   Internationalisation
•   Ressources bundles / client bundle : mettre en cache des ressources
    (fichiers, images, CSS …)
•   JSNI (JavaScript Native Inteface) : support pour JavaScript natif (inclure du
    code JavaScript dans du code Java).
•   Tests : GWTTestCase
•   Deferred binding (liaison différée) :
     • pour l’insertion d’une classe à la compilation, pas au runtime.
     • pour créer plusieurs implémentations (une par browser) de la même fonctionnalité
     • GWT.create(Class) instancie une classe via le deferred binding
•   Speed Tracer : mesurer les performances
•   Gin : GWT Injection, framework IoC pour GWT, côté client
•   Guice : framework d’injection de dépendances
•   etc …




                                          Celinio Fernandes                               No. 71
Conclusion
Librairies tierces
       • SmartGWT : Remplace GWT-Ext. Type de licence : open source LGPL.
C’est un wrapper de SmartClient (les composants encapsulent le code JavaScript SmartClient, en utilisant JSNI).
       http://gwt-ext.com/
       http://www.smartclient.com/smartgwt/showcase/
       • Sencha GXT (Ext GWT) : Sencha est le créateur du framework JavaScript Ext JS. Ce n’est pas un
           wrapper de Ext JS, les composants sont natifs c.a.d. écrits en Java. Types de licences : GPL et
           commercial.
       http://www.sencha.com/products/gxt/
       https://developers.google.com/web-toolkit/tools/gwtdesigner/features/gwt/gxt
       • GWT-Ext : wrapper autour de Ext JS. N’est plus maintenu par Sencha.
       • etc …


      • Questions à se poser :
1.   Peut-on mélanger ces widgets avec les widgets de base de GWT ?
2.   Open source ou commerciale ?
3.   Performances ? Composants plus riches mais performances plus faibles par rapport à GWT de base ?
      • Etude comparative de quelques widgets entre Sencha GXT et GWT :
      http://gxtvsgwt.appspot.com/
       Les widgets Sencha seraient 2 à 10 fois moins rapides que celles de GWT de base.



                                                      Celinio Fernandes                                           No. 73
Dart : la menace ?
•   Dart : créé en 2011 par Google. Certains développeurs GWT travaillent maintenant sur
    Dart.
•   Nouveau langage, avec une syntaxe proche d’un mélange entre C et Java. Produit du
    JavaScript.
•   Google IO 2012 (3 jours, fin juin) :
       • 2 sessions GWT seulement, pour l’instant (fin mai) : "Migrating Code from GWT to Dart" et
          "The History and Future of Google Web Toolkit"
       • Déjà au moins 4 sessions Dart de prévues
    https://developers.google.com/events/io/sessions




Source : http://www.dartlang.org/support/faq.html#future-for-GWT
– Version 2.5 de GWT contiendrait une grosse surprise ! 

                                               Celinio Fernandes                                     No. 74
Pour aller plus loin
–   Livres

     • En anglais :
GWT in Action, 2nd édition (prévue en août 2012)

      • En français :
Programmation GWT 2 - Développer des
applications RIA et Ajax avec le Google Web Toolkit
de Sami Jaber (1ère édition, janvier 2010).
Deuxième édition prévue en juin 2012.




–   Liens

https://developers.google.com/web-toolkit/doc/latest/DevGuide
https://developers.google.com/web-toolkit/doc/latest/DevGuideMvpActivitiesAndPlaces
http://groups.google.com/group/Google-Web-Toolkit



                                                Celinio Fernandes                     No. 75
Merci
•   Celinio Fernandes

Contenu connexe

Tendances

20091020 - Normandy Jug - Builders Battle
20091020 - Normandy Jug - Builders Battle20091020 - Normandy Jug - Builders Battle
20091020 - Normandy Jug - Builders BattleArnaud Héritier
 
20090615 - Ch'ti JUG - Apache Maven
20090615 - Ch'ti JUG - Apache Maven20090615 - Ch'ti JUG - Apache Maven
20090615 - Ch'ti JUG - Apache MavenArnaud Héritier
 
20080311 - Paris Vi Master STL TA - Initiation Maven
20080311 - Paris Vi Master STL TA - Initiation Maven20080311 - Paris Vi Master STL TA - Initiation Maven
20080311 - Paris Vi Master STL TA - Initiation MavenArnaud Héritier
 
Présentation Rex GWT 2.0
Présentation Rex GWT 2.0Présentation Rex GWT 2.0
Présentation Rex GWT 2.0Ippon
 
Quand java prend de la vitesse, apache maven vous garde sur les rails
Quand java prend de la vitesse, apache maven vous garde sur les railsQuand java prend de la vitesse, apache maven vous garde sur les rails
Quand java prend de la vitesse, apache maven vous garde sur les railsArnaud Héritier
 
Présentation du retour d'expérience sur Git
Présentation du retour d'expérience sur GitPrésentation du retour d'expérience sur Git
Présentation du retour d'expérience sur GitIppon
 
Présentation Maven
Présentation MavenPrésentation Maven
Présentation MavenSOAT
 
Introduction à GWT - GTI780 & MTI780 - ETS - A09
Introduction à GWT - GTI780 & MTI780 - ETS - A09Introduction à GWT - GTI780 & MTI780 - ETS - A09
Introduction à GWT - GTI780 & MTI780 - ETS - A09Claude Coulombe
 
Nouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et Mobile
Nouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et MobileNouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et Mobile
Nouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et MobileIppon
 
Gwt oxiane-novae-lr
Gwt oxiane-novae-lrGwt oxiane-novae-lr
Gwt oxiane-novae-lroxmed
 
Distribuer une librairie via maven
Distribuer une librairie via mavenDistribuer une librairie via maven
Distribuer une librairie via mavenFranck SIMON
 
Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika
Présentation Gradle au LyonJUG par Grégory Boissinot - ZenikaPrésentation Gradle au LyonJUG par Grégory Boissinot - Zenika
Présentation Gradle au LyonJUG par Grégory Boissinot - ZenikaZenika
 
NightClazz Build Tools & Continuous Delivery Avancé
NightClazz Build Tools & Continuous Delivery AvancéNightClazz Build Tools & Continuous Delivery Avancé
NightClazz Build Tools & Continuous Delivery AvancéZenika
 

Tendances (20)

Gradle_LyonJUG
Gradle_LyonJUGGradle_LyonJUG
Gradle_LyonJUG
 
20091020 - Normandy Jug - Builders Battle
20091020 - Normandy Jug - Builders Battle20091020 - Normandy Jug - Builders Battle
20091020 - Normandy Jug - Builders Battle
 
Sonar-Hodson-Maven
Sonar-Hodson-MavenSonar-Hodson-Maven
Sonar-Hodson-Maven
 
20090615 - Ch'ti JUG - Apache Maven
20090615 - Ch'ti JUG - Apache Maven20090615 - Ch'ti JUG - Apache Maven
20090615 - Ch'ti JUG - Apache Maven
 
20080311 - Paris Vi Master STL TA - Initiation Maven
20080311 - Paris Vi Master STL TA - Initiation Maven20080311 - Paris Vi Master STL TA - Initiation Maven
20080311 - Paris Vi Master STL TA - Initiation Maven
 
Présentation Rex GWT 2.0
Présentation Rex GWT 2.0Présentation Rex GWT 2.0
Présentation Rex GWT 2.0
 
Quand java prend de la vitesse, apache maven vous garde sur les rails
Quand java prend de la vitesse, apache maven vous garde sur les railsQuand java prend de la vitesse, apache maven vous garde sur les rails
Quand java prend de la vitesse, apache maven vous garde sur les rails
 
Présentation du retour d'expérience sur Git
Présentation du retour d'expérience sur GitPrésentation du retour d'expérience sur Git
Présentation du retour d'expérience sur Git
 
Présentation Maven
Présentation MavenPrésentation Maven
Présentation Maven
 
Introduction à GWT - GTI780 & MTI780 - ETS - A09
Introduction à GWT - GTI780 & MTI780 - ETS - A09Introduction à GWT - GTI780 & MTI780 - ETS - A09
Introduction à GWT - GTI780 & MTI780 - ETS - A09
 
Nouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et Mobile
Nouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et MobileNouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et Mobile
Nouveau look pour une nouvelle vie : HTML5, Spring, NoSQL et Mobile
 
gradle_lavajug
gradle_lavajuggradle_lavajug
gradle_lavajug
 
Gradle_BreizJUG
Gradle_BreizJUGGradle_BreizJUG
Gradle_BreizJUG
 
Gwt oxiane-novae-lr
Gwt oxiane-novae-lrGwt oxiane-novae-lr
Gwt oxiane-novae-lr
 
Maven
MavenMaven
Maven
 
Gwt intro-101
Gwt intro-101Gwt intro-101
Gwt intro-101
 
Distribuer une librairie via maven
Distribuer une librairie via mavenDistribuer une librairie via maven
Distribuer une librairie via maven
 
Gradle_BordeauxJUG
Gradle_BordeauxJUGGradle_BordeauxJUG
Gradle_BordeauxJUG
 
Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika
Présentation Gradle au LyonJUG par Grégory Boissinot - ZenikaPrésentation Gradle au LyonJUG par Grégory Boissinot - Zenika
Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika
 
NightClazz Build Tools & Continuous Delivery Avancé
NightClazz Build Tools & Continuous Delivery AvancéNightClazz Build Tools & Continuous Delivery Avancé
NightClazz Build Tools & Continuous Delivery Avancé
 

En vedette

Basics of Ext JS
Basics of Ext JSBasics of Ext JS
Basics of Ext JSikhwanhayat
 
La régence de Marie-Christine
La régence de Marie-ChristineLa régence de Marie-Christine
La régence de Marie-Christinexosea
 
La Seconde République
La Seconde RépubliqueLa Seconde République
La Seconde Républiquexosea
 
Une modernisation économique lente et inégale
Une modernisation économique lente et inégaleUne modernisation économique lente et inégale
Une modernisation économique lente et inégalexosea
 
Société et industrialisation (1830-1930)
Société et industrialisation (1830-1930)Société et industrialisation (1830-1930)
Société et industrialisation (1830-1930)xosea
 
La dictature de Primo de Rivera
La dictature de Primo de RiveraLa dictature de Primo de Rivera
La dictature de Primo de Riveraxosea
 
Un régime de notables
Un régime de notablesUn régime de notables
Un régime de notablesxosea
 
Le "Sexenio" démocratique
Le "Sexenio" démocratiqueLe "Sexenio" démocratique
Le "Sexenio" démocratiquexosea
 
La guerre civile
La guerre civileLa guerre civile
La guerre civilexosea
 
Régénération et échec du système
Régénération et échec du systèmeRégénération et échec du système
Régénération et échec du systèmexosea
 
"Desarrollismo" et crise politique
"Desarrollismo" et crise politique"Desarrollismo" et crise politique
"Desarrollismo" et crise politiquexosea
 
Le premier franquisme
Le premier franquismeLe premier franquisme
Le premier franquismexosea
 
La Restauration
La RestaurationLa Restauration
La Restaurationxosea
 
La transition démocratique
La transition démocratiqueLa transition démocratique
La transition démocratiquexosea
 
Repère affichage cinquième
Repère affichage cinquièmeRepère affichage cinquième
Repère affichage cinquièmeCéline Langlet
 
Programando en flash
Programando en flashProgramando en flash
Programando en flashLuis Palomino
 
III Workshop Google Analytics para Ejecutivos de Marketing
III Workshop Google Analytics para Ejecutivos de MarketingIII Workshop Google Analytics para Ejecutivos de Marketing
III Workshop Google Analytics para Ejecutivos de MarketingNeo Consulting
 

En vedette (20)

Basics of Ext JS
Basics of Ext JSBasics of Ext JS
Basics of Ext JS
 
Extjs
ExtjsExtjs
Extjs
 
La régence de Marie-Christine
La régence de Marie-ChristineLa régence de Marie-Christine
La régence de Marie-Christine
 
La Seconde République
La Seconde RépubliqueLa Seconde République
La Seconde République
 
Une modernisation économique lente et inégale
Une modernisation économique lente et inégaleUne modernisation économique lente et inégale
Une modernisation économique lente et inégale
 
Société et industrialisation (1830-1930)
Société et industrialisation (1830-1930)Société et industrialisation (1830-1930)
Société et industrialisation (1830-1930)
 
La dictature de Primo de Rivera
La dictature de Primo de RiveraLa dictature de Primo de Rivera
La dictature de Primo de Rivera
 
Un régime de notables
Un régime de notablesUn régime de notables
Un régime de notables
 
Le "Sexenio" démocratique
Le "Sexenio" démocratiqueLe "Sexenio" démocratique
Le "Sexenio" démocratique
 
La guerre civile
La guerre civileLa guerre civile
La guerre civile
 
Régénération et échec du système
Régénération et échec du systèmeRégénération et échec du système
Régénération et échec du système
 
"Desarrollismo" et crise politique
"Desarrollismo" et crise politique"Desarrollismo" et crise politique
"Desarrollismo" et crise politique
 
Le premier franquisme
Le premier franquismeLe premier franquisme
Le premier franquisme
 
La Restauration
La RestaurationLa Restauration
La Restauration
 
La transition démocratique
La transition démocratiqueLa transition démocratique
La transition démocratique
 
Repère affichage cinquième
Repère affichage cinquièmeRepère affichage cinquième
Repère affichage cinquième
 
ACCOSS Lettre Circulaire n˚2015-0000042 - stagiaire
ACCOSS Lettre Circulaire n˚2015-0000042 - stagiaireACCOSS Lettre Circulaire n˚2015-0000042 - stagiaire
ACCOSS Lettre Circulaire n˚2015-0000042 - stagiaire
 
Guide pratique du créateur - APCE 2015 07
Guide pratique du créateur - APCE 2015 07Guide pratique du créateur - APCE 2015 07
Guide pratique du créateur - APCE 2015 07
 
Programando en flash
Programando en flashProgramando en flash
Programando en flash
 
III Workshop Google Analytics para Ejecutivos de Marketing
III Workshop Google Analytics para Ejecutivos de MarketingIII Workshop Google Analytics para Ejecutivos de Marketing
III Workshop Google Analytics para Ejecutivos de Marketing
 

Similaire à Presentation of GWT 2.4 (PowerPoint version)

Présentation DevoxxFR 2015 sur GWT
Présentation DevoxxFR 2015 sur GWTPrésentation DevoxxFR 2015 sur GWT
Présentation DevoxxFR 2015 sur GWTDNG Consulting
 
JavaScript dans l'usine logicielle
JavaScript dans l'usine logicielleJavaScript dans l'usine logicielle
JavaScript dans l'usine logiciellejollivetc
 
Présentation GWT et HTML 5 pour l'Offline
Présentation GWT et HTML 5 pour l'OfflinePrésentation GWT et HTML 5 pour l'Offline
Présentation GWT et HTML 5 pour l'OfflineDNG Consulting
 
20091006 Dev Forum Fr 001Introduction à GWT en utilisant AppCase SDK
20091006 Dev Forum Fr 001Introduction à GWT en utilisant AppCase SDK20091006 Dev Forum Fr 001Introduction à GWT en utilisant AppCase SDK
20091006 Dev Forum Fr 001Introduction à GWT en utilisant AppCase SDKGreenIvory
 
SLIDES-625.1.1-IDL-4-build tools maven.pdf
SLIDES-625.1.1-IDL-4-build tools maven.pdfSLIDES-625.1.1-IDL-4-build tools maven.pdf
SLIDES-625.1.1-IDL-4-build tools maven.pdfArouNa3
 
GWT Approfondissement - GTI780 & MTI780 - ETS - A09
GWT Approfondissement  - GTI780 & MTI780 - ETS - A09GWT Approfondissement  - GTI780 & MTI780 - ETS - A09
GWT Approfondissement - GTI780 & MTI780 - ETS - A09Claude Coulombe
 
Gtug2 Mobile app with web technlogy
Gtug2 Mobile app with web technlogyGtug2 Mobile app with web technlogy
Gtug2 Mobile app with web technlogySacha Leprêtre
 
Être productif avec JHipster - Devoxx France 2017
Être productif avec JHipster - Devoxx France 2017Être productif avec JHipster - Devoxx France 2017
Être productif avec JHipster - Devoxx France 2017Julien Dubois
 
Paris Container Day 2016 : Cloudunit v2 (Treeptik)
Paris Container Day 2016 : Cloudunit v2 (Treeptik)Paris Container Day 2016 : Cloudunit v2 (Treeptik)
Paris Container Day 2016 : Cloudunit v2 (Treeptik)Publicis Sapient Engineering
 
Play framework - Human Talks Grenoble - 12.02.2013
Play framework - Human Talks Grenoble - 12.02.2013Play framework - Human Talks Grenoble - 12.02.2013
Play framework - Human Talks Grenoble - 12.02.2013Xavier NOPRE
 
Presentation du socle technique Java open source Scub Foundation
Presentation du socle technique Java open source Scub FoundationPresentation du socle technique Java open source Scub Foundation
Presentation du socle technique Java open source Scub FoundationStéphane Traumat
 

Similaire à Presentation of GWT 2.4 (PowerPoint version) (20)

Présentation DevoxxFR 2015 sur GWT
Présentation DevoxxFR 2015 sur GWTPrésentation DevoxxFR 2015 sur GWT
Présentation DevoxxFR 2015 sur GWT
 
Devoxx fr
Devoxx frDevoxx fr
Devoxx fr
 
JavaScript dans l'usine logicielle
JavaScript dans l'usine logicielleJavaScript dans l'usine logicielle
JavaScript dans l'usine logicielle
 
Gdd07 Gwt Dig
Gdd07 Gwt DigGdd07 Gwt Dig
Gdd07 Gwt Dig
 
gradle_nantesjug
gradle_nantesjuggradle_nantesjug
gradle_nantesjug
 
Présentation GWT et HTML 5 pour l'Offline
Présentation GWT et HTML 5 pour l'OfflinePrésentation GWT et HTML 5 pour l'Offline
Présentation GWT et HTML 5 pour l'Offline
 
Gwt final
Gwt finalGwt final
Gwt final
 
Gradle_ToulouseJUG
Gradle_ToulouseJUGGradle_ToulouseJUG
Gradle_ToulouseJUG
 
20091006 Dev Forum Fr 001Introduction à GWT en utilisant AppCase SDK
20091006 Dev Forum Fr 001Introduction à GWT en utilisant AppCase SDK20091006 Dev Forum Fr 001Introduction à GWT en utilisant AppCase SDK
20091006 Dev Forum Fr 001Introduction à GWT en utilisant AppCase SDK
 
SLIDES-625.1.1-IDL-4-build tools maven.pdf
SLIDES-625.1.1-IDL-4-build tools maven.pdfSLIDES-625.1.1-IDL-4-build tools maven.pdf
SLIDES-625.1.1-IDL-4-build tools maven.pdf
 
GWT Approfondissement - GTI780 & MTI780 - ETS - A09
GWT Approfondissement  - GTI780 & MTI780 - ETS - A09GWT Approfondissement  - GTI780 & MTI780 - ETS - A09
GWT Approfondissement - GTI780 & MTI780 - ETS - A09
 
SVN to GitHUb
SVN to GitHUbSVN to GitHUb
SVN to GitHUb
 
Gradle_ToursJUG
Gradle_ToursJUGGradle_ToursJUG
Gradle_ToursJUG
 
Gtug2 Mobile app with web technlogy
Gtug2 Mobile app with web technlogyGtug2 Mobile app with web technlogy
Gtug2 Mobile app with web technlogy
 
Être productif avec JHipster - Devoxx France 2017
Être productif avec JHipster - Devoxx France 2017Être productif avec JHipster - Devoxx France 2017
Être productif avec JHipster - Devoxx France 2017
 
Paris Container Day 2016 : Cloudunit v2 (Treeptik)
Paris Container Day 2016 : Cloudunit v2 (Treeptik)Paris Container Day 2016 : Cloudunit v2 (Treeptik)
Paris Container Day 2016 : Cloudunit v2 (Treeptik)
 
GWT no-dto
GWT no-dtoGWT no-dto
GWT no-dto
 
Play framework - Human Talks Grenoble - 12.02.2013
Play framework - Human Talks Grenoble - 12.02.2013Play framework - Human Talks Grenoble - 12.02.2013
Play framework - Human Talks Grenoble - 12.02.2013
 
Présentation1
Présentation1Présentation1
Présentation1
 
Presentation du socle technique Java open source Scub Foundation
Presentation du socle technique Java open source Scub FoundationPresentation du socle technique Java open source Scub Foundation
Presentation du socle technique Java open source Scub Foundation
 

Presentation of GWT 2.4 (PowerPoint version)

  • 2. Présentation de Google Web Toolkit • GWT (version 2.4) • Celinio Fernandes • juin 2012
  • 3. Sommaire • Introduction • Design pattern • Historique MVP • Principe • Création d’un projet • Mode développement • Bonnes pratiques • L’EventBus • Les widgets • Widget composite • L’API Activities and • UiBinder Places • Le code splitting • Events et handlers • Les services distants RPC • Conclusion Celinio Fernandes
  • 5. Historique – Créé en 2006 par Bruce Johnson et Joel Webber – Rachat par Google de la startup créée par Bruce Johnson – Version 1.0 en 2006 – Version 1.5 en 2008 – Version 2.0 en 2009 – Version 2.1 en 2010 (Activities and Places, Request Factory – une alternative à GWT RPC) – Version 2.2 en 2011 (update du widget CellTable) – Version 2.4 en septembre 2011 – Version 2.5 prévue en 2012 (un SuperDevMode ?) – Release notes : https://developers.google.com/web-toolkit/release-notes Celinio Fernandes No. 5
  • 6. Chronologie des frameworks Source : https://github.com/mraible/history-of-web-frameworks-timeline Celinio Fernandes
  • 7. A quelle catégorie de frameworks appartient GWT ? • Catégorisation possible : – basés sur des requêtes : • Struts, Spring MVC, Wicket – basés sur des composants : • JSF, Tapestry, Vaadin – RIA : • Flex, JavaFX GWT un mix des deux dernières catégories ? • génère du code qui tourne côté client donc basé sur des composants ? • utilise des widgets donc RIA ? Celinio Fernandes No. 7
  • 8. Principe • Un framework qui propose d’écrire une application en Java et de compiler ce code Java vers du HTML et du JavaScript nativement interprétable par les navigateurs web. Client Java JavaScript Compilateur GWT Services RPC Serveur Services Java Partie cliente : le code Java qui est au final compilé en JavaScript et qui est exécuté dans un browser. • N’utilisé, côté client, que des librairies de l’API Java qui peuvent être compilées en JavaScript • Emulation partielle de JRE (java.lang.*, java.util.*, etc…) Celinio Fernandes No. 8
  • 9. Plugin GWT pour Eclipse (1/3) • Renommé Google Plugin • Installation facile via l’URL • http://dl.google.com/eclipse/plugin/3.7 • (Eclipse 3.7 Indigo) • Permet de créer un projet GWT sous Eclipse • Permet de lancer une application en mode « developpement » Celinio Fernandes No. 9
  • 10. Plugin GWT pour Eclipse (2/3) Application sample (1) Application sample (2) Celinio Fernandes
  • 11. Plugin GWT pour Eclipse (3/3) Application sample (3) Application sample (4) Celinio Fernandes
  • 12. Structure d’un projet / module GWT •Fichier de configuration du module : LabGWT.gwt.xml •Package client : code Java compilé en JavaScript (si spécifié par le tag <source> du fichier de configuration) •Package server : code Java non compilé en JavaScript •Package shared : code Java commun au client et au serveur. Compilé en JavaScript (si spécifié par le tag <source> du fichier de configuration) •Point d’entrée : LabGWT.java public void onModuleLoad() équivalent du main() en C/C++/Java. •Page HTML d’accueil : LabGWT.html. Elle inclut le fichier JavaScript généré, <module>.nocache.js, dans un tag <script> : <script type="text/javascript" language="javascript" src="labgwt/labgwt.nocache.js"></script> Celinio Fernandes No. 12
  • 13. Fichiers JavaScript générés • Les fichiers JavaScript générés sont présent dans le classpath. • Ils sont par défaut obfuscated. C’est un format compressé (pas de retour à la ligne, pas d’espace, noms des fonctions changés, etc) qui accélère les temps de chargement. Celinio Fernandes
  • 14. Création d’un projet GWT avec Maven (1/2) Le plugin gwt-maven-plugin permet de générer un squelette de projet GWT Celinio Fernandes
  • 15. Création d’un projet GWT avec Maven (2/2) • Problème : • Archétype : • Classes non trouvées. Faire un mvn install d’abord. • mvn archetype:generate Puis copier-coller des classes générées suivantes : • -DarchetypeRepository=repo1.maven.org • /target/generated- • -DarchetypeGroupId=org.codehaus.mojo sources/gwt/foo/client/GreetingServiceAsync.java • -DarchetypeArtifactId=gwt-maven-plugin • /target/generated- • -DarchetypeVersion=2.4.0 sources/gwt/foo/client/Messages.java • vers /src/main/java/foo/client • http://mojo.codehaus.org/gwt-maven- plugin/user-guide/archetype.html • Dépendances Maven : <dependency> <groupId>com.google.gwt</groupId> <artifactId>gwt-servlet</artifactId> <version>2.4</version> <scope>runtime</scope> </dependency> <dependency> <groupId>com.google.gwt</groupId> <artifactId>gwt-user</artifactId> <version>2.4</version> <scope>provided</scope> </dependency> Celinio Fernandes
  • 16. Création d’un projet GWT avec Spring Roo (1/3) • Version standalone de Roo. Pas besoin de SpringSource Tool Suite (STS). • Un exemple standard, Expenses, intègre GWT : • Roo> script expenses.roo • Roo > exit Celinio Fernandes No. 16
  • 17. Création d’un projet GWT avec Spring Roo (2/3) Celinio Fernandes No. 17
  • 18. Création d’un projet GWT avec Spring Roo (3/3) • Projet importable dans Eclipse. • L’exemple Expenses utilise « Activities and Places ». • Autre commande Roo : • Roo > web gwt setup • Documentation officielle : • http://static.springsource.org/spring-roo/reference/html/base-gwt.html Celinio Fernandes
  • 19. Mode développement (1/3) • Le mode developpement permet de tester l’application dans le browser sans avoir besoin de compiler en JavaScript. • Apporte une plus grande productivité. Les modifications au niveau de l’UI sont visibles immédiatement, après refresh. • Requiert l’installation du plugin GWT Developer pour le browser (Firefox, Internet Explorer, Chrome …). • URL se termine avec gwt.codesvr=127.0.0.1:9997. Par exemple : http://127.0.0.1:8888/LabGWT.html?gwt.cod esvr=127.0.0.1:9997 Celinio Fernandes No. 19
  • 20. Mode développement (2/3) • Mode développement ou hosted • Mode web ou production • Le code Java est traduit en • Utilisé dans la phase de JavaScript développement • Déploiement sur le serveur • Le code client n’est pas traduit en • Application plus rapide JavaScript • Possibilité de debugger • Les messages de log sont affichés dans une fenêtre de log • Utilise par défaut un serveur embarqué : Jetty • Evite la compilation de l’application et le déploiement sur le serveur Celinio Fernandes
  • 21. Mode developpement (3/3) • Pour lancer le mode developpement avec le plugin Maven : <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>gwt-maven-plugin</artifactId> • goal gwt:run <version>2.4.0</version> <executions> • goal gwt:debug <execution> <goals> <goal>compile</goal> <goal>test</goal> <goal>i18n</goal> <goal>generateAsync</goal> </goals> </execution> </executions> <!-- Plugin configuration. There are many available options, see gwt-maven-plugin documentation at codehaus.org --> <configuration> <runTarget>labGWT2.html</runTarget> <hostedWebapp>${webappDirectory}</hostedWebapp> <i18nMessagesBundle>foo.client.Messages</i18nMessagesBundle> </configuration> </plugin> Celinio Fernandes No. 21
  • 23. Les widgets (1/7) • Widget = composant graphique • Les composants graphiques générés sont du code HTML. • On peut utiliser l’arbre DOM directement, même s’il vaut mieux utiliser les widgets et leurs propriétés : Button button= new Button(); DOM.setStyleAttribute(button.element, " backgroundColor", "blue"); DOM.setStyleAttribute(button.element, " border", " 1px solid "); • Dans la hiérarchie des classes des Widgets, la classe mère est com.google.gwt.user.client.ui.UIObject. • http://google-web-toolkit.googlecode.com/svn/javadoc/2.4/com/google/gwt/user/client/ui/UIObject.html • Sous-classes directes de UIObject : • MenuItem • MenuItemSeparator • TreeItem • Widget Celinio Fernandes No. 23
  • 24. Les widgets (2/7) • Sous-classes directes de com.google.gwt.user.client.ui.Widget : • AbstractNativeScrollbar : classe parente abstraite pour les scrollbars • CellWidget • Composite : pour créer des widgets personnalisés • FileUpload : widget qui wrap le tag HTML <input type="type"> • FocusWidget • Frame • Hidden • Hyperlink • Image • LabelBase • MenuBar • Panel : classe abstraite de base pour les panels (widgets qui contiennent d’autres widgets) • Tree : contient une hiérarchie de TreeItems Celinio Fernandes No. 24
  • 25. Les widgets (3/7) • Quelques widgets de position (layout) : HorizontalPanel FlowPanel DisclosurePanel VerticalPanel TabLayoutPanel Celinio Fernandes No. 25
  • 26. Les widgets (4/7) • Quelques widgets de saisie : CheckBox RadioButton DatePicker FileUpload Celinio Fernandes No. 26
  • 27. Les widgets (5/7) • Autres widgets : CellTable CellTree Tree Celinio Fernandes No. 27
  • 28. Les widgets (6/7) • Le showcase officiel : une gallerie de widgets avec code source disponible à l’URL http://gwt.google.com/samples/Sh owcase/Showcase.html • Disponible également dans le répertoire samples du SDK. Celinio Fernandes
  • 29. Les widgets (7/7) • Possibilité de créer un widget personnalisé soit en : • sous-classant un widget existant public class DynamicSelectionCell extends SelectionCell { … } • héritant com.google.gwt.user.client.ui.Composite (recommandé) public class MultiSelect extends Composite { public Label lab = new Label(); public TextBox textBox = new TextBox(); public ListBox listBox = new ListBox(); ... public MultiSelect(String caption) { HorizontalPanel panel = new HorizontalPanel(); panel.add(lab); panel.add(listBox); … // All composites must call initWidget() in their constructors. initWidget(panel); } ... } Celinio Fernandes No. 29
  • 30. L’interface UiBinder (1/5) – Façon déclarative de créer des layouts (vues, widgets …) • Un template avec l’extension ui.xml : RapportViewImpl.ui.xml • Code XML – Ne contient pas de logique – Décrit le layout • Une Owner classe de même nom : RapportViewImpl.java • Annotations : @UiField, @UiHandler, @UiTemplate (pour un nom de template différent et/ou avec plusieurs templates), etc… • Utilise UiBinder pour charger le layout • Relie les évènements au code Celinio Fernandes No. 30
  • 31. L’interface UiBinder (2/5) • Owner classe : • public class RapportViewImpl extends Composite implements RapportView { • private static RapportViewImplUiBinder uiBinder = GWT.create(RapportViewImplUiBinder.class); • interface RapportViewImplUiBinder extends UiBinder<Widget, RapportViewImpl> • { • } • @UiField Label lab; • @UiField TabPanel TableauNotes; • @UiField DockPanel monDockPanel; • @UiField Label PremiereNote; • @UiField Label DeuxiemeNote; • @UiField Button boutonHello; … • @UiHandler("boutonHello") • void onBoutonHelloClick(ClickEvent event) { • presenter.goTo(new HelloPlace(nom)); • } • … • } Celinio Fernandes No. 31
  • 32. L’interface UiBinder (3/5) • Template XML: • <!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> • <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" • xmlns:g="urn:import:com.google.gwt.user.client.ui"> • ... • <g:HTMLPanel> • Hello, • <span class="{style.important}" ui:field="nameSpan" /> • <g:DockPanel height="281px" width="448px" ui:field="monDockPanel"> • <g:Dock direction="WEST"> • <g:Label ui:field="lab" text="Rapport a faire" width="120px"></g:Label> • </g:Dock> • <g:Dock direction="SOUTH"> • <g:TabPanel ui:field="TableauNotes"> … </g:TabPanel> • </g:Dock> • <g:Dock direction="WEST"> • <g:Button ui:field="boutonHello" text="Retour à l&apos;accueil"/> • </g:Dock> • </g:DockPanel> • </g:HTMLPanel> • </ui:UiBinder> Celinio Fernandes No. 32
  • 33. L’interface UiBinder (4/5) • Wizard de création sous Eclipse Celinio Fernandes No. 33
  • 34. L’interface UiBinder (5/5) • GWT Designer pour le template Celinio Fernandes No. 34
  • 36. Events et handlers (1/4) – Un évènement (event) peut être : • un clic de bouton (ClickEvent) • un changement dans une listbox (ChangeEvent) • une touche de clavier pressée (KeyDownEvent) • un passage de souris dans une zone (MouseOverEvent) • un défilement (ScrollEvent) • etc… – La classe de base est com.google.gwt.event.shared.GwtEvent Celinio Fernandes No. 36
  • 37. Events et handlers (2/4) • Pour gérer ces évènements, on ajoute des handlers aux widgets. Avec plusieurs possibilités de faire: • en passant par une classe anonyme • en implémentant l’interface du Handler • etc … • Exemples d’interfaces d’handlers : ClickHandler, ChangeHandler, KeyDownHandler, MouseOverHandler, FocusHandler, ValueChangeHandler, SelectionHandler, OpenHandler … • L’interface de base est com.google.gwt.event.shared.EventHandler Celinio Fernandes No. 37
  • 38. Events et handlers (3/4) • Classe Handler anonyme : public void anonClickHandlerExample() { Button b = new Button("Click Me"); b.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { // handle the click event } }); } Celinio Fernandess No. 38
  • 39. Events et handlers (4/4) • Implémentation de l’interface du Handler : public class HandlerExample extends Composite implements ClickHandler { private FlowPanel fp = new FlowPanel(); private Button b1 = new Button("Button 1"); public HandlerExample() { initWidget(fp); fp.add(b1); b1.addClickHandler(this); } public void onClick(ClickEvent event) { Widget sender = (Widget) event.getSource(); … } } – Adéquat pour des handlers complexes (plusieurs boutons, design complexe ..) Celinio Fernandes No. 39
  • 41. Les services RPC (1/6) • Les services RPC (Remote Procedure Call) permettent de faire des appels d’objets entre la partie cliente et la partie serveur. • GWT utilise des services RPC asynchrones pour rendre les applications Web plus interactives. Que veut dire asynchrone ? • Le programme n’attend pas la fin de l’exécution de la méthode pour passer la suite (principe même d’Ajax). Si un service est long, il ne faut pas attendre la réponse et il faut laisser la main au browser. • GWT prend en charge la sérialisation et la désérialisation des objets Java. • GWT utilise des interfaces pour créer un service RPC : • Une interface synchrone qui hérite de com.google.gwt.user.client.rpc.RemoteService, côté client • Une interface asynchrone, côté client • Une classe, côté serveur (= package serveur), qui implémente l’interface synchrone et les méthodes RPC qu’on veut mettre à disposition côté client • Pourquoi des services RPC dans GWT ? • Permettre l’exécution de méthodes côté serveur et qui ne sont pas exécutables côté client (compilation impossible en JavaScript, problème de sécurité …) Celinio Fernandes No. 41
  • 42. Les services RPC (2/6) • Etapes 1. Créer les classes et interfaces RPC côté client 2. Créer l’implémentation côté serveur du service RPC. C’est une servlet qui implémente l’interface synchrone et qui étend RemoteServiceServlet. 3. Faire l’appel du service RPC dans le code 4. Ne pas oublier de modifier le fichier web.xml pour y déclarer la servlet et faire le mapping ! Celinio Fernandes No. 42
  • 43. Les services RPC (3/6) • Diagramme de la plomberie RPC • Source : https://developers.google.com/web-toolkit/doc/latest/DevGuideServerCommunication#DevGuidePlumbingDiagram • Celinio Fernandes No. 43
  • 44. Les services RPC (4/6) • L’interface synchrone (côté client) : @RemoteServiceRelativePath("manageVille") public interface ManageVilleService extends RemoteService { public long getCodePostalVille (String nom) throws VilleNonTrouveeExceptionDto; } • L’interface asynchrone (côté client) : public interface ManageVilleServiceAsync { void getCodePostalVille (String nom, AsyncCallback<long> callback); } • L’implémentation du service (côté serveur) : @RemoteServiceRelativePath("manageVille") public class ManageVilleDelegate extends SpringBeanInjectionRemoteServiceServlet implements ManageVilleService { @Autowired private ManageVille manageVilleApplication; public long getCodePostalVille (String nom) throws VilleNonTrouveeExceptionDto { // appels de services des autres couches / de modules non GWT … … } • Note : @RemoteServiceRelativePath associe le service à un chemin relatif Celinio Fernandes No. 44
  • 45. Les services RPC (5/6) • Appel du service RPC depuis une activity (côte client), par exemple : public class VilleActivity extends AbstractActivity implements VilleView.Presenter { // RPC service proxy private final ManageVille ServiceAsync manageVilleServiceProxy; … manageVilleServiceProxy.getCodePostalVille(String nom, new AsyncCallback<long> () { public void onFailure(Throwable caught) { Window.alert("Problème !!"); } public void onSuccess(long codePostal){ view.setCodePostal(codePostal); } }); …. } • Création d’une classe AsyncCallback anonyme, en paramètre de la méthode asynchrone appelée. Lab GWT No. 45
  • 46. Les services RPC (6/6) • Important : les objets transportés doivent être sérialisables. Les règles de sérialisation diffèrent un peu de celles de l’API Java standard. • https://developers.google.com/web-toolkit/doc/latest/DevGuideServerCommunication?hl=fr- FR#DevGuideSerializableTypes • Problème des entités : • Les entités JPA sont transformées au runtime par Hibernate, pour les rendre persistantes. Hibernate les instrumente en modifiant le bytecode, ce qui pose problème pour l’échange des données entre le client et le serveur à l’aide de la sérialisation. • Solution : • Utiliser le pattern DTO. Les objets de transfert (avec la même structure ou non que les objets persistés) ne sont pas instrumentés et peuvent être rendus sérialisables. • Et utiliser Dozer pour la transformation. Entité Dozer DTO Celinio Fernandes No. 46
  • 47. Design pattern MVP • Model View Presenter
  • 48. Le design pattern MVP (1/5) • Qui connait MVP ? • Permet d’éviter du code spaghetti MVP • • Modèle : les DTOs, les données qui sont affichées • Vue : l’interface graphique • Presenter : équivalent du contrôleur de MVC. Implémente l’accès à la logique métier et au modèle de données. Réagit aux évènements de l’utilisateur et qui sont transmis par la Vue. Celinio Fernandes No. 48
  • 49. Le design pattern MVP (2/5) • Avantages : • Séparation claire entre la partie présentation et la logique métier • Plus grande maintenabilité puisqu’il n’y a presque pas de dépendance avec la logique métier (couplage faible). • Plus facile à tester. On peut mocker la Vue, le Presenter … (Mockito). Celinio Fernandes No. 49
  • 50. Le design pattern MVP (3/5) • Un pattern conceptualisé par Martin Fowler : • http://martinfowler.com/eaaDev/ModelViewPresenter.html • Permet de séparer la logique métier de l’UI. • Deux variantes : Passive View et Supervising Controller • Source : http://msdn.microsoft.com/en-us/library/ff647543.aspx Celinio Fernandes No. 50
  • 51. Le design pattern MVP (4/5) • Dans GWT, c’est plutôt la variante Passive View qui est appliquée. • Sens unidirectionnel (dans l’idéal, la Vue est totalement passive) Vue Presenter Modèle • • Le Presenter met à jour la Vue. • Sens bidirectionnel Vue Presenter Modèle • Le Presenter communique avec la Vue et la Vue communique avec le Presenter. Il existe un lien étroit. • Dans les deux sens, il n’y a pas de communication directe entre le Modèle et la Vue. Celinio Fernandes No. 51
  • 52. Le design pattern MVP (5/5) • Différences avec MVC ? Vue Modèle Contrôleur • Le Contrôleur gère les actions de l’utilisateur. • La Vue peut accéder au Modèle directement. Vue Presenter Modèle • La Vue gère les actions de l’utilisateur (via le Presenter). • La Vue n’interagit pas avec le Modèle. Celinio Fernandes No. 52
  • 54. L’EventBus (1/5) • Le but du bus d’évènements est de permettre à des objets de « souscrire » à certains évènements du bus. • C’est un singleton. On peut créer plusieurs bus, par fonctionnalité. • Par exemple un bus pour traiter les évènements liés à la navigation seulement, un autre bus pour transmettre des messages … • Pour créer un bus, on peut étendre la classe com.google.gwt.event.shared.EventBus.SimpleEventBus • Permet un couplage lâche puisqu’il permet aux objets d’interagir sans avoir de dépendances directes les uns envers les autres. • Est utilisé par l’API Activities and Places. • Exemples d’utilisation : • Affichage d’une barre de notification lorsqu’un traitement démarre ou se termine. • Redirection vers un écran de login lors d’un timeout de session, après un appel à un service RPC Celinio Fernandes No. 54
  • 55. L’EventBus (2/5) • Une instance unique d’un EventBus est transmise aux composants qui interagissent avec. Composant 1 Composant 2 Composant 3 Event Event Event + + + etc… Handler Handler Handler EventBus Composant 4 Composant 5 Composant 6 Celinio Fernandes No. 55
  • 56. L’EventBus (3/5) • Création d’un évènement import com.google.gwt.event.shared.GwtEvent; public class MessageEvent extends GwtEvent<MessageEventHandler> { public static final Type<MessageEventHandler> TYPE = new Type<MessageEventHandler>(); private final String message; public MessageEvent(final String pMessage) { super(); message = pMessage; } @Override protected void dispatch(MessageEventHandler handler) { handler.onMessageRecu(this); } @Override public Type<MessageEventHandler> getAssociatedType() { return TYPE; } public String getMessage() { return message; } } Celinio Fernandes No. 56
  • 57. L’EventBus (4/5) • Création d’un handler d’évènement import com.google.gwt.event.shared.EventHandler; import com.google.gwt.event.shared.GwtEvent.Type; import com.google.gwt.user.client.Window; public class MessageEventHandler implements EventHandler { public static final Type<MessageEventHandler> TYPE = new Type<MessageEventHandler>(); public MessageEventHandler() { } /** * Affichage d'une alerte lors de la réception d'un message * * @param messageEvent */ public void onMessageRecu(final MessageEvent messageEvent) { Window.alert(messageEvent.getMessage()); } } Celinio Fernandes No. 57
  • 58. L’EventBus (5/5) • Classe com.google.gwt.event.shared.EventBus • 2 méthodes principales : • <H> HandlerRegistration addHandler(Event.Type<H> type, H handler) Ajoute un handler (à l’EventBus) pour recevoir des évènements de ce type de toutes les sources. private void ecouterEvents() { GWT.log("attachement des events"); this.eventBus.addHandler(MessageEvent.TYPE, new MessageEventHandler()); } • abstract void fireEvent(GwtEvent<?> event) Déclenche l'évènement passé en paramètre, pour les handlers qui écoutent ce type d'évènement private final MessageEvent messageEvent = new MessageEvent(« ATTENTION !!!"); … eventBus.fireEvent(messageEvent); Cet EventBus est par exemple passé en paramètre à la méthode start() d’une activity. Celinio Fernandes No. 58
  • 59. Activities and Places (1/8) • Une API pour la navigation et pour la gestion de l’historique. Apparu dans la version 2.1. • Adéquat pour mettre en place une architecture basée sur le design pattern MVP. • Ne pas confondre « Activities and Places » avec MVP : on peut implémenter MVP sans « Activities and Places » et on peut utiliser « Activities and Places » sans MVP. • Explications officielles : http://code.google.com/webtoolkit/doc/latest/DevGuideMvpActivitiesAndPlaces.html • API complexe • Bonne façon de commencer : http://code.google.com/p/google-web-toolkit/downloads/detail?name=Tutorial-hellomvp-2.1.zip Celinio Fernandes No. 59
  • 60. Activities and Places (2/8) –Les objets concernés • La vue : La partie graphique associée à une activité. • L’activité : c’est le presenter. L’interface du presenter est définie dans l’interface de la vue qui lui est associée. • La place : un objet Java qui représente un état bookmarkable de l’application. Utilisée pour l’historique. C’est l’endroit (la page) où l’on se trouve dans l’application. • Un PlaceHistoryMapper pour déclarer les places qu’on souhaite historiser (boutons Précédent et Suivant) dans l’application. Est lié à PlaceHistoryHandler qui permet le mapping bi- directionnel entre les places et l’URL (qui contient le token de la Place appelée). • Un PlaceController : gère le changement de places. • Un ActivityManager : détermine l’activité à lancer pour une place donnée. Il utilise un ActivityMapper. Un ActivityManager par zone est une bonne idée. • L’EventBus : est passé dans les activities et les vues. Il dispatche des évènements vers les parties intéressées. • Une ClientFactory : non requis mais bonne pratique. Utilisée pour l’injection d’objets tels que l’EventBus, le PlaceController, les vues … Celinio Fernandes No. 60
  • 61. Activities and Places (3/8) – La vue public interface HelloView extends IsWidget { void setName(String helloName); void setPresenter(Presenter listener); public interface Presenter { void goTo(Place place); } } • Hérite de IsWidget • Généralement une vue est mappée à un presenter. Les vues complexes peuvent avoir plusieurs presenters. • setPresenter(…) permet une communication bi- directionnelle Celinio Fernandes No. 61
  • 62. Activities and Places (4/8) – L’activity (presenter) public class HelloActivity extends AbstractActivity implements HelloView.Presenter { … public void goTo(Place place) { clientFactory.getPlaceController().goTo(place); } } • Elle étend AbstractActivity • Elle implémente l’interface déclarée dans la vue • Le PlaceController est injecté dans l’activité Celinio Fernandes No. 62
  • 63. Activities and Places (5/8) – Méthodes du cycle de vie d’une activity • public void start(AcceptsOneWidget containerWidget, EventBus eventBus) – est appelée lors du retour de l’activity par l’ActivityMapper – seule méthode obligatoire si on étend AbstractActivity • public String mayStop() – est appelée avant que l’utilisateur quitte l’activity – retourne un message pour prévenir l’utilisateur, sinon rien • public void onCancel() • est appelée si l’utilisateur change d’activity avant le retour de la méthode start(…) • public void onStop() • est appelée lorsque l’activity se termine (quand on quitte la page ou qu’une autre activity la remplace) Celinio Fernandes No. 63
  • 64. Activities and Places (6/8) – La place • public class GoodbyePlace extends Place { private String goodbyeName; public GoodbyePlacetoken) { this.goodbyeName = token; } public String getGoodbyeName() { return goodbyeName; } public static class Tokenizer implements PlaceTokenizer< GoodbyePlace > { @Override public String getToken(GoodbyePlace place) { return place.getGoodbyeName(); } @Override public GoodbyePlace getPlace(String token) { return new GoodbyePlace token); } } } • Une place hérite de com.google.gwt.place.shared.Place Celinio Fernandes No. 64
  • 65. Activities and Places (7/8) – Par défaut l’URL est de la forme http://127.0.0.1:8888/HelloMVP.html#{NomPlace}:T oken où • {NomPlace} : par défaut le nom de la classe de la place. Peut être changé à l’aide de l’annotation @Prefix • Token : le token retourné par PlaceTokenizer http://127.0.0.1:8888/HelloMVP.html#GoodbyePlace:World! Celinio Fernandes No. 65
  • 66. Activities and Places (8/8) – PlaceHistoryMapper @WithTokenizers( { HelloPlace.Tokenizer.class, GoodbyePlace.Tokenizer.class, RapportPlace.Tokenizer.class }) public interface AppPlaceHistoryMapper extends PlaceHistoryMapper { } • Non obligatoire. Si une place n’est pas déclarée, il n’y a pas d’historique pour cette place et le bouton « Précédent » du navigateur est désactivé. Celinio Fernandes No. 66
  • 67. Optimisation avec le code splitting (1/2) – Chargement à la demande • Par défaut, tout le code JavaScript est compilé en un seul fichier qui est téléchargé au chargement de la page. Ce chargement initial peut être long. • Le code splitting consiste à splitter ce fichier JS en plusieurs fichiers JS qui seront téléchargés quand ceux-ci seront appelés. • On insère des « split points » dans le code. GWT.runAsync(new RunAsyncCallback() { @Override public void onFailure(Throwable caught) { //En cas d'échec du téléchargement du nouveau code Window.alert("Echec du téléchargement du JavaScript"); } @Override public void onSuccess() { //Ce code est téléchargé au moment où il est appelé Window.alert("Chargement à la demande "); } }); Celinio Fernandes No. 67
  • 68. Optimisation avec le code splitting (2/2) – Les fichiers JavaScript générés sont placés dans le répertoire defferedjs – Il convient de placer les split points à des endroits judicieux. – Avec Activities and Places, on peut par exemple faire du code splitting au niveau de l’ActivityManager en créant un wrapper autour de la classe AbstractActivity, avec l’interface AsyncProvider<T,F>. Ce wrapper renvoie une activité quand elle est appelée. Son code n’est donc pas chargé au démarrage de l’application. Celinio Fernandes No. 68
  • 69. Autres bonnes pratiques (1/2) • Ne pas mélanger GWT avec d’autres frameworks, pour la partie présentation. • GWT ne doit pas être utilisé que pour créer des widgets mais aussi pour gérer la navigation, l’historique, l’internationalisation, la validation etc. • Créer des composants personnalisés réutilisables • Packager les ressources avec un client bundle Celinio Fernandes No. 69
  • 70. Autres bonnes pratiques (2/2) • Créer des classes chargées de gérer les callbacks (allège le code, permet de réutiliser les callbacks …) des services RPC. • public class FindAllVillesCallBack implements AsyncCallback<List<VilleRechercheDto>> { • ... • public void onFailure(Throwable caught) { • eventBus.fireEvent(finishSearchVillesEvent); • if (caught instanceof AccesInterditExceptionDto) { • view.accesDenied(); • } • else if (caught instanceof InvocationException) { • GWT.log("FindAllVillesCallBack : InvocationException *****" + caught.getMessage()); • return; • } • else if (caught instanceof NotFoundExceptionDto) { • view.noData(); • } else { • GWT.log("FindAllVillesCallBack: une erreur technique s'est produite : " + caught); • } • } • public void onSuccess(List<VilleRechercheDto> result) { • GWT.log("FindAllVillesCallBack : onSuccess****************"); • view.setData(result); • eventBus.fireEvent(finishSearchVillesEvent); • } • } • private final ManageVilleServiceAsync manageVilleServiceProxy; • manageVilleServiceProxy.findAllVilles(new FindAllDVillesCallBack(view, eventBus, finishSearchVillesEvent)); Celinio Fernandes No. 70
  • 71. Non couvert • Request Factory : alternative à GWT RPC • Internationalisation • Ressources bundles / client bundle : mettre en cache des ressources (fichiers, images, CSS …) • JSNI (JavaScript Native Inteface) : support pour JavaScript natif (inclure du code JavaScript dans du code Java). • Tests : GWTTestCase • Deferred binding (liaison différée) : • pour l’insertion d’une classe à la compilation, pas au runtime. • pour créer plusieurs implémentations (une par browser) de la même fonctionnalité • GWT.create(Class) instancie une classe via le deferred binding • Speed Tracer : mesurer les performances • Gin : GWT Injection, framework IoC pour GWT, côté client • Guice : framework d’injection de dépendances • etc … Celinio Fernandes No. 71
  • 73. Librairies tierces • SmartGWT : Remplace GWT-Ext. Type de licence : open source LGPL. C’est un wrapper de SmartClient (les composants encapsulent le code JavaScript SmartClient, en utilisant JSNI). http://gwt-ext.com/ http://www.smartclient.com/smartgwt/showcase/ • Sencha GXT (Ext GWT) : Sencha est le créateur du framework JavaScript Ext JS. Ce n’est pas un wrapper de Ext JS, les composants sont natifs c.a.d. écrits en Java. Types de licences : GPL et commercial. http://www.sencha.com/products/gxt/ https://developers.google.com/web-toolkit/tools/gwtdesigner/features/gwt/gxt • GWT-Ext : wrapper autour de Ext JS. N’est plus maintenu par Sencha. • etc … • Questions à se poser : 1. Peut-on mélanger ces widgets avec les widgets de base de GWT ? 2. Open source ou commerciale ? 3. Performances ? Composants plus riches mais performances plus faibles par rapport à GWT de base ? • Etude comparative de quelques widgets entre Sencha GXT et GWT : http://gxtvsgwt.appspot.com/ Les widgets Sencha seraient 2 à 10 fois moins rapides que celles de GWT de base. Celinio Fernandes No. 73
  • 74. Dart : la menace ? • Dart : créé en 2011 par Google. Certains développeurs GWT travaillent maintenant sur Dart. • Nouveau langage, avec une syntaxe proche d’un mélange entre C et Java. Produit du JavaScript. • Google IO 2012 (3 jours, fin juin) : • 2 sessions GWT seulement, pour l’instant (fin mai) : "Migrating Code from GWT to Dart" et "The History and Future of Google Web Toolkit" • Déjà au moins 4 sessions Dart de prévues https://developers.google.com/events/io/sessions Source : http://www.dartlang.org/support/faq.html#future-for-GWT – Version 2.5 de GWT contiendrait une grosse surprise !  Celinio Fernandes No. 74
  • 75. Pour aller plus loin – Livres • En anglais : GWT in Action, 2nd édition (prévue en août 2012) • En français : Programmation GWT 2 - Développer des applications RIA et Ajax avec le Google Web Toolkit de Sami Jaber (1ère édition, janvier 2010). Deuxième édition prévue en juin 2012. – Liens https://developers.google.com/web-toolkit/doc/latest/DevGuide https://developers.google.com/web-toolkit/doc/latest/DevGuideMvpActivitiesAndPlaces http://groups.google.com/group/Google-Web-Toolkit Celinio Fernandes No. 75
  • 76. Merci • Celinio Fernandes