10/04/23 2
Plan
Introduction GWT Des IHM avec GWT Des IHM avec GWT + Communiquer avec le
serveur Internationalisation I18n
Plan
Développer un composant graphique Historique du navigateur Logging Tester avec JUNIT Divers principes avancées
JavaScript overlay types Intégrer une appli GWT dans JavaScript Code Splitting Étendre la JRE Émulation Sérialisation spécifique Compile Reports
10/04/23 4
Partie 1
Introduction AJAX et XHTTPR Inconvénients du développement en JavaScript GWT comme solution
GWT SDK GWT Structure et configuration d’une application GWT Exécuter et débuguer un projet GWT en mode
développement Compiler et Déployer un projet GWT
Ateliers : Se familiariser avec l’environnement de développement GWT
10/04/23 5
AJAX
Ajax pour Asynchronous JavaScript & XML Réaliser des requêtes asynchrones au serveur et effectuer
la mise à jour de certaines parties de la page Web sans faire un rechargement complet
Fini le pénible rechargement de pages! Applications Web plus réactives et plus dynamiques Applications Web semblables à des applications
bureautiques en exécution locale (Desktop Like)
Basé sur du code-client en JavaScript CSS (Cascading Style Sheet) pour la présentation API DOM (Document Object Model) pour accéder et
modifier les éléments de la page JavaScript pour les traitements sur le poste client
10/04/23 6
En mode synchrone, le navigateur est gelé en attendant la réponse du serveur.
Diagramme de séquence - WEB standard
10/04/23 7
En mode asynchrone, l'exécution dans le navigateur se poursuit sans attendre la réponse du serveur. La réponse sera traitée par une fonction de retour (fonction Callback) quand elle arrivera.
Diagramme de séquence – Application AJAX
10/04/23 8
L’intérêt d’une architecture Ajax
10/04/23 9
XHTTPR pour XMLHttpRequest Il permet d’effectuer des échanges de
données XML, JSON, TEXT avec le serveur de façon asynchrone
Inventé par Microsoft en 1998 pour son navigateur IE
Adopté par les autres éditeurs à partir de 2002
Standardisé par le W3C en 2007
XHTTPR
10/04/23 10
XHTTPR
Méthodes : setRequestHeader(name, value) open(method, url, asynchronous, userName, password) send(data) abort()
Propriété readyState : 1 : méthode open invoqué avec succès 2 : méthode send invoqué avec succès 3 : la réponse est en cours de réception 4 : la réponse est complètement chargé
onreadystatechange event listener, permet de réagir à chaque changement de la valeur de la propriété readyState.
10/04/23 11
Création de l’objet XHTTPR
10/04/23 12
XHTTPR Appel & Callback
10/04/23 13
XHTTPR Appel & Callback
10/04/23 14
Inconvénients du développement en JavaScript
Problèmes de compatibilité entre les différents navigateurs
Ne fonctionne pas si JavaScript est désactivé
Les données chargées de façon dynamique ne sont pas indexées par les moteurs de recherche
Si le traitement du côté serveur est long, le traitement asynchrone d'Ajax fait que les changements se font avec un délai
Le bouton de retour en arrière ne marche pas, l'URL ne change pas et les signets ne fonctionnent pas.
Les appels Ajax ne peuvent se faire en dehors du domaine chargé initialement
10/04/23 15
Inconvénients du développement en JavaScript
Exigeant en ressources sur le poste client
Rareté des experts en JavaScript
JS n'est pas un véritable langage à objets
Pas de typage statique
Sensible à la moindre coquille
Quelques subtilités : « null » vs « undefined »
Débogage à l'exécution pas à la compilation
JS n'a pas été conçu pour de gros logiciels, mais juste pour mettre un peu d'interactivité dans une page web
10/04/23 16
GWT comme solution
GWT pour Google Web Toolkit
Créé en 2006 par Bruce Johnson & Joel Webber et racheté par Google
Open source sous licence Apache 2
Version actuelle est la 2.5.1
10/04/23 17
Principe GWT
GWT propose d’écrire une application WEB en java et de compiler ce code java en HTML et JavaScript nativement interprétable par le navigateur
Seul le code java de la partie cliente est compilé en JavaScript et HTML. Émulation partielle de la JRE (java.lang.*, java.util.*, …) N’utilise coté client que des API java qui peuvent être compilées en JavaScript
10/04/23 18
Avantages GWT
Développement rapide d'applications RIA par des programmeurs Java qui ne maîtrisent pas JavaScript
Le développement se fait en pur Java, ce qui permet les contrôles de cohérence à la compilation (contrairement à JavaScript qui est interprété) et de profiter de la puissance d’un language OO.
Utilisation de puissants IDEs java (Eclipse, NetBeans, IntelliJ) Débogueur Éditeur de code intelligent Industrialisation et Re-factorisation de code Analyse du code
Simplification de la phase de test par le support de JUnit & Selenium
10/04/23 19
Avantages GWT
Communication client-server basés sur des objets Java
Ne requiert aucun plugin pour le navigateur
Génère des applications Single page
Gestion de l'historique de navigation
Bibliothèque OO de composants IUG Semblable à SWING ou AWT
10/04/23 20
Avantages GWTTranscompilateur Java génère du JavaScript optimisé et compatible multi navigateur, «Write Once, Run Anywhere»
10/04/23 21
SDK GWT
10/04/23 22
GWT API
10/04/23 23
Transcompilateur JAVALe Transcompilateur JAVA est la pièce maîtresse de GWT, son rôle est de traduire le code client JAVA en code JavaScript optimisé
10/04/23 24
Transcompilateur JAVA JAVA AST Optimized java AST
Pruning : suppression des classes, interfaces, méthodes et attributs non référencés.
Finalizing : rendre les méthodes, les classes et variables final si c’est possible.
Make static : rendre static les méthodes d’instances si possible
Type Tightening : optimisation des attributs et paramètres pour les rendre concrets (réduire les opérateurs de cast et instanceof)
Method Call Tightening : Changement des appels de méthodes polymorphiques, en appel direct.
Dead code elimination : suppression des portions de code jamais utilisés.
Method inlining : suppression des méthodes non référencés dans une classe extérieure, et si la méthode ne dépasse pas 2 lignes embarquement de son code directement dans la méthode appelante.
10/04/23 25
Transcompilateur JAVA JAVA AST Optimized java AST
Same Parameter value Otimizer : détecte si une chaîne de caractères est utilisé comme paramètre de méthode, supprime le paramètre est utilise la chaîne directement dans le code
Remove empty super calls
Set of normalization rules : transformation du code pour que la génération du JavaScript soit optimal
Fusion des blocs catch Utilisation des arrays Remplacement des appels aux classes JDK par les classes
com.google.gwt.lang
Pruning : un deuxième passage après les changements au niveau du code
10/04/23 26
Transcompilateur JAVA
Le code JavaScript généré est par défaut obfuscated, c’est un format compressé qui accélère le temps de chargement au niveau du navigateur
10/04/23 27
Émulation JRE
Le Transcompilateur GWT comprend une API qui émule certaines classes de le JRE java
A noter que pour certaines classes seulement un sous-ensemble de méthode est pris en charge.
Java.lang Java.lang.annotation Java.math Java.io Java.sql Java.util Java.util.logging
Pour la liste complète des classes java et des méthodes supportés par l’émulation JRE,
consulter l’url : http://www.gwtproject.org/doc/latest/RefJreEmulation.html
10/04/23 28
Structure d’une application GWT
10/04/23 29
Structure d’une application GWT
GWTLab.gwt.xml : fichier de configuration de l’application (c’est l’élément de base du Transcompilateur)
configuration des librairies GWT du projet configuration de l'internationalisation configuration des navigateurs cibles configuration des points d'entrées de l'application ...
Package client : code client java à compiler en JavaScript (spécifié par le tag <source> dans le fichier de configuration)
Code de l'UI graphique et de son comportement Code Java à transcrire en JavaScript
Package server : code serveur java non compilé en JavaScript (traitements serveur)
Code de la partie serveur traitements des données et des échanges avec les clients
Code Java à compiler en Bytecode
10/04/23 30
Structure d’une application GWT
Package shared : code java commun au deux parties client et serveur, compilé en Javascript si spécifié par le tag <source>
Code qui sert en tant qu’intermédiaire entre les parties client et serveur, essentiellement en tant que DTO
/war : dossier contenant les ressources statiques Images Fichiers CSS Fichiers JavaScript
GWTLab.htm : La page d’entrée de l’application Contient le script généré GWTLab.nocache.js Charge dynamiquement l'application (JavaScript & HTML) spécifique
au navigateur
10/04/23 31
myApp.gwt.xml
10/04/23 32
myApp.gwt.xml
Module : déclaration inherits : utilisation d’autres modules entry-point : classe de démarrage de l’application source : code java à transcrire public : dossier à rendre public (accessible depuis le
navigateur) extend-property : extension d’une propriete existante
(utilisé lors du deffered binding) set-property : affection d’un valeur à une propriété
user.agent : ie6, ie8, safari, gecko1_8, safari, opera Locale : par défaut « default » …
Nombres d'applications résultantes {user.agent}x{locale} = 6 permutations par défaut
10/04/23 33
MyApp.htm
10/04/23 34
MyApp.htm
Page home de l’application
Page HTML standard Doit contenir une référence au fichier JavaScript
moduleName.nocache.js, responsable du chargement de la classe entrypoint définie au niveau du fichier de configuration .gwt.xml
10/04/23 35
Processus de développement
10/04/23 36
Deux modes d’exécution
Mode développement (dev mode) la JVM exécute le code GWT comme du byte code
Java à l'intérieur d'une fenêtre de navigateur Web Permet de profiter du débogage JAVA
Mode production (web mode) L’application est exécuté en tant JavaScript et HTML
généré à partir du code JAVA
10/04/23 37
Exécuter et débuguer un projet GWT en mode développement (dev mode)
Permet de tester l’application dans le navigateur sans avoir besoin de la compiler en JavaScript
Apporte une plus grande productivité, toute modification au niveau de l’UI est visible immédiatement après un simple refresh (Hot swap).
Nécessite l’installation du plugin « GWT Develloper » pour le navigateur cible
10/04/23 38
Compiler un projet GWT
Une fois testé en « dev mode », vous pouvez compiler votre code source Java en JavaScript et déployer votre application Web
Une application Web GWT qui a été déployée est dite en « web mode »
Une fois compilé le code-client est uniquement du pur JavaScript et du HTML
Afin de déployer l’ application Web en production, déplacez les fichiers du répertoire « war » sur le serveur Web, i.e. Tomcat ou Apache.
10/04/23 39
Compiler un projet GWT
10/04/23 40
Partie 2
Des IHM avec GWT La classe EntryPoint Structurer une page IHM avec des panels Les composants graphiques (GWT Widgets) Ajouter des composants graphiques à une page IHM Utiliser des feuilles de styles CSS Valider des données saisies Réagir aux actions utilisateurs
Ateliers : Développer une interface de saisie pour l’état civil d’une personne
10/04/23 41
La classe EntryPoint
EntryPoint, classe qui représente le point d’entrée de l’application (La classe main pour un programme java)
Implémente l’interface com.google.gwt.core.client.EntryPoint en définissant la méthode onLoadModule(), qui est automatiquement invoqué lors du démarrage de l’application
Elle doit obligatoirement offrir un constructeur sans arguments
Elle doit être déclaré dans le fichier de configuration .gwt.xml
<entry-point class='com.gwtlab.client.GWTLab'/>
10/04/23 42
Structurer une page IHM avec des panels
RootPanel : représente l’élément body de la page HTML principale RootPanel.get() : accès à l'élément <body> de l'arbre
DOM RootPanel.getId(String id) : accès à l'élément id du
DOM
Window : est l’équivalent de son homonyme en JavaScript.
10/04/23 43
Structurer une page IHM avec des panels
Structurer une page IHM avec des panels
Panel Type
AbsolutePanel DIV
DeckPanel DIV
DisclosurePanel TABLE
DockPanel TABLE
FlowPanel DIV
FocusPanel DIV
FormPanel DIV
Frame IFRAME
Structurer une page IHM avec des panels
Panel Type
HorizontalPanel TABLE
HorizontalSplitPanel DIV
HTMLPanel DIV
ScrollPanel DIV
StackPanel TABLE
TabPanel TABLE
VerticalPanel TABLE
VerticalSplitPanel DIV
10/04/23 46
Structurer une page IHM avec des panels
Panneaux de disposition simple : panneau en file (FlowPanel), panneau horizontal (Horizontal Panel), panneau vertical (VerticalPanel), panneau à coulisse (HorizontalSplitPanel, VerticalSplitPanel), panneau HTML (HTMLPanel), panneau superposé (DeckPanel)
Panneaux de disposition complexe : table flexible (FlexTable),grille (Grid), panneau polyptyque (DockPanel), panneau à onglets (TabPanel), panneau en pile (StackPanel)
Panneaux conteneurs simples : panneau composite ou composite (Composite) panneau simple (SimplePanel), panneau à barre de défilement (ScrollPanel), panneau de focus (FocusPanel)
Panneaux conteneurs complexes : panneau de formulaire (FormPanel), panneau à dévoilement (DisclosurePanel), panneau surprise (PopupPanel), boîte de dialogue (DialogBox)
Structurer une page IHM avec des panels
A partir de la version 2.0 de nouveaux panels, les Layout Panels
Des panels pour simplifier la conception de l’aspect général de l’application.
LayoutPanel, DockLayoutPanel, SplitLayoutPanel, StackLayoutPanel, TabLayoutPanel
Les Widgets
Widget = Composant graphique
Les composants graphiques sont traduits en HTML lors de la compilation JavaScript
La classe com.google.gwt.user.client.ui.UIObject est la classe mère de toutes les widgets.
Pour changer le comportement des widgets on peut intervenir directement sur l’arbre DOM, mais il vaut mieux utiliser les méthodes et propriétés des widgets
10/04/23 49
Les composants graphiques (GWT Widgets)
Tous ce que l'on peut trouver en HTML button, radiobox, checkbox, listbox, textbox,
textarea...
Des éléments plus complexes Datepicker Tree MenuBar DisclosurePanel
10/04/23 50
Les composants graphiques (GWT Widgets)
Éléments statiques: étiquette (Label), HTML, Image, hyperlien (Hyperlink), champ caché (Hidden)
Widgets (E/S) : bouton (Button), bouton poussoir (PushButton), bouton à bascule (ToggleButton), case à cocher (CheckBox), bouton radio (RadioButton), menu déroulant (ListBox), zone de texte (TextBox), zone de texte avec suggestions (SuggestBox), zone d'entrée de mot de passe (PasswordTextBox), zone de texte multiligne (TextArea), zone d'édition de texte enrichi (RichTextArea)
Widgets complexes : arbre (Tree), barre de menus (MenuBar), téléchargement de fichiers (FileUpload)
10/04/23 51
Ajouter des composants graphiques à une page IHM
10/04/23 52
Utiliser des feuilles de styles CSS
Déclarer la feuille de style dans le fichier de configuration .gwt.xml
<stylesheet src="styles.css"/>
Fichier CSS :.gwt-Widget {
background-color:black;color:lime;
}
Code Java :widget.setStyleName(“gwt-Widget”);
widget.addStyleName(“gwt-Widget”);
10/04/23 53
Utiliser des feuilles de styles CSS
Faire varier facilement l'apparence en fonction de l'état du composant
Code Java : (usage de CSS primaire et dépendant)Widget w = new Widget();w.setStylePrimaryName("widgetStyle");w.addStyleDependentName("selected");
Fichier CSS :.widgetStyle {
background-color:black;color:lime;
}
.widgetStyle .widgetStyle -selected {color:red;
}
10/04/23 54
Valider des données saisies
GWT offre la possibilité d’utiliser la JSR-303 Bean validation pour contrôler et valider les données saisies par l’utilisateur.
10/04/23 55
Valider des données saisies
Intégrer les API suivantes dans le classpath: validation-api-1.0.0.GA.jar (déjà incluse dans le SDK GWT)
validation-api-1.0.0.GA-sources.jar (déjà incluse dans le SDK GWT)
hibernate-validator-4.1.0.Final.jar hibernate-validator-4.1.0.Final-sources.jar slf4j-api-1.6.1.jar (utilisé par Hibernate Validator)
slf4j-log4j12-1.6.1.jar (utilisé par Hibernate Validator)
log4j-1.2.16.jar (utilisé par Hibernate Validator)
10/04/23 56
Valider des données saisies
Créer une factory Validator en héritant de la classe com.google.gwt.validation.client.AbstractGwtValidatorFactory
Cette classe sert à identifier la liste des classes qui peuvent être validés au niveau du navigateur
10/04/23 57
Valider des données saisies
Déclarer le validator au niveau du fichier .gwt.xml
<inherits name="org.hibernate.validator.HibernateValidator" /> <replace-with class="SampleValidatorFactory">
<when-type-is
class="javax.validation.ValidatorFactory" /> </replace-with>
Valider un bean :Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); Set<ConstraintViolation<Person>> violations = validator.validate(person);
10/04/23 58
Réagir aux actions utilisateurs
Programmation principalement Évènementielle
com.google.gwt.event.shared.GwtEvent : l'objet représentant l'évènement déclenché
com.google.gwt.event.shared.EventHandler : définition du comportement à déclencher sur évènement
com.google.gwt.event.shared.HandlerRegistration : gère l'abonnement d'un EventHandler à un Event
10/04/23 59
Réagir aux actions utilisateurs
GWT utilise le concept de récepteur ou gestionnaire (handelr interface) pour traiter les événements
Semblable à d'autres types d'applications graphiques comme SWING, AWT
Button b = new Button("Send");HandlerRegistration hr = b.addClickHandler(new
ClickHandler() {@Overridepublic void onClick(ClickEvent event) {
Window.alert("OK");}
});
10/04/23 60
Réagir aux actions utilisateurs
Click – déclenché quand l'usager clique un élément Blur – déclenché quand un élément perd le focus du
clavier Change - déclenché quand le contenu de la saisie
change Focus – déclenché quand un élément reçoit le focus
clavier KeyDown – déclenché quand l'usager appuie sur une
touche KeyUp – déclenché quand l'usager relâche une
touche KeyPress – déclenché quand un caractère est généré MouseOver – déclenché quand la souris passe au-
dessus
10/04/23 61
Réagir aux actions utilisateurs
MouseMove – déclenché quand la souris entre dans la zone
MouseOut – déclenché quand la souris sort de la zone
Scroll – déclenché quand un élément avec défilement bouge
OnLoad – déclenché quand un élément termine de se charger
DblClick – déclenché quand l'usager double-clique
Atelier 1
En se basant sur la structure fournie, réaliser l’atelier suivant : Ajouter un menu avec deux entrée
Nouvel user Consulter user
Un écran de saisie pour les infos user boutons sauvegarder et fermer
Un écran de consultation pour les infos user
Atelier 2
Compléter l’atelier 1 : Menu Nouvel user affiche l’écran de saisie Écran de saisie
Sauvegarder : Valide les données et affiche les
messages d’erreurs en haut de l’écran de saisie en rouge
affiche un message de confirmation et redirige vers l’écran de consultation
Fermer : ferme l’écran de saisie
10/04/23 64
Partie 3
Des IHM avec GWT + Internationalisation I18n Accès au ressources Intégrer du JavaScript dans une appli GWT
(JSNI) Séparer la présentation d’une IHM de sa
dynamique (UiBinder) GWT Widgets avancés (Cell Widgets) Pattern MVP
Ateliers : Transformer l'atelier 2 en appliquant le pattern MVP et le UIBinder
10/04/23 65
Internationalisation I18n
GWT offre un mécanisme pour gérer l’internationalisation basés sur des fichiers de propriétés et en respectant le standard java L’internationalisation est effectué de façon
statique pendant la compilation du code JAVA en code JavaScript lors de la génération des permutations
com.google.gwt.i18n.client.Constants : permet de gérer des chaînes de caractères statiques
com.google.gwt.i18n.client.Messages : permet de gérer des chaînes de caractères avec paramètres
Internationalisation I18n
Ajouter <inherits name="com.google.gwt.i18n.I18N"/> au niveau du fichier de configuration .gwt.xml
Ajouter <extend-property name="locale" values="…"/> pour spécifier les langues que va gérer l’application
Spécifier la langue par défaut de l’application <set-property-fallback name="locale" value="en"/>
10/04/23 67
Internationalisation I18n
MyConstants.properties, MyConstants.properties_eshelloWorld = …goodbyeWorld = …
Créer une interface qui étend l’interface com.google.gwt.i18n.client.Constants
Les fichiers properties et l’interface doivent être dans le même package
10/04/23 68
Internationalisation I18n
MyMessages.propertiespermissionDenied = Error {0}: User {1} Permission
denied.
Créer une interface qui étend l’interface com.google.gwt.i18n.client.Messages
Les fichiers properties et l’interface doivent être dans le même package
Internationalisation I18n
Pour charger une langue spécifique http://www.example.org/myapp.html?locale=fr_CA
Accès au ressourcesClientBundle
ClientBundle permet de grouper des ressources de différents types images, feuilles CSS, ressources binaires et autres.
TextResource : fournit une méthode getText() qui retourne le contenu sous forme de String ;
DataResource : fournit une méthode getUrl() qui retourne une URL absolue donnant accès à la ressource;
CssResource : permet de manipuler une ressource CSS; ImageResource : permet d’obtenir des informations sur
l’image, et son URL. L’avantage est de limiter le nombre de téléchargements,
ce qui réduit l’overhead causé par un grand nombre de téléchargements.
Pour utiliser le ClientBundle <inherits name="com.google.gwt.resources.Resources" />
Accès au ressourcesClientBundle
10/04/23 72
Intégrer du JavaScript dans une classe java GWT (JSNI)
JSNI pour JavaScript Native Interface
Permet d’intégrer directement du code JavaScript dans une classe Java.
Permet de faire communiquer du code JAVA et du code JavaScript
Facilite l'intégration des bibliothèques JavaScript externes.
Une méthode JavaScript peut être invoqué dans du code JAVA de façon standard
10/04/23 73
Intégrer du JavaScript dans une classe java GWT (JSNI)
Une méthode JSNI peut être static ou d’instance
La méthode JSNI est déclaré native et le code est inséré entre deux accolades
visibilite native typeRetour methodName(params)/*-{
code javascript }-*/
Intégrer du JavaScript dans une classe java GWT (JSNI)
Pour invoquer une méthode java dans une méthode JSNI [instance-expr.]@class-name::method-
name(param-signature)(arguments)
Pour accéder aux attributs static ou d’instance[instance-expr.]@class-name::field-name
Pour accéder aux objets JavaScript Window et Document, utiliser respectivement $win et $doc
L’invocation de la méthode JSNI au sein du code JAVA est faite de façon normale
Intégrer du JavaScript dans une classe java GWT (JSNI)
10/04/23 76
Séparer la présentation d’une IHM de sa dynamique UiBinder
Outil de conception d‘IHM à partir d'une représentation XML, sans programmation
Facilite le découplage de l’IHM entre la disposition du contenu en XML le code du comportement en Java et l'apparence gouvernée par des feuilles de style CSS
Un template XML avec l’extension ui.xml : MyView.ui.xml Code xml et/ou HTML qui décrit l’affichage Ne contient pas de logique
Une classe propriétaire du même nom : MyView.java Gère la dynamique de l’IHM et associe les événements
aux composants
10/04/23 77
Séparer la présentation d’une IHM de sa dynamique UiBinder
UIBinder<U, O> : classe responsable de faire la liaison entre le template XML et la classe propriétaire. U : le type de l’élément root du template XML O : la classe propriétaire
Pour initialiser la liaison :
Séparer la présentation d’une IHM de sa dynamique UiBinder
@UIField : associe un composant déclaré dans la classe à son correspondant au niveau du template xml.
@UIHandler : associe une méthode de la classe à un événement d’un composant
@UITemplate("view.ui.xml") : permet d’associer une classe à une template autre que celui par défaut.
10/04/23 79
Séparer la présentation d’une IHM de sa dynamique UiBinder
10/04/23 80
Séparer la présentation d’une IHM de sa dynamique UiBinder
10/04/23 81
GWT Widgets avancés (Cell Widgets)
Les cells widgets (data presentation widgets) sont des widgets spécialisé dans l’affichage de grandes quantités de données : Liste : CellTable Tables : DataGrid Arbre : CellTree Navigateur : CellBrowser
A la différence des autres widgets qui gèrent un arbre DOM pour afficher une liste de String par exemple, Cell n’utilise qu’un seul objet DOM pour toute la liste.
10/04/23 82
GWT Widgets avancés (Cell Widgets)
Injecter des données via une listeCellList<String> cellList = new CellList<String>(textCell);
cellList.setRowData(0, DAYS);
Injecter des données via un dataProvider ListDataProvider<String> dataProvider = new
ListDataProvider<String>(); List<String> data = dataProvider.getList(); data.add(...) dataProvider.addDataDisplay(cellList);
10/04/23 83
10/04/23 84
MVP
MVP pour Modèle-Vue-Présentation (Model-View-Presenter)
Facilite la séparation des responsabilités de traitement entre les différents composants
M : Le modèle, simple bean qui contient les données à afficher / traiter.
V: La vue correspond à l’interface d'affichage et ne contient aucun traitement, elle définit la disposition des widgets et leur apparences.
P : Le présentateur est responsable des traitements, Réactions de l’application aux événements utilisateurs. Interaction avec le serveur Logique de navigation
10/04/23 85
MVP
10/04/23 86
MVP
10/04/23 87
MVP
Le présentateur contient la logique du composant d'IU. Il envoie les données mises à jour à la vue et reçoit les valeurs modifiées par la vue.
Le présentateur reçoit les événements envoyés par les autres composants de l'application et il émet ses propres événements via le bus d'événements.
Le présentateur reçoit des données du Modèle
Le présentateur et la vue associée sont couplés via une Interface d'Affichage
Atelier
En se basant sur la structure fournie, réaliser l’atelier suivant : Retravailler la classe PersonEditionLayout en se basant sur
UIBinder Internationaliser les chaînes de caractères et les messages Lors de la confirmation de la sauvegarde afficher un popup
de confirmation en se basant sur le panel PopupPanel Si des erreurs de validation existent, les afficher dans le
section error (voir la page html principale) en utilisant du JSNI
Ne pas oublier de respecter le MVP
10/04/23 89
Partie 4
Communiquer avec le serveur RPC
Principe du RPC Développer un appel RPC Invoquer un appel RPC Traiter le retour d’un appel RPC (AsyncCallback)
Invoquer une Servlet HTTP Manipuler JSON Gestion des exceptions
Ateliers : Ajouter un mécanisme de login à notre application état civilEnregistrer les données de l’état civil dans le serveur
10/04/23 90
Principe du RPC
GWT RPC (Remote Procedure Call), permet de faire communiquer le navigateur client avec les services hébergés sur le serveur, par appel à des méthodes de façon asynchrone.
Fournit une procédure automatique de sérialisation des objets Le Marshaling et le Unmarshaling des objets JAVA
est automatisé par le framework GWT
Support de : XML, JSON (JavaScript Object Notation)
10/04/23 91
Principe du RPC
10/04/23 92
Développer un appel RPC
Une première interface au niveau client dite Synchrone définit les services Chaque service est associé à une annotation
@RemoteServiceRelativePath (path) path : le chemin relatif utilisé par le navigateur pour
invoquer le service
10/04/23 93
Développer un appel RPC
Une deuxième interface coté client dite Asynchrone qui est utilisé par le client pour invoquer le service et qui identifie les mêmes méthodes que l’interface synchrone.
Porte le même nom que l’interface synchrone plus le suffixe «Async»
Un paramètre de plus est ajouté à la signature de chaque méthodes, de type AsyncCallback<U>
U : le même type que le retour de la méthode correspondante dans l’interface synchrone.
Toutes les méthodes sont void.
10/04/23 94
Développer un appel RPC
Une Classe à implémenter côté serveur qui contient le traitement à effectuer
Elle implémente l’interface Synchrone Elle hérite de la classe RemoteServiceServlet
10/04/23 95
Développer un appel RPC
Déclarer le service comme servlet au niveau du fichier web.xml Le path identifié au niveau du tag url-pattern doit être le même que celui
déclaré dans le service Synchrone par l’annotation @RemoteServiceRelativePath (path)
10/04/23 96
Invoquer un appel RPC
Instancier le service par appel de GWT.create() On récupère un objet de type Asynchrone L’objet récupéré est en réalité un proxy qui permet de communiquer avec le
serveur.
10/04/23 97
Invoquer un appel RPC
L’appel RPC au service se fait alors de la façon la plus simple en invoquant la méthode souhaité de du proxy instancié initialement
10/04/23 98
Traiter le retour d’un appel RPC (AsyncCallback)
Le traitement du retour RPC est effectué par le dernier paramètre du service Asynchrone de type AsyncCallback
Invoquer une Servlet HTTP
GWT offre la possibilité de communiquer avec le serveur HTTP par simple envoi de requêtes depuis le code GWT
fonctionne globalement de façon similaire à n’importe quel langage, c’est-à-dire : Construction de la requête HTTP Envoi de la requête Traitement de la réponse
Invoquer une Servlet HTTP
com.google.gwt.http.client.RequestBuilder setTimeoutMillis() : permet de spécifier le temps max
que doit attendre le navigateur pour recevoir la réponse
setHeader() : permet d’ajouter des valeurs au header de la requête
sendRequest(String, RequestCallback) : envoyer le requête
1er paramètre : les données à envoyer 2éme paramètre : le handler à exécuter lors de la
réception de réponse La méthode retourne un objet Request qui peut être utilisé pour interroger le statut de la requête via isPending(), ou l’annuler via cancel().
Invoquer une Servlet HTTP
com.google.gwt.http.client.RequestCallback
onResponseReceived(Request request, Response response) : le traitement à exécuter lors de la réception de la réponse si OK
onError(Request request, Throwable exception) : le traitement à exécuter si l’appel a échoué ou que le temps de réponse est ecoulé, la cause du problème est contenu dans le paramètre exception.
Invoquer une Servlet HTTP Pour utiliser la requête HTTP, intégrer le module
<inherits name="com.google.gwt.http.HTTP" />
Manipuler JSON
JSON pour JavaScript Object Notation
Format d’échange de données allégé, simple à générer et à parser, communément utilisé pour le transport de données sur un réseau.
Utilisé dans les applications AJAX, ou il constitue une alternative moins lourde à XML.
Techniquement, JSON est une notation dérivée de JavaScript, ce qui le rend plus facile à manipuler dans ce langage ; cependant il est possible de manipuler JSON dans la plupart des langages actuels.
Manipuler JSON
Pour manipuler du JSON intégrer le module <inherits name="com.google.gwt.json.JSON" />
com.google.gwt.json.client.JSONParser : permet de parser une chaîne de caractère qui représente un contenu JSON parseStrict(String jsonString) : méthode qui parse la
chaine JSON et retourne un objet JSON (JSONValue)
com.google.gwt.json.client.JSONValue : représente un contenu JSON
get(String key) : permet de récupérer la valeur d’une propriété du contenu JSON
Set<String> keySet() : retourne la liste des propriétés de l’objet JSON
Manipuler JSON
Manipuler JSON
Manipuler JSON
10/04/23 108
Gestion des exceptions
GWT étant un framework JAVA, offre la possibilité de gérer des exceptions par le même mécanisme que JAVA.
Deux types d’exceptions Checked Exceptions Unexpected Exceptions
10/04/23 109
Gestion des exceptionsChecked Exceptions
Les méthodes de l’interface RemoteService peuvent remonter (throws) les exceptions survenues lors de l’appel RPC.
Les exceptions remontés (throws) le sont jusqu’au code client.
Le code client appelant traite les exceptions remontés en implémentant la méthode AsyncCallback.onFailure(Throwable)
10/04/23 110
Gestion des exceptionsUnexpected Exceptions
InvocationException : déclenche si l’appel RPC ne parvient pas à invoquer le service au niveau serveur pour des problémes réseau ou autre.
IncompatibleRemoteServiceException : déclenché si la version d’un service deployé au niveau du serveur n’est pas compatible avec celle deployé au niveau du navigateur.
Le code client appelant traite ces deux exceptions en implémentant la méthode AsyncCallback.onFailure(Throwable)
10/04/23 111
Serialization Formater des dates et des nombres Développer un composant
graphique Historique du navigateur Logging Tester avec JUNIT
10/04/23 112
Serialization
Les paramètres et types de retour des méthodes GWT RPC doivent être serializable Ces valeurs seront transmises à travers le réseau entre
le client et le serveur
Types de données Java sont déjà serializable Les Primitives, byte, short, int, long, boolean, float,
double, …. String, Date, Character, Integer, Byte, Double, … Tableau (Array) de types serializable
Les types définies par le développeur et qui servent à faire communiquer le client et le serveur doivent être serializable
10/04/23 113
Formater des dates et des nombres
GWT ne prends pas en charge les classes de formatage standard pour les dates et les nombres java.text.Format
com.google.gwt.i18n.client. NumberFormat et com.google.gwt.i18n.client. DateTimeFormat permettent d’effectuer le formatage des dates et de nombres Ajouter <inherits name="com.google.gwt.i18n.I18N"/>
au niveau du fichier de configuration .gwt.xml
10/04/23 114
Formater des dates
com.google.gwt.i18n.client.PredefinedFormat est un enum qui permet de spécifier le format souhaité
10/04/23 115
Formater des nombres
NumberFormat.getFormat() permet de spécifier un format autre que les formats standards 0 : décimal, zéro affiché si pas de valeur # : décimal, vide si pas de valeur . : séparateur décimal - : signe négative , : séparateur de groupe
10/04/23 116
Développer un composant graphique
En créant Un Composite, agrégation de widgets existantes et autres Composites
"from scratch« , Définition d'un nouveau Widget
En Encapsulant un composant JavaScript d'une bibliothèque tierce via du JSNI
10/04/23 117
Développer un composant graphique
10/04/23 118
Historique du navigateur
GWT Permet de prendre le contrôle des boutons historiques du navigateur
Ajouter une iframe au niveau de la page home de l’application avec comme identifiant _gwt_historyFrame
L’API com.google.gwt.user.client.History permet de gérer cette historique
History.newItem(“nouveauJeton”) pour ajouter une nouvelle entrée dans l’historique
History.addHistoryListener(valueChangeHandler) pour réagir aux click sur les boutons historiques
10/04/23 119
Historique du navigateur
10/04/23 120
Logging
GWT offre un mécanisme qui permet d’émuler la classe java.util.logging au niveau du code client et de générer ainsi de la log au niveau du navigateur
Pour l’exploiter il suffit d’ajouter la déclaration suivante au niveau du fichier de configuration .gwt.xml
Au niveau des classes client, utiliser la log comme d’habitude dans une classe JAVA
Logging
com.google.gwt.logging.server.RemoteLoggingServiceImpl
10/04/23 122
Logging
gwt.logging.logLevel : prend les même valeurs que ceux fournis par la classe java.util.logging.Level
gwt.logging.enabled : True / false, permet d’activer ou désactiver la log
gwt.logging.consoleHandler : Disabled / Enabled, la log est écrite dans la console javascript
gwt.logging.systemLogHandler : la log est écrite dans la sortie standard (ne fonctionne qu’on DevMode)
gwt.logging.developmentModeLogHandler : la log est écrite sur appel de la méthode GWT.log (ne fonctionne qu’on DevMode)
gwt.logging.firebugLogHandler : la log est écrite dans la console fireBug
gwt.logging.popupLogHandler : la log est affiché dans un popup gwt.logging.simpleRemoteLogHandler : la log est envoyé au
serveur via RPC
10/04/23 123
Tester avec JUNIT
GWT offre une intégration avec JUNIT pour les tests unitaires
com.google.gwt.junit.client.GWTTestCase est l’API qui permet cette intégration
Le test case doit hériter de la classe GWTTestCase Définir la méthode abstract getModuleName() pour identifier
le module à tester Si le test unitaire concerne la partie cliente, ne pas oublier
d’ajouter le package contenant les tests en tant que source au niveau du fichier de configuration .gwt.xml.
gwtSetup() est exécuté avant chaque test gwtTearDown() est exécute après chaque test
com.google.gwt.junit.tools.GWTTestSuite permet de créer des TestSuite pour GWT
Atelier
Développer un nouveau composant qui permet de simuler un calendrier autoaffichable
Partie 5
JavaScript overlay types Intégrer une appli GWT dans
JavaScript Code Splitting Étendre la JRE Émulation Compile Reports
JavaScript overlay types
GWT grâce à JSNI permet d’intégrer facilement des classes d’objets définies dans le language JavaScript
Ce mécanisme fort appelé JavaScript overlay types facilite l’intégration de framework JavaScript dans GWT
com.google.gwt.core.client.JavaScriptObject permet de représenter un objet JavaScript native
Intégrer une appli GWT dans JavaScript
Code Splitting
Les fichiers JavaScript générés peuvent être de grandes tailles pour certains écrans, ce qui peut impacter les temps de réponse de l’application
GWT offre un mécanisme pour palier à ce problème, Code Splitting
Découper le code JavaScript et ne télécharger le code qu’au besoin, surtout le code qui gère la partie dynamique de l’écran
Code Splitting
Pour implémenter le Splitting, placer l’instruction GWT.runAsync(RunAsyncCallback) à l’emplacement du code que vous souhaiter ne pas être chargé lors de l’affichage de l’écran
Cet emplacement s’appelle le point de séparation (Split point)
com.google.gwt.core.client.RunAsyncCallback interface qui gère le call back lors de la définition du Split point onSuccess : Traitement qui correspond au contenu du
fichier JavaScript à téléchargé onFailure : Réaction de l’application si le fichier n’est pas
téléchargé
Code Splitting
Étendre l’Émulation JRE
GWT permet d’intégrer facilement de nouvelles classe du JDK pour l’émulation JRE
Ajouter le tag super-source au niveau du fichier de configuration .gwt.xml pour identifier le dossier qui contient le code source des classes à émuler
Faire en sorte que le nouveau code source soit compatible avec l’émulation JRE de GWT
Étendre l’Émulation JRE
Pour contourner la limitation du compilateur JAVA de ne pas redéfinir les classes core java
Pour un projet sous maven, mettre le code source des classes sous le dossier ressources
Pour un projet qui n’est pas sous maven, exclure le code source de la compilation
Étendre l’Émulation JRE
Compile Reports
Compile GWT projets avec les options -compileReport -XsoycDetailed -XcompilerMetrics
Partie 6
Editor
Planification de tâches
MVP Activities & Places
Deffered Binding
Editor
GWT fournit un mécanisme qui permet de réduire le code nécessaire pour transférer les données du bean vers l’écran pour affichage et vice versa.
Editor : Responsable de l’édition (affichage) d’un ensemble de propriétés d’un objet, couramment un écran IHM, com.google.gwt.editor.client.Editor
Editor
Driver : Responsable de faire l’association entre le bean et l’Editor com.google.gwt.editor.client.EditorDriver
Pour simplifier cette association @path : associe un composant graphique au
niveau de l’Editor avec une propriete du bean de données
@Ignore : permet d’indiquer au driver d’ignorer un composant
Editor
Le driver fournit deux méthodes pour interagir avec l’IHM : edit(Object) : prend en paramètre le bean à
afficher, récupère les données du bean et les affiche au niveau du composant indiqué
flush() : sans paramètre et construit le bean sur la base des valeurs des différents composants indiqué par l’annotation @Path
Planification de tâches
GWT offre un outil très simple pour pouvoir mettre en place : des tâches à démarrage différé des tâches avec exécution périodique
com.google.gwt.user.client.Timer, classe abstraite nécessite l’implémentation de la méthode run() run() : implémente le traitement que doit
exécuter la tâche.
Planification de tâches
schedule(startMillis) : planifie le 1er démarrage de la tâche, prends en paramètre le délai en milliseconde que doit attendre la tache avant de s’exécuter.
scheduleRepeating(periodMillis) : permet de planifier le périodicité de répétition de l’exécution de la tâche.
cancel() : permet de stopper la planification et l’exécution de la tâche
MVP Activities & Places
Activity : représente le P du pattern MVP implémente com.google.gwt.activity.shared.AbstractActivity start : initialise et démarre l’activité mayStop : définit le message d’alerte à afficher lors de
l’arrêt de cette activité.
Place : permet d’identifier l’état de l’application à un moment donnée, et sert à reproduire cet état lors de l’utilisation des boutons historique du navigateur com.google.gwt.place.shared.Place
MVP Activities & Places
PlaceHistoryMapper : permet de lister l’ensemble des types de Place gérés par l’application
ActivityMapper : permet d’associer chaque type de place à une Activity com.google.gwt.activity.shared.ActivityMapper
PlaceController : responsable de la navigation d’une place vers un autre goto(Place) : indiquer la nouvelle destination (Activity)
de l’application
MVP Activities & Places
ActivityManager : responsable de la gestion et de l’exécution des Activities com.google.gwt.activity.shared.ActivityManager PlaceChangeRequestEvents : notifie l'activité
courante quand une nouvelle place a été demandée. Si l'activité actuelle permet la Place changement (Activity.onMayStop( ) retourne null ) ou l'utilisateur le permet (en cliquant sur OK dans la boîte de dialogue de confirmation )
Deferred Binding (liaison différée)
GWT offre la possibilité de générer plusieurs versions du code JavaScript lors de la compilation, sachant qu’une seule doit être chargée lors de l’exécution.
Deferred Binding fait référence au fait que l’opération de sélection de la version de code à charger s’effectue au démarrage de l’application
Le résultat est un temps de chargement optimal, puisque seul le code nécessaire pour l’environnement de l’utilisateur est téléchargé.
Deferred Binding (liaison différée)
Le Deferred Binding est mis en œuvre par exemple dans l’internationalisation « statique » à base d’interfaces, le compilateur génère une version de code par navigateur cible.
Le mécanisme de Deferred Binding est mis en jeu explicitement lorsque le code fait appel à la méthode GWT.create().
Cette méthode permet d’instancier une classe, mais à la différence de l’utilisation classique de new, elle indique au compilateur GWT que la classe spécifiée en paramètre peut être remplacée par une autre implémentation, selon le contexte de l’utilisateur
Deferred Binding (liaison différée)
Substitution : la classe est remplacée par une autre selon des règles spécifiées dans le fichier module ;
Génération : les différentes variantes de l’implémentation fournie sont générées lors de la compilation GWT par un « générateur ». com.google.gwt.core.ext.Generator Génère une classe Java qui représente
l’implémentation souhaité
10/04/23 148
Ressources
http://www.gwtproject.org/index.html
http://www.tutorialspoint.com/gwt/
http://googlewebtoolkit.blogspot.com/
https://groups.google.com/forum/#!forum/google-web-toolkit
https://code.google.com/p/gwt-platform/