SlideShare une entreprise Scribd logo
1  sur  75
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. 4
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. 6
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. 7
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. 8
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. 11
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. 15
Création d’un projet GWT avec Spring
              Roo (2/3)




             Celinio Fernandes   No. 16
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. 18
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. 20
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. 22
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. 23
Les widgets (3/7)
•     Quelques widgets de position (layout) :

    HorizontalPanel



    FlowPanel



    DisclosurePanel




                                                                    VerticalPanel
    TabLayoutPanel




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



    CheckBox




    RadioButton


                                                            DatePicker



    FileUpload




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



    CellTable




    CellTree                                     Tree




                             Celinio Fernandes          No. 26
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. 28
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. 29
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. 30
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. 31
L’interface UiBinder (4/5)
• Wizard de création sous Eclipse




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




                                  Celinio Fernandes   No. 33
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. 35
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. 36
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. 37
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. 38
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. 40
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. 41
Les services RPC (3/6)
•   Diagramme de la plomberie RPC




•   Source : https://developers.google.com/web-toolkit/doc/latest/DevGuideServerCommunication#DevGuidePlumbingDiagram

                                                              Celinio Fernandes                                         No. 42
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. 43
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. 44
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. 45
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. 47
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. 48
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. 49
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. 50
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. 51
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. 53
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. 54
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. 55
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. 56
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. 57
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. 58
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. 59
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. 60
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. 61
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. 62
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. 63
Activities and Places (7/8)
– Par défaut l’URL est de la forme
http://127.0.0.1:8888/HelloMVP.html#{NomPlace}:Token
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. 64
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. 65
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. 66
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. 67
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. 68
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. 69
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. 70
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. 72
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. 73
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. 74
Merci
Celinio Fernandes

Contenu connexe

Tendances

Uni.sherbrooke 2015 créez la meilleur application grâce à gwt, gwtp et j...
Uni.sherbrooke 2015   créez la meilleur application grâce à gwt, gwtp et j...Uni.sherbrooke 2015   créez la meilleur application grâce à gwt, gwtp et j...
Uni.sherbrooke 2015 créez la meilleur application grâce à gwt, gwtp et j...Arcbees
 
Gwt fast overview_v1
Gwt fast overview_v1Gwt fast overview_v1
Gwt fast overview_v1David Herviou
 
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
 
Introduction à GWT - GTI780 & MTI780 - ETS - A08
Introduction à GWT - GTI780 & MTI780 - ETS - A08Introduction à GWT - GTI780 & MTI780 - ETS - A08
Introduction à GWT - GTI780 & MTI780 - ETS - A08Claude Coulombe
 
20091020 - Normandy Jug - Builders Battle
20091020 - Normandy Jug - Builders Battle20091020 - Normandy Jug - Builders Battle
20091020 - Normandy Jug - Builders BattleArnaud Héritier
 
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
 
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
 
Introduction à GWT - GTI780 & MTI780 - ETS - A09
Introduction à GWT - GTI780 & MTI780 - ETS - A09Introduction à GWT - GTI780 & MTI780 - ETS - A09
Introduction à GWT - GTI780 & MTI780 - ETS - A09Claude Coulombe
 
Gwt oxiane-novae-lr
Gwt oxiane-novae-lrGwt oxiane-novae-lr
Gwt oxiane-novae-lroxmed
 
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
 
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
 

Tendances (20)

Uni.sherbrooke 2015 créez la meilleur application grâce à gwt, gwtp et j...
Uni.sherbrooke 2015   créez la meilleur application grâce à gwt, gwtp et j...Uni.sherbrooke 2015   créez la meilleur application grâce à gwt, gwtp et j...
Uni.sherbrooke 2015 créez la meilleur application grâce à gwt, gwtp et j...
 
Gwt fast overview_v1
Gwt fast overview_v1Gwt fast overview_v1
Gwt fast overview_v1
 
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
 
Introduction à GWT - GTI780 & MTI780 - ETS - A08
Introduction à GWT - GTI780 & MTI780 - ETS - A08Introduction à GWT - GTI780 & MTI780 - ETS - A08
Introduction à GWT - GTI780 & MTI780 - ETS - A08
 
