GIÁO ÁN DẠY THÊM (KẾ HOẠCH BÀI DẠY BUỔI 2) - TIẾNG ANH 6, 7 GLOBAL SUCCESS (2...
Gwt fast overview_v1
1. Google Web Toolkit
David Herviou
@herviou
+david herviou
david.herviou@gmail.com
2. Présentation
● Généralités
● Construire son UI en GWT
● Internationalisation | i18n
● Communication Evènementielle
● Communication Client / Serveur
● Pour aller plus loin
● Bibliographie
4. GWT
Qu'est ce que c'est ?
Une boite à outil pour construire des
applications WEB
Codez en Java
Obtenez une application Javascript
Vise le développement industrialisé
d'applications WEB performantes
5. GWT
Qu'est ce que c'est ?
Open source
Maintenu par Google et la communité
Utilisé par des milliers de personnes
Ecosystème actif et riche
6. Grand Principes
● Les freins aux applications performantes
○ le nombre de requêtes
○ le volume des requêtes
● Approche GWT
○ Une application Javascript optimisée par Navigateur
○ Un bundle unique JS
○ Chacun son boulot :
■ Le Client s'occupe du rendu
■ le Serveur des données
Approche orientée "client lourd"
7. Principes / Objectifs
● Les freins à la productivité
○ les spécificités d'implémentations des différents
navigateurs
○ le debuggage du Javascript
○ la gestion des css spécifiques
● Approche GWT :
○ "don't care about web browser"
○ Code Java : debuggage Java
○ Librairie de widgets disponibles
9. Organisation Projet GWT
la page Host
./war/MyApp.html
○ la page d'entrée de l'application GWT
○ contient un script MyApp.nocache.js
○ charge en dynamique l'application (code javascript)
spécifique au navigateur
Principe des permutations
10. Organisation Projet
Partie client/serveur
./src/my.package.myapp.client
○ Code de l'UI graphique et de son comportement
○ Code Java à transcrire en Javascript
./src/my.package.myapp.server
○ Code de la partie serveur gestion des données et
des échanges avec les clients
○ Code Java à compiler en Bytecode
11. Module GWT
./src/my.package.myapp.MyApp.gwt.xml
○ configuration des librairies GWT du projet
○ configuration de l'internationalisation
○ configuration des navigateurs cibles
○ configuration des points d'entrées de l'applications
○ ...
C'est l'élément de base pour le compilateur GWT
12. Module GWT
<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='fr_dhu_gwt_slides'> ● <module> : déclaration
<!-- Inherit the core Web Toolkit stuff.-->
<inherits name='com.google.gwt.user.User'/> ● <inherits> : utilisation
<!-- Inherit the default GWT style sheet.--> d'autres modules
<inherits name='com.google.gwt.user.theme.
clean.Clean'/> ● <entry-point> : classe
<!-- Specify the app entry point class.--> Java-démarrage de
<entry-point class='fr.dhu.gwt.slides.client. l'application
Slides'/>
<!-- Specify the paths for translatable code-->
● <source> : code java à
<source path='client'/> transcrire
<!-- manage english-->
<extend-property name="locale" value="en"/>
● <extend-property> :
</module> extension d'une
propriété existante
13. Compilateur GWT
2 modes de fonctionnement
● Production
○ Code Java vers Code Javascript avec permutations
○ JRE Emulation:
Classes et méthodes translatables ou ayant une implementation
Javascript
○ Pour les curieux: com.google.gwt.dev.Compiler
● Développement ou DevMode
○ Accélérer la boucle coder/compiler/vérifier
○ Plugin GWT branché sur le navigateur
● Se base sur le contenu du module GWT
14. Compilateur GWT
permutations
L'utilisateur final ne veut "payer" que ce qu'il
consomme
● Améliorer le volume/nombre d'éléments
ramener à l'utilisateur
● Tenir compte des spécificités des
implémentations/bugs des navigateurs
● Tenir compte de l'internationalisation des
applications
● Offrir un mécanisme d'extension des
spécificités applicatives
15. Compilateur GWT
permutations
● user.agent
○ par défaut : "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
● Possibilité de définir ses axes de permutations
{user.agent}x{locale}x{deferred-binding properties}
17. Compilateur GWT
Permutations et deferred Binding
Comment cela fonctionne-t-il concrètement ?
New Object()
résolution statique
MyObject.class.newInstance()
résolution au runtime
GWT.create(MyObject.class)
résolution différée / classes clientes
18. Compilateur GWT
Permutations et deferred Binding
Exemple de l'implementation d'une Popup
● l'utilisateur effectue
PopupPanel myPopup = new PopupPanel();
● cette classe contient / wrap / ~pattern proxy
PopupImpl p = GWT.create(PopupImpl.class)
● et le compilateur GWT à la règle :
<!-- Mozilla needs a different implementation due to issue #410 -->
<replace-with class="com.google.gwt.user.client.ui.impl.PopupImplMozilla">
<when-type-is class="com.google.gwt.user.client.ui.impl.PopupImpl"/>
<when-property-is name="user.agent" value="gecko1_8"/>
</replace-with>
19. Compilateur GWT
● Substitution d'implémentation
● Génération automatique de code
● Améliore la flexibilité du compilateur
● Facilite le développement du code spécifique
21. Layout et Positionnement
● Organisation de l'affichage de l'UI
● RootPanel
○ RootPanel.get() : accès à l'élément <body> de l'arbre
DOM
○ RootPanel.getId(String id) : accès à l'élément id du
DOM
● FlowPanel, FormPanel, HTMLPanel,
ScrollPanel, PopupPanel
○ Elements classique HTML
● {Dock, Split, Stack, Tab}LayoutPanel
○ Element HTML complexe
○ Structure globale de l'application
○ Structure d'éléments conséquents de l'application
22. Layout exemple
TabLayoutPanel tabPanel = new TabLayoutPanel(2.5, Unit.EM);
// Add a home tab
HTML homeText = new HTML(constants.cwTabPanelTab0());
tabPanel.add(homeText, "Accueil");
// Add a tab with an image
SimplePanel imageContainer = new SimplePanel();
imageContainer.setWidget(new Image(Showcase.images.gwtLogo()));
tabPanel.add(imageContainer, "Logo GWT");
// Add a tab
HTML moreInfo = new HTML(constants.cwTabPanelTab2());
tabPanel.add(moreInfo, "Plus d'info");
// Return the content
tabPanel.selectTab(0);
23. 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
Les layouts et les widgets sont la base de la
construction d'une Application Web Riche GWT
24. Widgets exemples
// Create a DateBox
DateTimeFormat dateFormat =
DateTimeFormat.getLongDateFormat();
DateBox dateBox = new DateBox();
dateBox.setFormat(new DateBox.DefaultFormat(dateFormat));
// Create the text area and toolbar
RichTextArea area = new RichTextArea();
area.ensureDebugId("cwRichText-area");
area.setSize("100%", "14em");
RichTextToolbar toolbar =
new RichTextToolbar(area);
toolbar.setWidth("100%");
25. Créer ces propres composants
● En créant des Composite
○ aggrégation de widgets et autres Composites
● "from scratch"
○ Définition d'un nouveau Widget
● En wrappant du javascript existant
○ Encapsulation en Java d'un composant d'une
bibliothèque tierce
○ Pas d'optimisation possible dans ce cas
La méthode la plus courante est l'utilisation des
Composite
26. Composite exemple
public class MyFirstComposite extends Composite {
public MyFirstComposite(String label) {
// create the widget container
VerticalPanel fp = new VerticalPanel();
// add a checkbox for choice
fp.add(new CheckBox(label));
// add a multiple choice box
ListBox lb = new ListBox();
lb.addItem("item 1");
lb.addItem("item 2");
fp.add(lb);
// initialize widget
initWidget(fp);
}
}
somewhere else...
MyFirstComposite fc = new MyFirstComposite("Je prends l'option");
27. Comment du code Java donne de
l'HTML
Comment le code Java /** Class FlowPanel **/
public FlowPanel() {
donne un arbre DOM ? setElement(DOM.createDiv());
}
● Rappel : /** Class DOM **/
○ Java transcrit en public static Element createDiv() {
return Document.get().createDivElement().cast();
Javascript }
● Javascript /** Class Document **/
○ manipule et interagit public final DivElement createDivElement() {
return (DivElement) DOMImpl.impl.createElement
avec les noeuds DOM (this, DivElement.TAG);
}
● Exemple avec le /** Class DivElement **/
FlowPanel static final String TAG = "div";
28. Interaction avec l'utilisateur
● Permettre à l'utilisateur d'interagir avec
l'application
● Programmation principalement
Evènementielle
● Notions principales à retenir :
○ Event : l'objet représentant l'évènement déclenché
○ Handler: definition du comportement à déclencher
sur évènement
○ HandlerRegistration : gère l'abonnement d'un
Handler à un Event
29. Interaction avec l'utilisateur
exemple
// create the widget container
VerticalPanel fp = new VerticalPanel();
..
..
..
// add a button
Button b = new Button("Send");
fp.add(b);
HandlerRegistration hr = b.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
Window.alert("OK");
}
});
// initialize widget
initWidget(fp);
30. Construction déclarative d'interface
avec UIBinder
● Partie statique de l'UI :
○ Déclaratif
○ XML
● Séparation des responsabilités
○ UIBinder : UI statique
○ Java : UI dynamique et gestion des données
● Meilleure structuration de l'interface
● Interaction XML / Java
32. Mise en forme avec CSS
● CSS : mise en forme du contenu HTML
○ implémentation spécifique suivant les navigateurs
○ peut représenter une part conséquente et complexe
de la partie UI d'une application
● Approche classique :
○ 1 gros fichier CSS
○ peut modulaire
○ simple à mettre en oeuvre
● Approche GWT :
○ compatible avec l'approche classique MAIS
○ propose une approche modulaire
○ possibilité de manipuler le CSS depuis le code Java
○ L'idéal est d'éviter le CSS spécifique !
33. UI: CSS exemple "classique"
// create the widget container .MyComposite {
VerticalPanel fp = new VerticalPanel(); border-style : solid;
fp.setStylePrimaryName("MyComposite"); border-width : thin;
... override : hidden;
padding : 0.5em;
// add a multiple choice box min-width : 200px;
ListBox lb = new ListBox(); }
...
fp.add(lb); .MyComposite-List {
lb.addStyleName("MyComposite-List"); margin-bottom : 1em;
margin-top : 1em;
// add a button }
Button b = new Button("Send");
fp.add(b); .MyComposite-Button {
b.addStyleName("MyComposite-Button"); float : right;
}
// initialize widget
initWidget(fp);
36. Gestion des images
● Souvent goulot d'étranglement des
échanges client/serveur
● beaucoup d'overhead pour peu de contenu
● norme HTTP 1.1 : deux requêtes
simultanées vers le même domain/port !
● Approche GWT
○ packager les images avec l'application
○ images encodées en base64
○ gestion native de l'internationalisation
37. Gestion des images exemple
public class MyComposite extends Composite {
...
public interface MyImages extends ClientBundle {
@Source("gwt-logo.png")
ImageResource logoGWT();
}
<ui:with type="fr.dhu.gwt.client.MyComposite.MyImages" field="images"></ui:with>
<ui:style field="myStyle" type="fr.dhu.gwt.client.MyComposite.Css">
...
.MyComposite-Image {
float : left;
}
</ui:style>
<g:VerticalPanel ... >
...
<g:FlowPanel>
<g:Image resource="{images.logoGWT}" styleName="{myStyle.MyComposite-Image}"/>
<g:Button ... ui:field="b" styleName="{myStyle.MyComposite-Button}"/>
</g:FlowPanel>
</g:VerticalPanel>
39. Internationalisation
● Gérer les langues est aujourd'hui
Indispensable
● Gérer nativement dans GWT
○ basé sur la valeur 'locale' du navigateur
○ intégré au mécanisme des permutations
● Comment ?
○ Déclarer une interface XXXMessages qui étend
Messages
○ Déclarer autant de XXXMessages_lg.properties que
de langage gérer
○ Déclarer au compilateur GWT la gestion de ses
nouvelles 'locale'
43. Gestion de l'historique
● Contexte : Une application GWT
○ pas de génération de plusieurs pages HTML
○ pas d'historique de navigation à priori
● Comment obtenir :
○ différents points d'entrées dans l'application
■ Application "Bookmarkable"
○ obtenir une simulation de navigation aller/retour
■ Simuler une application à plusieurs pages HTML
44. Gestion de l'historique
sur les application Javascript
https://www.google.fr/#hl=fr&q=test
● partie de l'URL qui ne part pas jusqu'au
serveur
● Interprétable par la partie cliente
● Sa modification inclu l'empilement dans
l'historique du navigateur :
https://www.google.fr/#hl=fr&q=test
https://www.google.fr/#hl=fr&q=test1
45. Gestion de l'historique en GWT
● Une API dédiée : Classe History
● Notion d'évènements
○ History.newItem
● Notion d'Handler
History.addValueChangeHandler(ValueChangeHandler<String> handler)
myValueChangeHandler = new ValueChangeHandler<String>() {
@Override
public void onValueChange(ValueChangeEvent<String> event) {
// get URL fragment
String token = event.getValue();
// do what you want with the token
...
}
}
46. Bus d'évènements
● Une application
○ un ensemble de widgets
○ un ensemble d'interaction
■ homme/UI
■ UI/serveur
■ UI/UI
● Interaction UI/UI : Bus logiciel d'évènement
dispatcher un évènement depuis un widget vers un
ensemble de cibles non connues
● Intérêts
○ Mettre à jour l'UI en réaction à un changement
○ Couplage lâche entre composant
47. Bus d'évènements exemple
// declare an Handler for our event
public interface MyEventHandler
extends EventHandler {
● Déclarer un Handler
void onEvent(MyEvent event); ○ Contrat d'interface
}
pour les
// declare an Event for EventBus communication
public class MyEvent consommateurs
extends GwtEvent<MyEventHandler> { ● Déclarer un Event
/** TYPE of this event */ ○ Donnée d'échange
public static final Type<MyEventHandler> TYPE =
new Type<MyEventHandler>(); entre le producteur et
@Override
les consommateurs
public Type<MyEventHandler> getAssociatedType() { ○ Un Event = Un TYPE
return TYPE;
}
@Override
protected void dispatch(MyEventHandler handler) {
handler.onEvent(this);
}
}
48. Bus d'évènements exemple
// One single Bus (Singleton pattern)
// to fire event onto and triggering Handler s
SimpleEventBus singleBus = new SimpleEventBus();
// One widget is registering on application EventBus ● Déclarer un Bus unique
HandlerRegistration hr =
singleBus.addHandler( pour l'applicatoin
MyEvent.TYPE,
new MyEventHandler() {
● Les widgets s'abonnent
@Override au TYPE d'évènements
public void onEvent(MyEvent event) {
// do what you want with event souhaité
}
}); ● Les widgets producteurs
// Another one is triggering event
émettent les évènements
singleBus.fireEvent(new MyEvent()); ● Les évènements sont
propagés par le bus
jusqu'aux abonnés
50. Communication Client/Serveur
Principe d'Asynchronisme
● Permettre d'échanger des données entre l'UI
et le serveur
● Deux possibilités :
○ Synchrone : fonctionnement sur les applications non
Javascript
○ Asynchrone : peut être un fonctionnement sur les
applications Javascript
● Asynchronisme
○ Avoir une application réactive
○ Peut être complexe à mettre en oeuvre :
multiples navigateurs - multiples implémentation de XHR
51. Echange Client/Serveur:
GWT-RPC
● Framework de communication Asynchrone
● Masque les complexités d'implémentation
des navigateurs
● Permet l'échange de données complexes
● Facile à mettre en oeuvre
52. GWT-RPC exemple
● une interface Synchrone extends
RemoteService
● une interface Asynchrone pour le côté client
○ Nomenclature : SynchronousInterfaceAsync
// declare synchronous version of service
@RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
String greetServer(String name) throws IllegalArgumentException;
}
// declare asynchronous version of service
public interface GreetingServiceAsync {
void greetServer(String input, AsyncCallback<String> callback) throws llegalArgumentException;
}
53. GWT-RPC
exemple Côté Client
● Instanciation du service
○ 1 fois pour toute l'application
○ Utiliser un pattern Factory
GreetingServiceAsync service = GWT.create(GreetingService.class);
● Utilisation du service
service.greetServer("David", new AsyncCallback<String>() {
@Override
public void onSuccess(String result) {
Window.alert(result);
}
@Override
public void onFailure(Throwable caught) {
Window.alert("error while calling Greeting Service");
}
});
54. GWT-RPC
exemple Côté Serveur
● Implementation du service côté serveur
○ extends RemoteServiceServlet
○ implemente la version synchrone du service
// Service Implementation server side
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService {
public String greetServer(String input) throws IllegalArgumentException {
return "hello "+input;
}
}
● Modification du descripteur de déploiement
<servlet>
<servlet-name>greetServlet</servlet-name>
<servlet-class>fr.dhu.gwt.server.GreetingServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>greetServlet</servlet-name>
<url-pattern>/dhu/greet</url-pattern>
</servlet-mapping>
56. Framework GWT depuis la v2.x
● Gestion des Places et Activities
○ controle de la navigation dans l'application
○ formalise l'utilisation du fragment d'URL
● Gestion du Pattern MVP
○ Model/Vue/Controller
○ Améliore les tests de l'application cliente
● Gestion des applications orientées données
○ Ramener les actions sur les bases de données côté
navigateur
○ RequestFactory
57. Sécurité
● La sécurité se prend en compte à partir du
développement
● XSS:
○ Attaque par injection de données dans l'application
○ SafeHTML
○ escaping des données pouvant être injectées
● XSRF:
○ Attaque depuis un site tiers vers le site cible utilisant
votre précédente authentification sur le site cible
○ GWT-RPC avec Token
■ génération unique d'Id pour une appel RPC
■ deux appels séquentiels pour forger une requête
58. framework Editor
● Souvent fastidieux de faire du code "passe
plat"
myModel.setField1Value(myUI.getField1Value());
myModel.setField2Value(myUI.getField2Value());
...
myModel.setField3Value(myUI.getField3Value());
ou faire l'inverse !
● Framework GWT Editor
○ Automatise le mapping modèle de donnée vers UI et
vice versa
○ Basé sur des conventions de nommages des
champs
59. Compatiblité HTML5
● N'oubliez pas Java -> Javascript donc
génération d'HTML
● Possibilité également d'écrire de l'HTML en
GWT
○ avec des méthodes type setInnerHTML
○ avec l'HTMLPanel
○ Attention à la compatibilité multi-navigateur
● Des éléments HTML5 sont déjà gérés en
GWT
○ ClientSideStorage
○ Audio, Video
○ Canvas
60. Optimisations
● Amélioration par observation statique
○ soycReport : Rapport de compilation
○ permet d'identifier les gros volumes de code
○ permet d'identifier éventuellement les points de
modularisation
● Amélioration par observation dynamique
○ Lancer l'application et utiliser SpeedTracer ou
Firebug
● Modulariser l'application
○ Casser le monolythe applicatif
○ Télécharger des bouts de code Javascript à la
demande
61. Ecosystème
Quelques projets qui pourront vous intérresser
● m-gwt : portage pour tablette et mobile
● sencha gxt : framework et librairie de
composant GWT
● gwt-platform : framework autour de GWT
● vaadin : framework autour de GWT
● playN : cross-platform pour jeux basé sur
GWT
● Gin : framework d'injections de dépendance
● ... et pleins d'autres encore