GWT Principes & Techniques
Des IHM avec GWT
Des IHM avec GWT +
Communiquer avec le serveur
Internationalisation I18n
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
2. 17/03/14 2
Plan
Introduction
GWT
Des IHM avec GWT
Des IHM avec GWT +
Communiquer avec le
serveur
Internationalisation I18n
3. 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
4. 17/03/14 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
5. 17/03/14 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
6. 17/03/14 6
En mode synchrone, le navigateur est gelé en attendant la
réponse du serveur.
Diagramme de séquence - WEB standard
7. 17/03/14 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
9. 17/03/14 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. 17/03/14 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.
14. 17/03/14 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
15. 17/03/14 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
16. 17/03/14 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
17. 17/03/14 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
18. 17/03/14 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
19. 17/03/14 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
23. 17/03/14 23
Transcompilateur JAVA
Le Transcompilateur JAVA est la pièce maîtresse de GWT, son rôle
est de traduire le code client JAVA en code JavaScript optimisé
24. 17/03/14 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.
25. 17/03/14 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
26. 17/03/14 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
27. 17/03/14 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
29. 17/03/14 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
30. 17/03/14 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
32. 17/03/14 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
34. 17/03/14 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
36. 17/03/14 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
37. 17/03/14 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
38. 17/03/14 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.
40. 17/03/14 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
41. 17/03/14 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'/>
42. 17/03/14 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.
44. 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
45. 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
46. 17/03/14 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)
47. 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
48. 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
49. 17/03/14 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
50. 17/03/14 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)
52. 17/03/14 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”);
53. 17/03/14 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;
}
54. 17/03/14 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.
55. 17/03/14 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)
56. 17/03/14 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
57. 17/03/14 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);
58. 17/03/14 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
59. 17/03/14 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() {
@Override
public void onClick(ClickEvent event) {
Window.alert("OK");
}
});
60. 17/03/14 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
61. 17/03/14 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
62. 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
63. 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
64. 17/03/14 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
65. 17/03/14 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
67. 17/03/14 67
Internationalisation I18n
MyConstants.properties, MyConstants.properties_es
helloWorld = …
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
68. 17/03/14 68
Internationalisation I18n
MyMessages.properties
permissionDenied = 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
70. Accès au ressources
ClientBundle
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" />
72. 17/03/14 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
73. 17/03/14 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
}-*/
74. 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
76. 17/03/14 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
77. 17/03/14 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 :
78. 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.
81. 17/03/14 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.
82. 17/03/14 82
GWT Widgets avancés (Cell Widgets)
Injecter des données via une liste
CellList<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);
84. 17/03/14 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
87. 17/03/14 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
88. 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
89. 17/03/14 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 civil
Enregistrer les données de l’état civil dans le serveur
90. 17/03/14 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)
92. 17/03/14 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
93. 17/03/14 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.
94. 17/03/14 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
95. 17/03/14 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)
96. 17/03/14 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.
97. 17/03/14 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
98. 17/03/14 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
99. 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
100. 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().
101. 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.
102. Invoquer une Servlet HTTP
Pour utiliser la requête HTTP, intégrer le module
<inherits name="com.google.gwt.http.HTTP" />
103. 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.
104. 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
108. 17/03/14 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
109. 17/03/14 109
Gestion des exceptions
Checked 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)
110. 17/03/14 110
Gestion des exceptions
Unexpected 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)
111. 17/03/14 111
Serialization
Formater des dates et des nombres
Développer un composant
graphique
Historique du navigateur
Logging
Tester avec JUNIT
112. 17/03/14 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
113. 17/03/14 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
114. 17/03/14 114
Formater des dates
com.google.gwt.i18n.client.PredefinedFormat est un
enum qui permet de spécifier le format souhaité
115. 17/03/14 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
116. 17/03/14 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
118. 17/03/14 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
120. 17/03/14 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
122. 17/03/14 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
123. 17/03/14 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
124. Atelier
Développer un nouveau composant
qui permet de simuler un calendrier
autoaffichable
125. Partie 5
JavaScript overlay types
Intégrer une appli GWT dans
JavaScript
Code Splitting
Étendre la JRE Émulation
Compile Reports
126. 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
129. 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
130. 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é
132. É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
133. É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
135. Compile Reports
Compile GWT projets avec les options
-compileReport -XsoycDetailed -XcompilerMetrics
136. Partie 6
Editor
Planification de tâches
MVP Activities & Places
Deffered Binding
137. 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
138. 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
139. 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
140. 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.
141. 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
142. 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
143. 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
144. 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 )
145. 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é.
146. 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
147. 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é