20091020 - Normandy Jug - Builders Battle
20091020 - Normandy Jug - Builders Battle20091020 - Normandy Jug - Builders Battle
20091020 - Normandy Jug - Builders Battle
 
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
 
Gradle_BreizJUG
Gradle_BreizJUGGradle_BreizJUG
Gradle_BreizJUG
 
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
 
Introduction à GWT - GTI780 & MTI780 - ETS - A09
Introduction à GWT - GTI780 & MTI780 - ETS - A09Introduction à GWT - GTI780 & MTI780 - ETS - A09
Introduction à GWT - GTI780 & MTI780 - ETS - A09
 
Gwt oxiane-novae-lr
Gwt oxiane-novae-lrGwt oxiane-novae-lr
Gwt oxiane-novae-lr
 
NightClazz Build Tools & Continuous Delivery Avancé
NightClazz Build Tools & Continuous Delivery AvancéNightClazz Build Tools & Continuous Delivery Avancé
NightClazz Build Tools & Continuous Delivery Avancé
 
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
 
Apache Maven 3
Apache Maven 3Apache Maven 3
Apache Maven 3
 
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
 
Présentation1
Présentation1Présentation1
Présentation1
 

En vedette

BordeauxJUG : Portails &amp; Portlets Java
BordeauxJUG : Portails &amp; Portlets JavaBordeauxJUG : Portails &amp; Portlets Java
BordeauxJUG : Portails &amp; Portlets JavaCamblor Frédéric
 
"La Ligne" - La construction de la LGV SEA en bande-dessinée.
"La Ligne" - La construction de la LGV SEA en bande-dessinée."La Ligne" - La construction de la LGV SEA en bande-dessinée.
"La Ligne" - La construction de la LGV SEA en bande-dessinée.LISEA
 
Resiliency Inventory CA1
Resiliency Inventory CA1Resiliency Inventory CA1
Resiliency Inventory CA1Destiny Devone
 
Travaux de cartographie par l'observatoire socio-économique LISEA
Travaux de cartographie par l'observatoire socio-économique LISEATravaux de cartographie par l'observatoire socio-économique LISEA
Travaux de cartographie par l'observatoire socio-économique LISEALISEA
 
Focus sur plusieurs espèces protégées
Focus sur plusieurs espèces protégéesFocus sur plusieurs espèces protégées
Focus sur plusieurs espèces protégéesLISEA
 
LISEA et LGV SEA - Dossier de presse 2017
LISEA et LGV SEA - Dossier de presse 2017LISEA et LGV SEA - Dossier de presse 2017
LISEA et LGV SEA - Dossier de presse 2017LISEA
 
Ajax en Java - GTI780 & MTI780 - ETS - A09
Ajax en Java - GTI780 & MTI780 - ETS - A09Ajax en Java - GTI780 & MTI780 - ETS - A09
Ajax en Java - GTI780 & MTI780 - ETS - A09Claude Coulombe
 
Portails Etat De L'art
Portails  Etat De L'artPortails  Etat De L'art
Portails Etat De L'artTugdual Grall
 
7 plugins de la communauté à ne pas manquer ! - Liferay France Symposium 2016
7 plugins de la communauté à ne pas manquer ! - Liferay France Symposium 20167 plugins de la communauté à ne pas manquer ! - Liferay France Symposium 2016
7 plugins de la communauté à ne pas manquer ! - Liferay France Symposium 2016Sébastien Le Marchand
 
Être à jour en logiciels de gestion stratégique
Être à jour en logiciels de gestion stratégiqueÊtre à jour en logiciels de gestion stratégique
Être à jour en logiciels de gestion stratégiqueDynacomTechnologies
 
Technical Writing Presentation
Technical Writing PresentationTechnical Writing Presentation
Technical Writing PresentationEmily Flanagan
 
Roller Derby Photo Essay
Roller Derby Photo EssayRoller Derby Photo Essay
Roller Derby Photo EssayAnne Morris
 
Politics_Pain_and_the_Torture_of_the_American_People_May_1_2005
Politics_Pain_and_the_Torture_of_the_American_People_May_1_2005Politics_Pain_and_the_Torture_of_the_American_People_May_1_2005
Politics_Pain_and_the_Torture_of_the_American_People_May_1_2005Aviel Shatz
 
Solutions Linux Développement Rapide Java
Solutions Linux Développement Rapide JavaSolutions Linux Développement Rapide Java
Solutions Linux Développement Rapide JavaLaurent Guérin
 
Programas web
Programas webProgramas web
Programas webtorimary
 

En vedette (20)

BordeauxJUG : Portails &amp; Portlets Java
BordeauxJUG : Portails &amp; Portlets JavaBordeauxJUG : Portails &amp; Portlets Java
BordeauxJUG : Portails &amp; Portlets Java
 
"La Ligne" - La construction de la LGV SEA en bande-dessinée.
"La Ligne" - La construction de la LGV SEA en bande-dessinée."La Ligne" - La construction de la LGV SEA en bande-dessinée.
"La Ligne" - La construction de la LGV SEA en bande-dessinée.
 
Doc1elfines
Doc1elfinesDoc1elfines
Doc1elfines
 
Resiliency Inventory CA1
Resiliency Inventory CA1Resiliency Inventory CA1
Resiliency Inventory CA1
 
Btgwl ashraf uddin
Btgwl ashraf uddinBtgwl ashraf uddin
Btgwl ashraf uddin
 
Travaux de cartographie par l'observatoire socio-économique LISEA
Travaux de cartographie par l'observatoire socio-économique LISEATravaux de cartographie par l'observatoire socio-économique LISEA
Travaux de cartographie par l'observatoire socio-économique LISEA
 
Focus sur plusieurs espèces protégées
Focus sur plusieurs espèces protégéesFocus sur plusieurs espèces protégées
Focus sur plusieurs espèces protégées
 
LISEA et LGV SEA - Dossier de presse 2017
LISEA et LGV SEA - Dossier de presse 2017LISEA et LGV SEA - Dossier de presse 2017
LISEA et LGV SEA - Dossier de presse 2017
 
Ajax en Java - GTI780 & MTI780 - ETS - A09
Ajax en Java - GTI780 & MTI780 - ETS - A09Ajax en Java - GTI780 & MTI780 - ETS - A09
Ajax en Java - GTI780 & MTI780 - ETS - A09
 
Portails Etat De L'art
Portails  Etat De L'artPortails  Etat De L'art
Portails Etat De L'art
 
7 plugins de la communauté à ne pas manquer ! - Liferay France Symposium 2016
7 plugins de la communauté à ne pas manquer ! - Liferay France Symposium 20167 plugins de la communauté à ne pas manquer ! - Liferay France Symposium 2016
7 plugins de la communauté à ne pas manquer ! - Liferay France Symposium 2016
 
Hyper Text Markup Language
Hyper Text Markup LanguageHyper Text Markup Language
Hyper Text Markup Language
 
Être à jour en logiciels de gestion stratégique
Être à jour en logiciels de gestion stratégiqueÊtre à jour en logiciels de gestion stratégique
Être à jour en logiciels de gestion stratégique
 
Technical Writing Presentation
Technical Writing PresentationTechnical Writing Presentation
Technical Writing Presentation
 
Roller Derby Photo Essay
Roller Derby Photo EssayRoller Derby Photo Essay
Roller Derby Photo Essay
 
Politics_Pain_and_the_Torture_of_the_American_People_May_1_2005
Politics_Pain_and_the_Torture_of_the_American_People_May_1_2005Politics_Pain_and_the_Torture_of_the_American_People_May_1_2005
Politics_Pain_and_the_Torture_of_the_American_People_May_1_2005
 
Tingju Zhu, IFPRI
Tingju Zhu, IFPRITingju Zhu, IFPRI
Tingju Zhu, IFPRI
 
Solutions Linux Développement Rapide Java
Solutions Linux Développement Rapide JavaSolutions Linux Développement Rapide Java
Solutions Linux Développement Rapide Java
 
Iceberg
IcebergIceberg
Iceberg
 
Programas web
Programas webProgramas web
Programas web
 

Similaire à Presentation of GWT 2.4 (PDF 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
 
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
 
JavaScript dans l'usine logicielle
JavaScript dans l'usine logicielleJavaScript dans l'usine logicielle
JavaScript dans l'usine logiciellejollivetc
 
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
 
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
 
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
 
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
 
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
 
Chaine de production pipeline
Chaine de production   pipelineChaine de production   pipeline
Chaine de production pipelineNicolas wallerand
 

Similaire à Presentation of GWT 2.4 (PDF 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
 
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
 
JavaScript dans l'usine logicielle
JavaScript dans l'usine logicielleJavaScript dans l'usine logicielle
JavaScript dans l'usine logicielle
 
Gradle_ToulouseJUG
Gradle_ToulouseJUGGradle_ToulouseJUG
Gradle_ToulouseJUG
 
Gdd07 Gwt Dig
Gdd07 Gwt DigGdd07 Gwt Dig
Gdd07 Gwt Dig
 
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
 
Gradle_ToursJUG
Gradle_ToursJUGGradle_ToursJUG
Gradle_ToursJUG
 
Gwt final
Gwt finalGwt final
Gwt final
 
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
 
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
 
SVN to GitHUb
SVN to GitHUbSVN to GitHUb
SVN to GitHUb
 
Gtug2 Mobile app with web technlogy
Gtug2 Mobile app with web technlogyGtug2 Mobile app with web technlogy
Gtug2 Mobile app with web technlogy
 
Gwt intro-101
Gwt intro-101Gwt intro-101
Gwt intro-101
 
Ê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
 
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
 
GWT no-dto
GWT no-dtoGWT no-dto
GWT no-dto
 
Chaine de production pipeline
Chaine de production   pipelineChaine de production   pipeline
Chaine de production pipeline
 

Presentation of GWT 2.4 (PDF version)

  • 1. Présentation de Google Web Toolkit GWT (version 2.4) Celinio Fernandes juin 2012
  • 2. 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
  • 4. 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. 4
  • 5. Chronologie des frameworks Source : https://github.com/mraible/history-of-web-frameworks-timeline Celinio Fernandes
  • 6. 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. 6
  • 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. 7
  • 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. 8
  • 9. Plugin GWT pour Eclipse (2/3) Application sample (1) Application sample (2) Celinio Fernandes
  • 10. Plugin GWT pour Eclipse (3/3) Application sample (3) Application sample (4) Celinio Fernandes
  • 11. 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. 11
  • 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
  • 13. 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
  • 14. 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
  • 15. 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. 15
  • 16. Création d’un projet GWT avec Spring Roo (2/3) Celinio Fernandes No. 16
  • 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
  • 18. 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. 18
  • 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
  • 20. 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. 20
  • 22. 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. 22
  • 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. 23
  • 24. Les widgets (3/7) • Quelques widgets de position (layout) : HorizontalPanel FlowPanel DisclosurePanel VerticalPanel TabLayoutPanel Celinio Fernandes No. 24
  • 25. Les widgets (4/7) • Quelques widgets de saisie : CheckBox RadioButton DatePicker FileUpload Celinio Fernandes No. 25
  • 26. Les widgets (5/7) • Autres widgets : CellTable CellTree Tree Celinio Fernandes No. 26
  • 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
  • 28. 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. 28
  • 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. 29
  • 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. 30
  • 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. 31
  • 32. L’interface UiBinder (4/5) • Wizard de création sous Eclipse Celinio Fernandes No. 32
  • 33. L’interface UiBinder (5/5) • GWT Designer pour le template Celinio Fernandes No. 33
  • 35. 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. 35
  • 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. 36
  • 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. 37
  • 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. 38
  • 40. 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. 40
  • 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. 41
  • 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. 42
  • 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. 43
  • 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. 44
  • 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. 45
  • 46. Design pattern MVP • Model View Presenter
  • 47. 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. 47
  • 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. 48
  • 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. 49
  • 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. 50
  • 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. 51
  • 53. 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. 53
  • 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. 54
  • 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. 55
  • 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. 56
  • 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. 57
  • 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. 58
  • 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. 59
  • 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. 60
  • 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. 61
  • 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. 62
  • 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. 63
  • 64. Activities and Places (7/8) – Par défaut l’URL est de la forme http://127.0.0.1:8888/HelloMVP.html#{NomPlace}:Token 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. 64
  • 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. 65
  • 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. 66
  • 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. 67
  • 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. 68
  • 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. 69
  • 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. 70
  • 72. 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. 72
  • 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. 73
  • 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. 74