Vous êtes sur la page 1sur 44

Google Web Toolkit

1.5

Présentation et mise en œuvre du


Google Web Toolkit v 1.5

Antony Fons, 2008

Page 1
Table des matières

1. Objectif ...............................................................................................................................3
2. Introduction ......................................................................................................................3
3. Google Web Toolkit (GWT)..........................................................................................3
3.1. Présentation..................................................................................................................... 3
3.2. Composants..................................................................................................................... 4
3.3. Principes de fonctionnement........................................................................................... 5
3.3.1. Généralités........................................................................................................................... 6
3.3.2. Principes du compilateur GWT Java-to-Javascript.............................................................6
3.3.3. Intégration dans une architecture n-tier.............................................................................. 7
3.4. Points forts et limitations.................................................................................................8
4. Mise en œuvre ..................................................................................................................9
4.1. Notions de base............................................................................................................... 9
4.1.1. Module................................................................................................................................. 9
4.1.2. EntryPoint............................................................................................................................ 9
4.1.3. Le fichier Html « hôte »..................................................................................................... 10
4.2. Structure d’un projet GWT........................................................................................... 10
4.2.1. Organisation physique....................................................................................................... 10
4.2.2. Le package Client...............................................................................................................11
4.2.3. Le package Server.............................................................................................................. 11
4.2.4. Les fichiers principaux....................................................................................................... 11
4.3. La gestion des évènements............................................................................................ 13
4.3.1. Types d'évènements............................................................................................................ 13
4.3.2. Gérer les évènements......................................................................................................... 14
4.4. Communication asynchrone Client / Server..................................................................14
4.4.1. Principes de fonctionnement.............................................................................................. 14
4.4.2. Particularité de la sérialisation implémentée par GWT.................................................... 20
4.4.3. Propagation des exceptions............................................................................................... 21
4.5. Cas de Test.................................................................................................................... 21
4.5.1. Création du squelette de l’application............................................................................... 21
4.5.2. Importation dans Jdeveloper 10.1.3.X............................................................................... 22
4.5.3. Test de l’exécution en mode « Hosted »............................................................................. 26
4.5.4. Implémentation de l’appel RPC......................................................................................... 27
4.5.5. Déploiement dans un container OC4J Standalone............................................................ 32
5. Notions avancées ..........................................................................................................37
5.1. L'accessibilité................................................................................................................ 37
5.1.1. ARIA et GWT...................................................................................................................... 37
5.1.2. Ajout de l’accessibilité dans les composants (Widgets) GWT........................................... 37
5.2. Internationalisation des applications sous GWT........................................................... 37
5.2.1. L’interface Constants......................................................................................................... 38
5.2.2. L’interface Messages......................................................................................................... 40
5.3. Sécurité.......................................................................................................................... 41
5.3.1. Validation des paramètres................................................................................................ 42
5.3.2. Cross Site Scripting............................................................................................................ 42
6. Conclusion ......................................................................................................................42
7. Table des Figures et Illustrations. ..........................................................................43
8. Glossaire ..........................................................................................................................45

Page 2
1. Objectif
Ce document a pour but de faire une présentation du framework Google Web Toolkit. Il
comprend la présentation du fonctionnement du framework, des notions de bases et
avancées, ainsi que la mise en œuvre d’un cas de test d’exemple.

2. Introduction

Google Web Toolkit (GWT), présentée en mai 2006 par la société Google, est un ensemble
d’outils permettant de développer des interfaces Web riches. Il entre, de ce fait, dans la
catégorie des framework RIA (Rich Internet Application) tel que Adobe Flex, Microsoft
Silverlight ou OpenLaszlo.
Les aspects essentiels de GWT, qui le distinguent des autres frameworks du marché, sont
les suivants :
- Utilisation des technologies HTML, Javascript et CSS pour l’exécution de l’interface
utilisateur cliente.
- Conception de l’interface utilisateur en langage Java. Un compilateur Java-to-
Javascript se charge de la transformation des classes Java en modules Javascript,
interprétables par le navigateur Web.
- Utilisation de la technologie AJAX pour l’implémentation des échanges avec les
serveurs (Basée sur l’objet XMLHttpRequest et un protocole RPC1 propriétaire).

De plus, le framework GWT offre les outils de debugging, de test et d’internationalisation.

3. Google Web Toolkit (GWT)

3.1.Présentation

Google Web Toolkit est un framework, créé par Google, destiné à faciliter le développement
d’interfaces graphiques pour applications web.
Le framework GWT permet de développer des interfaces riches en utilisant le langage Java.
Les concepts implémentés sont tout à fait similaires à ceux présents dans la librairie
graphique Java Swing.

GWT fourni un ensemble de composants et d’outils pour développer ces interfaces riches :

- Un compilateur Java-To-Javascript.
- Une librairie Javascript, émulant, avec quelques limitations, les librairies de la JRE
1.5.
- Une bibliothèque Java, GWT API.
- Un outil de debug , le GWT Shell.

1
Remote Procedure Call

Page 3
3.2.Composants

Les composants du framework s’articulent autour du compilateur Java-to-JavaScript.

Figure 1 : Les composants de GWT

Le Java-to-JavaScript Compiler

Le compilateur Java-to-javascript est le cœur du framework GWT. Il assure la création d’un


code JavaScript à partir d’un code source Java, et non pas à partir d’un bytecode. Ce
compilateur assure donc une transformation, par meta-programmation, de code en mode
text-to-text. Il s’appuie sur 2 autres composants :
- La librairie JRE Emulation, écrite en JavaScript et émulant, de façon « nécessaire et
suffisante », la JRE 1.5
- La librairie JSNI, permettant de spécifier les mécanismes d’échanges entre le code
Java et le code JavaScript.

La bibliothèque JRE Emulation Library

Cette bibliothèque JavaScript à pour rôle d’émuler les classes et méthodes de la JRE 1.5,
« nécessaires et suffisantes » à la conception d’interfaces riches. Sont notamment émulés
les packages suivants :

- java.lang, dans sa quasi-totalité.


- java.lang.annotation
- java.util
- java.io, notamment l’interface Serializable, les classes OutputStream et PrintStream.
- java.sql avec les classes Date, Time et TimeStamp.

La bibliothèque GWT API

Cette bibliothèque inclut six librairies du framework, destinées au développement de


l’application RIA proprement dite. A savoir, les bibliothèques suivantes :

- Classes graphiques (« widgets ») dans le package com.google.gwt.user.client.ui

Page 4
- La librairie d’internationalisation i18n (package com.google.gwt.i18n)
- Classes réalisant les interactions, en mode asynchrone, avec un serveur distant
(appel RPC). On trouve ces classes d’appel RPC dans les packages
com.google.gwt.user.server.rpc et com.google.gwt.user.client.rpc. Elles mettent en
œuvre l’objet « Ajax » HttpXmlRequest.
- Composants de gestion de l’historique de navigation (Package
com.google.gwt.user.client). L’application RIA créée par GWT étant entièrement en
Javascript, l’historique de navigation n’est plus géré par le navigateur. Cette librairie
offre les classes permettant cette gestion.
- Junit (package com.google.gwt.junit) permettant d’implémenter des classes de tests
unitaires.
- Librairies des traitements de document xml, parsing XML (package
com.google.gwt.xml).

Le Hosted Web Browser (GWT Shell)

Le framework GWT offre un outil de test des applications RIA développées : le Hosted Web
Browser, ou GWT Shell. Ce dernier exécute, dans un environnement minimum, les
interfaces graphiques et les appels RPC implémentés par le développeur. Pour ce faire,
GWT Shell utilise des composants issus du moteur Apache Tomcat.

En phase de développement, les avantages de GWT Shell sont les suivants :

- Pas de compilation Java-to-JavaScript.


- Déploiement sur un serveur Web inutile.
- Logging paramétrable de l’application.
- Intégration dans un I.D.E. aisée.

Figure 2 : Les fenêtres du Hosted Web Browser

Page 5
3.3.Principes de fonctionnement

3.3.1.Généralités

Le principe de fonctionnement d’une application GWT peut être décrit à travers son cycle de
vie.

Dans un premier temps, il convient de mettre en place une organisation respectueuse des
spécifications de GWT. Cette action est réalisée par l’outil applicationCreator fourni au
framework. Il va mettre en place :

- La structure des packages Java dans le répertoire de l’application.


- Un fichier xml : descripteur du module.
- Un fichier basique html, point d’entrée de présentation de l’application.

Le développement de l’application s’effectuera sur cette structure.

Figure 3 : Principes de GWT

Comme le montre la Figure 3, l’écriture du code (1.Write) va s’appuyer sur la bibliothèque


Java GWT User Interface Library afin de concevoir les modules graphiques : Widgets.
L’implémentation du code utilisera aussi les librairies Javascript qui émulent la JRE 1.5.

Ces contraintes sont nécessaires au fonctionnement correct du compilateur GWT Java-to-


Javascript (3. Compile). Ce dernier va transformer le code Java de l’interface graphique en
un code Javascript, directement exécutable par le navigateur.

Page 6
A ce stade, l’application peut être testée avec le Hosted Web Browser, et/ou déployée (4.
Run/test).

3.3.2.Principes du compilateur GWT Java-to-Javascript.

Ce compilateur représente le cœur du framework GWT. Il se base sur les concepts de méta-
modélisation afin de transformer le code Java écrit par le développeur en un code Javascript
interprété par le navigateur.
Cette transformation se base sur les relations entre le méta-modèle Java et le méta-modèle
Javascript ainsi que sur la construction d’un arbre syntaxique (AST : Abstract Syntax Tree)

On peut résumer ci-dessous les étapes de la transformation :

- Le chargeur ModuleDefLoader effectue un parcours récursif de l’arbre des modules 2


afin d’en extraire les méta-données (mappage, propriétés, héritage).
- Préparation des règles de permutations (Preferred Binding3) pour les 4 navigateurs
supportés.
- Création des arbres syntaxiques (AST). Le compilateur s’appuie massivement sur les
AST. Il met en œuvre l’API Eclipse JDT Core et un parseur « propriétaire »,
TypeOracle, afin de réaliser l’arbre syntaxique de l’application.
- Génération du script Javascript « scriptSelector » réalisant ces permutations.
- Générations des scripts Javascript.

De plus, le compilateur met en œuvre les méthodes d’optimisation suivantes :

- Le « pruning » qui correspond à une suppression totale de tout attribut ou méthode


non utilisé.
- Transformation en « finalize » des classes non-redéfinies.
- Réécriture du code non-polymorphique en « static ».
- Analyse du code Java (« type flow ») afin d’utiliser les types les plus concrets
possibles.
- Suppression du code « mort », jamais appelé.

L’efficacité du compilateur et les méthodes d’optimisation mises en œuvre permettent la


création d’un code Javascript particulièrement léger et performant.

3.3.3.Intégration dans une architecture n-tier

Tout comme les framework de présentation déjà existant, GWT permet d’accéder aux
couches inférieures d’une application. GWT étant un framework de conception d’interfaces
riches, il appartient donc à la couche « présentation » d’une application n-tier.
Le framework GWT est essentiellement orienté pour la conception d’interfaces Web riches.
De ce fait, il semble justifié de le faire exclusivement appartenir à la couche « présentation »
de l’architecture.
Mais ce framework offre des fonctionnalités d’appels de méthodes à distance (Remote
Procedure Call), permettant d’interagir avec des services distants. Cette action est

2
Un module, au regard de GWT, est un élément de l’application qui peut être rapproché d’un Use Case
graphique.
3
Le Preferred Binding est le mécanisme qui permet au framework de constituer une matrice de fichiers Javascript
en fonction de paramètres ciblés (navigateur cible, internationalisation, etc).

Page 7
implémentée sous forme d’une classe Servlet, non-transformée en Javascript, et exécutée
sur un moteur de Servlet.
Dans une première approche, nous pourrions considérer que les classes Servlet RPC du
framework appartiennent à la couche « Application ». Mais, dans l’optique d’un couplage
inter-couches le plus lâche possible, il conviendra d’intégrer ces classes RPC à la couche
« présentation »4 .

Figure 4 : classes GWT dans une architecture n-tier

Afin d’assurer cette faiblesse de couplage, les classes Servlet RPC du framework
interagissent avec le contrôleur de Use Case. Il conviendra alors d’étudier les techniques à
mettre en œuvre dans l’échange de données entre les deux couches (Objets de type Value
Object, mapping de Value Object, affranchissement du RPC GWT au profit de SOAP ou
REST …).

3.4.Points forts et limitations

Points forts

L’avantage majeur du framework est la génération du code JavaScript à partir du code Java.
Cela permet aux développeurs de se concentrer uniquement sur la technologie Java, avec
les avantages induits :

- Les compétences sont nombreuses


- Les intégrations dans les IDE (Eclipse et NetBeans) sont stables et variées
- Java permet un debug pas à pas.
- Un seul code Java est décliné, pour tous les navigateurs, par le compilateur Java-to-
JavaScript.
- Le code JavaScript généré est compact et fortement optimisé.

L’optimisation (temps de chargement réduits) est aussi un point fort de GWT, grâce à :

- L’utilisation de la compression gzip.


- L’allégement de la taille des fichiers grâce aux noms raccourcis de variables et
fonctions JavaScript.
- Le chargement des scripts dans une iframe cachée en tâche de fond.
-
- L’utilisation de la mise en cache des navigateurs.
4
Comme sont considérées les classes « actions » du framework Struts.

Page 8
-

De plus, la forte communauté impliquée dans ce projet a permis la conception de


nombreuses bibliothèques, notamment EXT-GWT5.

Limitations

Les limitations de GWT sont essentiellement celles inhérentes à JavaScript :

- Obligation, pour le navigateur, d’autoriser les scripts JavaScript


- Les appels RPC sont toujours sur le mode asynchrone.
- L’interpréteur JavaScript est mono-thread.
- GWT supporte les primitives Java, à l’exception de Long (pas de support 64 bits en
JavaScript) qui est mappé en float.

- Les styles sont exclusivement définis dans une feuille CSS.

4. Mise en œuvre

4.1.Notions de base

Les projets GWT s’articulent autour de deux concepts principaux : les modules et les Entry
Point (méthode d’entrée dans l’application). De plus, la phase de présentation, par le
navigateur, s’appuie sur un fichier Html « hôte »

4.1.1.Module

Un module GWT est une unité de projet, composée de sources Java et de ressources,
ayant une configuration unique. Cette dernière est spécifiée dans un fichier XML, de forme
« nomdumodule.gwt.xml ».
Ce fichier défini les ressources nécessaires à la compilation du projet et à son exécution.

Un mécanisme d’héritage entre les modules est disponible. Cela permet au framework GWT
de construire des applications Web complexes, à la façon des librairies et packages que l’on
trouve dans les applications Java.

4.1.2.EntryPoint

La méthode unique d’exécution d’un module GWT est définie par un « Entry Point ». Ce
dernier est décrit dans un élément xml du fichier de configuration :

<entry-point class=’fullQualifiedName.nomduprojetApp'/>

5
Bibliothèque de composants enrichissant le framework GWT : http://extjs.com/products/gxt/

Page 9
Cette balise va spécifier le nom, en notation pointée, de la classe qui implémentera
l’interface com.google.gwt.core.client.EntryPoint. Cette classe sera chargée à
l’exécution du module.

L’interface com.google.gwt.core.client.EntryPoint dispose d’une seule


méthode :

public void onModuleLoad(){



}

Cette méthode sera appelée au chargement du module. Le fonctionnement est donc


similaire à la méthode main(…) d’une application Java.

4.1.3.Le fichier Html « hôte »

Ce fichier, « nomdumodule.html », permet aux navigateurs d’exécuter les scripts


JavaScript générés par le compilateur GWT. Pour ce faire, une balise « script » est
positionnée dans l’élément « head » de fichier html.

<head>
<script type="text/javascript" language="javascript" src="
fullQualifiedName.nomduprojetApp.nocache.js">
</script>
</head>

4.2.Structure d’un projet GWT

4.2.1.Organisation physique

Figure 5 Structure d'un projet GWT

Page 10
Lors de l’initialisation d’un projet GWT, l’utilitaire « applicationCreator.cmd » va mettre
en place la structure du projet, à savoir :
- le package de l’application, contenant un package client .
- le squelette du fichier de configuration du module, nomApplication.gwt.xml ,
typiquement testApp.gwt.xml dans l’exemple de la Figure 5.
- Une classe « entry point » vide : testApp.java dans la figure supra
- le fichier html hôte, ainsi que la feuille de style css.

La Figure 5 montre l’organisation d’un projet GWT dans l’IDE Oracle Jdeveloper 10.1.3. On
remarque que le module GWT a été intégré dans une architecture en couches, notamment
dans la couche (le package) « présentation ». Le nom de l’application étant
« testAsyncApp », on remarquera le fichier de configuration testAsyncApp.gwt.xml à
la racine du package « présentation » et le fichier html hôte testAsyncApp.html dans le
dossier de publication Web.

4.2.2.Le package Client

Ce package contient toutes les classes Java qui seront transformées par le compilateur
Java-to-JavaScript, afin de produire le code JavaScript à exécuter par le navigateur. La
compilation concerne le package client et tout les sous-packages existants.

Depuis la version 1.5 du framework, les restrictions qui existaient avec la précédente version
ont été levées. Néanmoins, certains points sont à prendre en considération :

- Visibilité impossible des autres packages que « client »


- Emulation des packages Java limitée à la librairie JRE Emulation6

4.2.3.Le package Server

Ce package n’est pas crée par l’outil applicationCreator. Il doit être implémenté par le
développeur. Il contient le code qui ne sera, ni compilé en JavaScript, ni envoyé au
navigateur. Typiquement, les classes de ce package héritent de la classe « Servlet » et
implémentent les mécanismes RPC de GWT.

4.2.4.Les fichiers principaux

MonApplication.gwt.xml (plus généralement le fichier .gwt.xml)

Ce fichier au format XML décrit l'application GWT. On y trouve :

- Les modules dont hérite l'application.


- La description d'un module.
- La classe EntryPoint du module.
- Les « servlet » fournissant des services côté serveur.

6
http://code.google.com/docreader/#p=google-web-toolkit-doc-1-5&s=google-web-toolkit-doc-1-
5&t=RefJreEmulation

Page 11
Exemple :

<module>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/>
<!-- Inherit the default GWT style sheet. You can change -->
<!-- the theme of your GWT application by uncommenting -->
<!-- any one of the following lines. -->
<inherits name='com.google.gwt.user.theme.standard.Standard'/>
<!-- Other module inherits -->
<!-- Specify the app entry point class. -->
<entry-point class='cedii.testcasegwt.client.testApp'/>
<!-- Specify the servlet . -->
<servlet path="/AppelAbsence"
class="cedii.testcasegwt.server.AppelAbsenceImpl"/>
<!-- Specify the application specific style sheet. -->
<stylesheet src='testApp.css'/>
</module>

L’élément <inherits> permet de définir les héritages du module. Par défaut, le module hérite
de la classe com.google.gwt.user.User (implémentation de tout les widgets GWT). Afin
d’activer l’internationalisation, on fera hériter le module de la classe
com.google.gwt.i18n.I18N.

L’élément <entry-point> défini la classe Java qui implémente l’interface EntryPoint de GWT.
C’est le point d’entrée dans l’application. (voir 4.1.2).

MonApplication.html (le fichier hôte HTML)

Ce fichier HTML ne contient quasiment aucun code HTML. Il permet juste au navigateur de
charger le module et le code JavaScript associé. Il est également possible de définir dans ce
fichier des slots dans lequel les composants graphiques vont venir s'insérer.

Exemple de fichier :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!-- -->
<!-- Any title is fine -->
<!-- -->
<title>testApp</title>

<!-- -->
<!-- This script loads your compiled module. -->
<!-- If you add any GWT meta tags, they must -->
<!-- be added before this line. -->
<!-- -->
<script type="text/javascript" language="javascript"
src="cedii.testcasegwt.testApp.nocache.js"></script>
</head>

<!-- -->
<!-- The body can have arbitrary html, or -->
<!-- you can leave the body empty if you want -->
<!-- to create a completely dynamic UI. -->
<!-- -->
<body>

<!-- OPTIONAL: include this if you want history support -->

Page 12
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1'
style="position:absolute;width:0;height:0;border:0"></iframe>

</body>
</html>

Ce fichier est simpliste car tous les composants graphique sont inclus dans le script
JavaScript cedii.testcasegwt.testApp.nocache.js

MonApplication.java (L'EntryPoint)

Cette classe, contenue dans le package « client », implémente l’interface


com.google.gwt.core.client.EntryPoint .

public class testAsyncApp implements EntryPoint {

/**
* This is the entry point method.
*/
public void onModuleLoad() {

}
}

Comme le montre le code ci-dessus, cette classe n’implémente qu’une seule méthode :
onModuleLoad().
C’est cette classe qui implémente les composants graphiques GWT et qui sera transformée
en JavaScript par le compilateur Java-to-JavaScript.

4.3.La gestion des évènements

On retrouvera, dans la version 1.5 du framework, une gestion des événements similaire à
celle implémentée dans d’autres interfaces graphiques comme AWT ou Swing.

4.3.1.Types d'évènements

Les composants de l'interface WEB sont susceptibles d'émettre des évènements en fonction
des actions de l'utilisateur :
- clic sur un bouton,
- modification de la valeur d'un champ de saisie,
- …

GWT supporte tous les événement susceptibles d'être géré par les navigateurs WEB :

BUTTON_LEFT ONDBLCLICK ONLOAD


BUTTON_MIDDLE ONERROR ONLOSECAPTURE
BUTTON_RIGHT ONCLICK ONSCROLL
ONCHANGE

KEYEVENTS MOUSEEVENTS FOCUSEVENTS


ONKEYDOWN ONMOUSEDOWN ONBLUR

Page 13
ONKEYPRESS ONMOUSEMOVE ONFOCUS
ONKEYUP ONMOUSEOUT
ONMOUSEOVER
ONMOUSEUP

Le framework permet de gérer des évènements plus spécifiques aux navigateurs Web,
comme :

- la soumission de formulaire
- la fermeture de popup
- les actions sur des cellules de tableau
- les actions sur des onglets
- les clics sur un arbre (Tree)
- le dimensionnement et fermeture d’une fenêtre.

4.3.2.Gérer les évènements

Pour effectuer un traitement en fonction des évènements générés, il faut (comme avec
SWING) attacher des « Listeners » aux composant dont on veut traiter les évènements.

Par exemple :

Button bouton = new Button("Cliquer");


bouton.addClickListener(new ClickListener(){
public void onClick(Widget sender){
Window.alert("Le bouton a été cliqué");
}
});

Chaque widget possède un certain nombre de méthodes addXXListener, qui reçoivent en


paramètre un « Listener » précis. L’interface « Listener » hérite de « EventListener ». Cette
dernière ne définie qu’une seule méthode onBrowserEvent qui sera levé lorsqu’un
événement7 se produira dans le navigateur.

4.4.Communication asynchrone Client / Server


4.4.1.Principes de fonctionnement

La communication entre le client et le serveur se fait d’une manière asynchrone par


l’implémentation d’un mécanisme de RPC (Remote Procedure Call) classique.
L’asynchronisme signifie que, une fois l'appel effectué, le code « client » continue de
s'exécuter sans attendre de réponse.

Les communications asynchrones fonctionnent sur le principe des « Events Handler »


(Gestionnaire d'événements). Pour ce faire, le développeur implémente un objet de type
« CallBack », dont le code sera exécuté à la réception de la réponse du serveur.

7
voir la liste des constantes de la classe Event : API javadoc classe Event

Page 14
Figure 6 Principe de l'asynchronisme

Le framework GWT met en œuvre ce mécanisme de « CallBack » à travers un objet de type


« Proxy », généré automatiquement à l’exécution du module GWT. Cet objet aura la
responsabilité de sérialiser/désérialiser les appels au serveur (une classe « servlet »
fournissant le service attendu) et de traiter l’enchaînement requête/réponse.

Figure 7 Rôles des éléments RPC GWT

Plus précisément, on trouvera les classes mises en jeu dans le diagramme de classe infra

Figure 8 Diagramme de classes simplifié, mécanisme RPC

Dans la suite de ce document, nous considérerons des fragments de code du cas de test, à
savoir l’affichage d’une collection d’objets de type DTO nommés « Absences ».

Page 15
L'interface du service.

Cette interface, qui se trouve dans le package « client » défini le contrat de service de l’appel
RPC. Elle étend com.google.gwt.user.client.rpc.RemoteService

import com.google.gwt.user.client.rpc.RemoteService;

import java.util.List;

public interface AppelAbsence extends RemoteService {

public AbsenceDTO getAbsenceById(Integer id)throws


IllegalArgumentException;

public List<AbsenceDTO> getAllAbsences();


}

Elle va servir à définir le contrat de l’implémentation, coté serveur, qui sera exécuté sous
forme de servlet.

L’implémentation coté Serveur

Dans le package « server », celui qui ne sera pas transformé en JavaScript par le
compilateur, on place l’implémentation de l’interface du service.

import cedii.testcasegwt.client.AbsenceDTO;
import cedii.testcasegwt.client.AppelAbsence;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import java.util.ArrayList;
import java.util.List;
/**
* Classe implémentation de l'interface de service cliente.
*
*/
public class AppelAbsenceImpl extends RemoteServiceServlet implements
AppelAbsence {

public AppelAbsenceImpl() {
super();
}
public AbsenceDTO getAbsenceById(Integer id) {

// . . . //
}

/**
* Méthode retournant la liste de toute les absences
* @return
*/
public List<AbsenceDTO> getAllAbsences() {
List<AbsenceDTO> lesAbsences = new ArrayList();

AbsenceDTO uneAbsence = new AbsenceDTO();


uneAbsence.setIdAbsence(Long.valueOf(1));
uneAbsence.setCposs("618896");
uneAbsence.setDateDebut("12/10/2007");
uneAbsence.setDateFin("20/10/2007");
uneAbsence.setTypeAbsence("RTT");
lesAbsences.add(uneAbsence);

Page 16
AbsenceDTO uneAbsence1 = new AbsenceDTO();
uneAbsence1.setIdAbsence(Long.valueOf(2));
uneAbsence1.setCposs("902832");
uneAbsence1.setDateDebut("14/07/2008");
uneAbsence1.setDateFin("01/08/2008");
uneAbsence1.setTypeAbsence("CA");
lesAbsences.add(uneAbsence1);

return lesAbsences;
}
}

Cette classe hérite de RemoteServiceServlet qui étend lui-même HttpServlet. Nous


avons donc affaire à une servlet qui implémente les méthodes de l’interface du service.
Nous verrons plus loin la justification de l’utilisation d’helperDTOMapping.
Dans le Test Case, les méthodes retournent des DTO, ou des listes de DTO.

Les types retournés doivent obligatoirement implémenter l’interface Serializable.

L’interface asynchrone

Toujours dans le package « client », le développeur devra implémenter une interface


spécifiant les méthodes de service, avec un objet Callback passé en paramètre.
La règle de nommage de cette interface est la suivante : nom de l’interface suffixée de
« Async ».

Le code ci-dessous montre l’interface asynchrone du cas de test.

import com.google.gwt.user.client.rpc.AsyncCallback;
import java.util.List;

public interface AppelAbsenceAsync {


public void getAbsenceById(Integer id, AsyncCallback<AbsenceDTO>
callback);

public void getAllAbsences(AsyncCallback<List<AbsenceDTO>> callback);


}

On remarque que les méthodes ne retournent rien, puisque c’est l’objet AsynCallBack qui
recevra les retours des appels RPC.

L’appel dans la classe « EntryPoint ».

Une fois ces classes implémentées, la mise en œuvre de l’appel asynchrone peut être faite
dans la méthode onLoad() de la classes EntryPoint. Le mécanisme en est le suivant :

- Création de l’objet Proxy par une méthode (Create) d’une Factory GWT.
- Instanciation du, ou des, objets AsyncCallBack

L’exemple est donné dans le fragment de code ci-dessous.

public class testApp implements EntryPoint {

/**
* This is the entry point method.
*/

Page 17
public void onModuleLoad() {

//GWT.create : génération du proxy du service


appelAsyncProxy =
(AppelAbsenceAsync)GWT.create(AppelAbsence.class);

// Mapping (endpoint) vers le servlet distant


ServiceDefTarget endpoint = (ServiceDefTarget)appelAsyncProxy;

// Définition de l'URL d'appel


String moduleRelativeURL = GWT.getModuleBaseURL() +
"/AppelAbsence";

// pointe vers l'url réelle du service distant


endpoint.setServiceEntryPoint(moduleRelativeURL);

// Déclaration de la classe objet callback


callbackGetAllAbsence = new
AsyncCallback<Collection<AbsenceDTO>>() {
public void onFailure(Throwable throwable) {
Window.alert(throwable.getStackTrace().toString())
;
}

public void onSuccess(Collection result) {


Collection<AbsenceDTO> lesAbsences = result;
populateTable(lesAbsences, ftable);
}
};
}

L’objet Proxy.

A l’exécution, la méthode create du framework GWT est appelée afin de créer un objet
Proxy, appelAsyncProxy dans l’exemple du Test Case. Ce Proxy implémente l’interface
de Service Asynchrone et l'interface ServiceDefTarget. Il sera responsable, coté client,
des appels à la servlet coté serveur.
Plus précisément, l’objet Proxy à pour rôles :

- Sérialiser la requête.
- Envoyer la requête
- Recevoir la réponse
- Désérialiser la réponse

L’interface ServiceDefTarget permet de définir la localisation « physique » de la servlet


rendant le service distant.

L’objet AsyncCallback

Chaque appel à une méthode côté serveur sera traité, coté client, par un objet de type
AsyncCallback. Cet objet ne possède que deux méthode, onSuccess et onFailure, qui
seront invoquées en fonction de la réponse retournée par la servlet du serveur.

La première méthode est celle qui est appelée en cas de succès de la requête et elle
possède en paramètre l'objet retourné par la méthode appelée.

La seconde méthode est celle qui est appelée en cas d'échec de la requête. Elle possède en
paramètre l'objet de type Throwable lancé par le code côté serveur.

Page 18
En résumé, le mécanisme mise en œuvre par GWT afin d’effectuer les appels asynchrones,
de type RPC, peut être décrit par le diagramme de séquence infra

Figure 9 Diagramme de séquence mécanisme RPC GWT

Coté serveur, on remarquera que les appels sont reçus par une servlet du framework GWT
(RemoteServiceServlet) qui déléguera les méthodes « métiers » à la servlet
implémentant le service.

Page 19
Figure 10 Diagramme d'activité des appels RPC de GWT

4.4.2.Particularité de la sérialisation implémentée par GWT

Principe

Lors de la création de requêtes ou de réponses, GWT sérialise automatiquement les


éléments à transférer :
- Objets passés en paramètres des appels de services
- Objets retournés par les servlets du coté serveur

Cette sérialisation s’appuie sur la librairie JRE Emulation. Cette bibliothèque supporte la
plupart des types java.lang. Quelques restrictions sont néanmoins présentes8 :

- En JavaScript, le seul type numérique supporté est le type 64 Bit en base flottante.
8
Voir : coding GWT

Page 20
GWT ne sérialise pas les champs qui sont marqués final.
La sérialisation fournie par GWT gère également l'héritage.

4.4.3.Propagation des exceptions.

Le framework prend en charge les exceptions définies par la bibliothèque JRE Emulation. De
même, les exceptions « métiers » seront propagées, uniquement si elles sont composées de
types définis par la JRE Emulation.

Les exceptions dues aux appels RPC du framework seront de 2 types, « Checked
Exception » et « Unexpected Exceptions ».

Checked Exception

Les « Checked Exception » sont propagées depuis l’implémentation d’un service (coté
serveur). Elles doivent êtres capturés par un client implémentant la méthode
AsyncCallBack.onFailure(Throwable).

Unexpected Exceptions

Ces exceptions sont de deux types :


- InvocationException, qui est levé lorsque que l’accès à l’implémentation du service
est impossible. Dans ce cas, l’exception est passée à l’implémentation de la méthode
AsyncCallBack.onFailure(Throwable).
- IncompatibleRemoteServiceException est produite lorsque l’interface de service (coté
client) et son implémentation (coté serveur) ne sont plus en phase. Dans le cas, par
exemple, ou une nouvelle interface est déployée coté client alors que sont ancienne
implémentation est toujours active.

4.5.Cas de Test

Afin de cerner la technologie GWT, on va mettre en œuvre un cas de test. Ce cas affichera,
après action sur un bouton, une liste de données. L’accès aux données sera appels
asynchrones.
Ce cas de test sera géré sous Jdeveloper 10.1.3.4.

4.5.1.Création du squelette de l’application.

On va réaliser cette mise en place grâce à l’outil applicationCreator fourni par le


framework

En mode console, on va exécuter :

applicationCreator -out c:\testcaseGwt


cedii.testcasegwt.presentation.client.testApp

Page 21
Le paramètre –out détermine le chemin du projet, il est suivi par le nom qualifié de la classe
implémentant le « entry point ». Les spécifications de GWT imposent que cette classe soit
incluse dans un package « client ».

Cet utilitaire va mettre en place la structure dans le dossier c:\testcaseGwt, le nom du


module est « testApp » et il est inclus dans le package cedii.testcasegwt.presentation.client

Les options complètes de applicationCreator sont affichées par l’option « -help »

La sortie de console montre les actions réalisées :

Created directory c:\testcaseGWT\src


Created directory c:\testcaseGWT\src\cedii\testcasegwt\presentation
Created directory c:\testcaseGWT\src\cedii\testcasegwt\presentation\client
Created directory c:\testcaseGWT\src\cedii\testcasegwt\presentation\public
Created file
c:\testcaseGWT\src\cedii\testcasegwt\presentation\testApp.gwt.xml
Created file
c:\testcaseGWT\src\cedii\testcasegwt\presentation\public\testApp.ht
ml
Created file
c:\testcaseGWT\src\cedii\testcasegwt\presentation\public\testApp.cs
s
Created file
c:\testcaseGWT\src\cedii\testcasegwt\presentation\client\testApp.ja
va
Created file c:\testcaseGWT\testApp-shell.cmd
Created file c:\testcaseGWT\testApp-compile.cmd

On remarquera que le répertoire « server », nécessaire aux appels asynchrone, n’est pas
créé. Il faudra donc le faire manuellement.

4.5.2.Importation dans Jdeveloper 10.1.3.X

Un « plugin GWT » existe pour Jdeveloper. Mais il ne nous semble pas finalisé, ni stable.
L’importation du squelette applicatif sous Jdeveloper se fera donc manuellement.

Il convient de suivre les étapes suivantes :

- Créer un nouveau projet WEB (Web Project)

Page 22
Figure 11 Création du projet dans JDeveloper 10.1.3.x

- Suivant
- Sélectionner le dossier créé précédemment C:\testcaseGwt

Figure 12 Nommage du projet

- Suivant

Page 23
Figure 13 Choix de la version de Servlet

- Suivant

Figure 14 Profile Web du projet

- Suivant
- Fin

Le projet apparaît dans la liste de Jdeveloper :

Page 24
Figure 15 Structure du projet dans JDeveloper 10.1.3.x

Il convient aussi définir les librairies de GWT dans le classpath du projet. Pour ce faire, il
faut :
- Clic droit sur le projet  properties  Libraries
- Add Jar/Directory
- Ajouter les Jars de GWT présent dans le dossier gwt-windows-1.5.x. La librairie
gwt-benchmark-viewer.jar n’est pas nécessaire si l’on ne désire pas faire
d’évaluation des performances.
- Ajouter le dossier contenant les sources du projet .

Figure 16 Déclaration des bibliothèques dans le classpath

Afin de tester l’application, il faut configurer l’exécution en mode Hosted (shell). Ce mode
d’exécution sera défini dans l’item « Run/Debug » des propriétés du projet. Faire « New »
afin de créer une nouvelle condition d’exécution. La nommer « GWT Shell ».

Page 25
Figure 17 Création d'un profile d'exécution

Cliquez sur Edit afin de définir les propriétés d’exécution (Lauch Settings)

Dans « Default Run Target », utiliser le bouton « Browse » afin de sélectionner le chemin
de la classe GWTShell.class .

Figure 18 Paramètres du profile d'exécution

Depuis la version 1.5 de GWT, il convient de positionner la mémoire d’exécution de la


JVM à 512 Mo en définissant « Java Options » à –Xmx512M

Dans Program Arguments, spécifier les arguments du GWTShell, à savoir :

- le chemin du fichier html hôte après la directive « -out »


- la politique de création du code JavaScript utilisée. Si DETAILLED, le code généré
est compréhensible9.
- « -logLevel » donne le niveau de journalisation.
- Le chemin du fichier hôte au sein du package de l’application et au regard répertoire
contenant le fichier de description gwt.xml

Dans le cas du cas de test, l’argument Program Arguments aura les paramètres suivants :

-out C:\testcaseGWT\public_html -style DETAILED -logLevel DEBUG


cedii.testcasegwt.presentation.testApp/testApp.html

4.5.3.Test de l’exécution en mode « Hosted »

9
Décrit dans la documentation GWT : http://code.google.com/docreader/#p=google-web-toolkit-doc-1-
5&s=google-web-toolkit-doc-1-5&t=DevGuideModuleHostedModeScript

Page 26
A ce stade de l’implémentation, le squelette fourni une page simple qui affiche un bouton.
Pour test, il convient de l’exécuter en mode « Hosted » (le Hosted Web Browser réalisé par
la classe GWTShell). Sélectionner la classe testApp.java et cliquer sur l’icône « run »
de Jdevelopper.

« GWT Development Shell » se lance :

Figure 19 Le Serveur en mode "Hosted"

Puis le « Hosted Browser », pointant vers l’application :

Figure 20 Le navigateur en mode "Hosted"

Le mode « hosted » peut aussi être lancé par l’appel à la commande monAppli-
shell.cmd présente à la racine du projet. Avec Jdevelopper, il peut être intéressant de
définir cette commande comme outil externe (menu Tools -> External Tools).

4.5.4.Implémentation de l’appel RPC.

Le Test Case testcasegwt permet de mettre en œuvre, de façon triviale, les objets
nécessaires aux appels RPC.

L'interface de service coté « client »

import com.google.gwt.user.client.rpc.RemoteService;

Page 27
import java.util.List;

public interface AppelAbsence extends RemoteService {

public AbsenceDTO getAbsenceById(Integer id)throws


IllegalArgumentException;

public List<AbsenceDTO> getAllAbsences();

Cette interface définit les méthodes du service disponible côté serveur. On remarque que
l’utilisation des types génériques est possible depuis la version 1.5 du framework.

L'interface de service asynchrone coté « client » :

import com.google.gwt.user.client.rpc.AsyncCallback;

import java.util.List;

public interface AppelAbsenceAsync {


public void getAbsenceById(Integer id, AsyncCallback<AbsenceDTO>
callback);

public void getAllAbsences(AsyncCallback<List<AbsenceDTO>> callback);


}

Les méthodes sont liées à celles de l'interface de service, comme vu précédemment. Mais
de plus, toutes les méthodes reçoivent en paramètres l’objet callback.

La classe implémentant le service coté « serveur » :

import cedii.testcasegwt.client.AbsenceDTO;
import cedii.testcasegwt.client.AppelAbsence;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import java.util.ArrayList;
import java.util.List;

/**
* Classe implémentation de l'interface de service cliente.
*
*/
public class AppelAbsenceImpl extends RemoteServiceServlet implements
AppelAbsence {

public AppelAbsenceImpl() {
super();
}

public AbsenceDTO getAbsenceById(Integer id) {

AbsenceDTO result = null;

return null;
}

/**

Page 28
* Méthode retournat la liste de toute les absences
* @return
*/
public List<AbsenceDTO> getAllAbsences() {
List<AbsenceDTO> lesAbsences = new ArrayList();

AbsenceDTO uneAbsence = new AbsenceDTO();


uneAbsence.setIdAbsence(Long.valueOf(1));
uneAbsence.setCposs("618896");
uneAbsence.setDateDebut("12/10/2007");
uneAbsence.setDateFin("20/10/2007");
uneAbsence.setTypeAbsence("RTT");
lesAbsences.add(uneAbsence);

AbsenceDTO uneAbsence1 = new AbsenceDTO();


uneAbsence1.setIdAbsence(Long.valueOf(2));
uneAbsence1.setCposs("902832");
uneAbsence1.setDateDebut("14/07/2008");
uneAbsence1.setDateFin("01/08/2008");
uneAbsence1.setTypeAbsence("CA");
lesAbsences.add(uneAbsence1);

return lesAbsences;
}
}

Cette classe, qui hérite de Servlet, implémente l’interface de service et retourne le résultat de
l’appel du service. Elle est déployée coté serveur et ne sera pas transformée par le
compilateur Java-to-Javascript. La méthode getAllAbsences() retourne une collections
de DTO (Data Transfert Object) Absence.

La classe DTO :

import java.io.Serializable;

/**
* Classe Value Object représentant une Absence
*/
public class AbsenceDTO implements Serializable {
private Long idAbsence;
private String cposs, typeAbsence, domaineCram, dateDebut, dateFin;

public AbsenceDTO() {
}

public void setIdAbsence(Long idAbsence) {


this.idAbsence = idAbsence;
}

public Long getIdAbsence() {


return idAbsence;
}

public void setDateDebut(String dateDebut) {


this.dateDebut = dateDebut;
}

public String getDateDebut() {


return dateDebut;
}

public void setDateFin(String dateFin) {


this.dateFin = dateFin;
}

Page 29
public String getDateFin() {
return dateFin;
}

public void setCposs(String cposs) {


this.cposs = cposs;
}

public String getCposs() {


return cposs;
}

public void setTypeAbsence(String typeAbsence) {


this.typeAbsence = typeAbsence;
}

public String getTypeAbsence() {


return typeAbsence;
}

public void setDomaineCram(String domaineCram) {


this.domaineCram = domaineCram;
}

public String getDomaineCram() {


return domaineCram;
}

public boolean equals(Object obj) {


if (this == obj) {
return true;
}
if (obj instanceof AbsenceDTO) {
AbsenceDTO autreDto = (AbsenceDTO)obj;
if (this.idAbsence != autreDto.idAbsence) {
return false;
}
return true;
}
return false;
}

public String toString() {


StringBuffer sb = new StringBuffer();
sb.append(this.idAbsence.toString());
sb.append(" : ");
sb.append(this.cposs);
sb.append(" - ");
sb.append(this.dateDebut.toString());
return sb.toString();
}
}

Afin de pouvoir traverser les couches du framework GWT, cette classe doit obligatoirement
implémenter l’interface Serialisable.

La classe « module » implémentant EntryPoint :

public class testApp implements EntryPoint {

private AppelAbsenceAsync appelAsyncProxy;


private AsyncCallback callbackGetAllAbsence;

/**
* This is the entry point method.
*/
public void onModuleLoad() {

Page 30
// Création du Panel
VerticalPanel vPanel = new VerticalPanel();
vPanel.setWidth("100%");
vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);

// Création du Bouton
Button button = new Button("Afficher Absences");

// Création d'une table HTML


final FlexTable ftable = new FlexTable();
//.. .
// code existent dans le test Case

// ajout du bouton et de la table au Panel


vPanel.add(button);
vPanel.add(ftable);
RootPanel.get().add(vPanel);

//GWT.create : génération du proxy du service


appelAsyncProxy =
(AppelAbsenceAsync)GWT.create(AppelAbsence.class);

// Mapping (endpoint) vers le servlet distant


ServiceDefTarget endpoint = (ServiceDefTarget)appelAsyncProxy;

// Définition de l'URL d'appel


String moduleRelativeURL = GWT.getModuleBaseURL() +
"/AppelAbsence";

// pointe vers l'url réelle du service distant


endpoint.setServiceEntryPoint(moduleRelativeURL);

// Déclaration de la classe objet callback


callbackGetAllAbsence = new
AsyncCallback<Collection<AbsenceDTO>>() {
public void onFailure(Throwable throwable) {
Window.alert(throwable.getStackTrace().toString())
;
}

public void onSuccess(Collection<AbsenceDTO> result) {


populateTable(result, ftable);
}
};

button.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
appelAsyncProxy.getAllAbsences(callbackGetAllAbsen
ce);
}
});
}

Les points important dans cette classe sont :


- Création du proxy par appel de
(AppelAbsenceAsync)GWT.create(AppelAbsence.class).
- Mapping vers le lien réel URI de la servlet implémentant le service :
setServiceEntryPoint
- Instanciation de l’objet CallBack qui va attendre la réponse de la servlet implémentant
le service.

Page 31
Le fichier HTML d'entrée testApp.html :

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!-- -->
<!-- Any title is fine -->
<!-- -->
<title>testApp</title>

<!-- -->
<!-- This script loads your compiled module. -->
<!-- If you add any GWT meta tags, they must -->
<!-- be added before this line. -->
<!-- -->
<script type="text/javascript" language="javascript"
src="cedii.testcasegwt.testApp.nocache.js"></script>
</head>

<!-- -->
<!-- The body can have arbitrary html, or -->
<!-- you can leave the body empty if you want -->
<!-- to create a completely dynamic UI. -->
<!-- -->
<body>

<!-- OPTIONAL: include this if you want history support -->


<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1'
style="position:absolute;width:0;height:0;border:0"></iframe>

</body>
</html>

Afin que la servlet soit exécutée en mode « Hosted », il convient d’en spécifier le chemin
dans le fichier de configuration gwt.xml :

<servlet path="/AppelAbsence"
class="cedii.testcasegwt.serveur.AppelAbsenceImpl"/>

Le chemin sera « mappé » en regard du paramètre passé à la méthode


GWT.getModuleBaseURL de l’application.

Toute l’application étant produite dans les scripts JavaScript, mise en cache, on remarque
que ce fichier est simplissime. Le module sera chargé par le script
cedii.testcasegwt.testApp.nocache.js

4.5.5.Déploiement dans un container OC4J Standalone

Avant d’effectué le déploiement, il convient de « compiler » l’application en fichiers


JavaScript. Pour ce faire, deux méthode sont disponibles :

- En mode « Hosted », cliquer sur « compile/Browse »


- En mode console, lancer le script monAppli-compile.cmd

Dans le cas d’une application mettant en œuvre les appels RPC, il faudra spécifier le chemin
des servlet, impémantant les services, dans le descripteur web.xml

Page 32
Il faudra donc correctement positionner la balise <servlet-mapping> du fichier web.xml, afin
que l’appel RPC point correctement vers la servlet. Dans notre cas de test, on fera :

<servlet>
<servlet-name>AppelAbsence</servlet-name>
<servlet-class>cedii.testcasegwt.server.AppelAbsenceImpl
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AppelAbsence</servlet-name>
<url-pattern>cedii.testcasegwt.testApp/AppelAbsence</url-pattern>
</servlet-mapping>

Par la suite, le déploiement sur un serveur d’application se résume à :

- publier les fichier JavaScript, css et html générés (package client de l’application
GWT)
- déployer les servlet du package server.
- installer la bibliothèque gwt-user.jar et gwt-servlet.jar.

Il conviendra donc de crée un descripteur de déploiement Web sous Jdevelopper 10.1.3.4 :

Faisons New -> Deployement Profiles sur le projet, choisir War Files :

Figure 21 Choix du type de déploiement

Ensuite, on devra définir les différentes sources dans le fichiers de déploiement, dans notre
cas de test, ce fichier se nomme webapp.deploy.

Page 33
Figure 22 Spécification du contexte de déploiement

Une fois cet écran renseigné, il faudra renseigner les différents « File Groups ». Dans le File
« Groups Web Files », on choisi « Project HTML Root Directory » comme « Contributor » et
l’on spécifie les « Filters » comme montré ci dessous :

Figure 23 Choix des contributeurs Web

On procédera de la même façon pour les groupes « WEB-INF/classes » et « WEB-INF/lib ».


Les spécifications sont décrites dans les figures ci-dessous.

Page 34
Figure 24 Choix des classes contributrices

Figure 25 Choix des bibliothèques nécessaires

Une fois le descripteur de déploiement configuré, on peut déployer l’application GWT sur un
serveur OC4J Standalone, comme on le ferais pour une application Web classique.
Le fichier .war associé à l’application est déployé sur le serveur, son contenu est décrit dans
la figure infra .

Page 35
Figure 26 Contenu du fichier war d'une application GWT

Pour l’exécution du cas de test, l’appel à l’application se fait par l’url suivant :

http://localhost:8888/testgwt/cedii.testcasegwt.testApp/testApp.html

L’appel de l’url de l’application affiche le résultat suivant :

Figure 27 Exemple de résultat en mode déployé

On remarque que l’appel RPC fonctionne correctement.

Page 36
5. Notions avancées
5.1.L'accessibilité

GWT produisant des applications JavaScript, et non du code HTML, l’implémentation des
fonctionnalités d’accessibilité reste problématique. Le projet ARIA10 (Accessible Rich Internet
Applications) un projet en cours du W3C semble être une réponse.

ARIA propose d’adapter l’arbre DOM11 des objets JavaScript afin de les rendre accessibles
aux périphériques lecteurs d’écran (Brail ou sonores).

Mais, ce projet étant toujours en développement, tous les navigateurs ne vont pas produire
les événements prise en charge par ARIA.

5.1.1.ARIA et GWT

ARIA va permettre d’ajouter, au DOM des composants graphiques de GWT, deux types de
fonctionnalités :
- Prise en charge du rôle (ce qu’il fait) du widget.
- Prise en charge de l’état du widget.

Actuellement, la plupart des widgets GWT incluent les propriétés ARIA et les raccourcis
Clavier. Notamment, CustomButton, Tree, TreeItem, MenuBar, MenuItem, TabBar, et
TabPanel.
De plus, tout les widgets qui héritent de la classe FocusWiddget contiennent, par défaut, une
balise « tabindex », facilitant la navigation clavier.

5.1.2.Ajout de l’accessibilité dans les composants (Widgets) GWT.

La compatibilité avec les fonctionnalités ARIA est implémentée dans la classe


com.google.gwt.user.client.ui.Accessibility.

Grâce à cette classe, Il conviendra de mettre en correspondance les rôles et états de la


spécification ARIA avec les comportements des widgets GWT12.

5.2.Internationalisation des applications sous GWT

L’internationalisation des applications est prise en charge par le framework. Deux interfaces
sont disponibles afin d’assurer cette fonctionnalité.

10
http://wiki.codetalks.org/wiki/index.php/Main_Page
11
Document Object Model
12
Toute la mise en œuvre ARIA sur le lien suivant ARIA and GWT

Page 37
5.2.1.L’interface Constants

Cette interface permet, à partir d’un fichier de propriétés .properties, de remplacer les textes
statiques par l’appel à une méthodes. Cette méthodes retournera un texte présent dans le
fichier .properties correspondant à la localisation de l’application.

La mise en œuvre dans le cas de test débute par l’exécution de l’outil i18nCreator qui va
mettre en place l’interface Constants, un fichier « properties » vide ainsi qu’un utilitaire
xxxConstants-i18n.cmd permettant de mettre à jours l’interface en fonction des fichiers
« properties ».

L’outil en mode console, i18nCreator, prend un certains nombre de paramètres, mais pour le
cas de test, nous l’utiliserons de la sorte :

C:\gwt-windows-1.5.2>i18nCreator -out c:\testcaseGWT\


cedii.testcasegwt.client.i18n.TestConstants

Le paramètre –out spécifie le chemin de l’application, il est suivi par le nom, totalement
qualifié, de l’interface de localisation.

Ainsi, dans le cas de test, l’exécution de i18nCreator aura créé :

- TestConstants.properties.
- L’outil TestConstants-i18n.cmd

On complète le fichier « properties » et l’on crée son pendant français.

TestConstants.properties :

ClassName: TestConstants
tabletitle = holidays
displayword = display

TestConstant_fr.properties :

ClassName: TestConstants
tabletitle = Absences
displayword = Afficher

Après l’exécution de l’outil testConstants-i18n.cmd, l’interface


testConstants.java est crée ou modifiée de la sorte :

public interface TestConstants extends


com.google.gwt.i18n.client.Constants {
/**
* Translated "display".
*
* @return translated "display"
*/
@DefaultStringValue("display")
String displayword();

/**
* Translated "holidays".
*
* @return translated "holidays"
*/
@DefaultStringValue("holidays")

Page 38
String tabletitle();

/**
* Translated "testConstants".
*
* @return translated "testConstants"
*/
@DefaultStringValue("testConstants")
String ClassName();
}

On voit que la localisation par défaut est celle définie dans le fichier
TestConstants.porperties, afin de rendre la localisation « fr » accessible, il faudra le
spécifier dans le fichier de configuration du module (testApp.gwt.xml)

<inherits name="com.google.gwt.i18n.I18N"/>
<!-- French language, independent of country -->
<extend-property name="locale" values="fr"/>

Cette directive rend disponible l’affichage « localisé » de l’application, dans le cas contraire,
la localisation par défaut (En) est toujours exécutée.

Il convient maintenant de spécifier l’appel aux méthodes dans le code de l’application. Ainsi,
dans le module testApp.java, on trouvera :

TestConstants useConstant =
(TestConstants)GWT.create(TestConstants.class);
Button button = new Button(useConstant.displayword()+" " +
useConstant.tabletitle());

Le choix de la localisation à l’exécution du module ne peut se faire qu’a travers la pages


HTML Hôte. En effet, la production des script JavaScripts est faite par le compilateur avant
leur envoi aux navigateurs. La localisation est donc demandée de deux façons :

- soit par l’ajout d’une balise <meta name="gwt:property" content="locale=x_Y">dans


la page hôte.
- Soit par la paramétrage de la requête http en ajoutant à l’URL du module :
« ?locale=fr »

Le résultat devient le suivant :

Figure 28 Exemple de texte statique par défaut

et en paramétrant la requête http :

Page 39
Figure 29 Exemple de texte statique "localisé" Fr

Attention, après chaque modification des fichiers « properties », il conviendra de ré-appliquer


les utilitaires xxx-i18n.cmd

5.2.2.L’interface Messages

Cette interface permet, toujours selon des fichiers .properties, de fournir des messages
paramétrés, selon la localisation de l’application.
Le principe de fonctionnement est similaire à celui de l’interface Constants.
Les fichiers « properties » seront de la forme :

welcome: Welcome. The current time is {0}.


rpcok: RPC call finished at {0}

welcome: Bienvenue. Il est {0}.


rpcok: L'appel RPC s'est terminé à {0}

Le paramètre {0} sera reçu par l’appel de la méthode.

L’exemple dans la classe module montre le fonctionnement.

Instanciation de l’interface Messages :

useMessages = (TestMessages)GWT.create(TestMessages.class);

Appel de la méthode avec passage de paramètre afin de l’afficher dans un Label :

Date time = new Date();


infoLabel.setText(useMessages.rpcok(time.toString()));

Les figures suivantes montrent le résultat, à l’exécution

Page 40
Figure 30 Exemple de messages paramétrés par défaut

Figure 31 Exemple de messages paramétrés "localisé" Fr

Dans la version actuelle de GWT (1.5), il n’existe pas de mécanisme permettant de


récupérer la « locale » du navigateur.

La solution la plus simple pourrait être d’appeler l’application GWT, à travers une JSP qui
fournirait la localisation en paramètre de l’url.

Par contre, le mécanisme de « Deffered Binding » permettant l’envoi au client de fichiers


spécifique à la localisation et au navigateur (donc de taille réduite), le chargement d’une
nouvelle page « localisée » est très rapide.

5.3.Sécurité

Il convient d’apprécier le comportement des modules, développées avec GWT, selon l’angle
de la sécurité des applications Web. Par contre, il faudra garder à l’esprit que le framework
produit un code JavaScript, et que de ce fait, on rencontrera toutes les vulnérabilités
inhérentes à ce langage. Ces problématiques de sécurité avec GWT sont abordées dans un
article officiel du site GWT13
On appréciera la sécurité selon les 3 vulnérabilités essentielles ; validation des paramètres,
Cross Site Scripting et Injection SQL.
13
Voir Security for GWT Applications

Page 41
5.3.1. Validation des paramètres

Le framework GWT ne propose pas de fonctionnalités de validation des paramètres. Pour ce


faire, il faut faire appel à des bibliothèques tiers, comme EXT-GWT par exemple.

Le développeur devra implémenter le contrôle des paramètres entrés, par l’utilisation


d’expressions régulières par exemple. Cette validation est d’autant plus importante qu’elle
évite aussi les attaques par injections SQL.

5.3.2.Cross Site Scripting

Le cross-site scripting consiste à injecter du code malicieux JavaScript dans la page active
d’un site web. Ce code s’exécutera au niveau du navigateur, donc coté client. Plusieurs
« bonnes pratiques » sont préconisées par les développeurs de GWT afin de se prémunir de
ce type d’attaque :

- Eviter d’insérer du code JavaScript étranger à une génération par le framework.


- Ne pas coder de méthode modifiant la balise innerHTML dans les widgets GWT.
- Eviter d’intégrer des actions JavaScript non-sécurisées, grâce à JSNI. Notamment,
les modifications de balise innerHTML ou l’appel de la fonction eval.

De l’aveux même de Google, la sécurité est un point qui n’est pas encore totalement maîtrisé
par le framework. Des bibliothèques tierces, comme EXT-GWT qui offre une interface
Validator de validation de paramètres, permettent à minima d’implémenter une sécurité
de l’application.

6. Conclusion
Avec sa version 1.5, le framework GWT est maintenant proche de la maturité. La
communauté utilisant ce produit Open Source est forte et réactive.

Pour peu que quelques compétences AWT et/ou Swing soient présentes, le développement
d’application RIA avec GWT s’avère rapide. De plus, un outil graphique, GWT Designer
existe dans l’IDE Eclipse, par contre sa licence est exclusivement commerciale.

Grâce à l’optimisation du code JavaScript généré et à la production de scripts spécifiques


aux navigateurs14, les applications GWT se montrent performantes.

Par contre, la gestion de l’accessibilité (avec ARIA) ainsi que de la sécurité des applications
sont d’une implémentation incomplète. Pour la sécurité, de nouvelles fonctionnalités
devraient apparaître avec les prochaines versions du framework.
Il est aussi regrettable que les appels RPC s’appuient sur un protocole propriétaire, hors
spécifications internationales (OMG, W3C, OASIS, etc). Par contre, ce protocole optimisé et
utilisant une compression gzip se montre efficace.

14
La technique de « Deffered Binding » propre à GWT

Page 42
7. Table des Figures et Illustrations.

Figure 1 : Les composants de GWT...............................................................................4


Figure 2 : Les fenêtres du Hosted Web Browser ......................................................5
Figure 3 : Principes de GWT............................................................................................6
Figure 4 : classes GWT dans une architecture n-tier ..............................................8
Figure 5 Structure d'un projet GWT...........................................................................10
Figure 6 Principe de l'asynchronis m e .......................................................................14
Figure 7 Rôles des éléments RPC GWT.....................................................................15
Figure 8 Diagramme de classe s simplifié, mécanism e RPC..............................15
Figure 9 Diagramme de séquence mécanism e RPC GWT..................................19
Figure 10 Diagramme d'activité des appels RPC de GWT.................................20
Figure 11 Création du projet dans JDeveloper 10.1.3.x .....................................23
Figure 12 Nommage du projet .....................................................................................23
Figure 13 Choix de la version de Servlet .................................................................24
Figure 14 Profile Web du projet ..................................................................................24
Figure 15 Structure du projet dans JDeveloper 10.1.3.x ...................................25
Figure 16 Déclaration des bibliothèque s dans le classpath ..............................25
Figure 17 Création d'un profile d'exécution ...........................................................26
Figure 18 Paramètres du profile d'exécution .........................................................26
Figure 19 Le Serveur en mode "Hosted" ..................................................................27
Figure 20 Le navigateur en mode "Hosted" ............................................................27
Figure 21 Choix du type de déploiem ent .................................................................33
Figure 22 Spécification du contexte de déploiem ent ..........................................34
Figure 23 Choix des contributeurs Web ...................................................................34
Figure 24 Choix des classe s contributrices .............................................................35
Figure 25 Choix des bibliothèque s néces saires ....................................................35
Figure 26 Contenu du fichier war d'une application GWT................................36
Figure 27 Exemple de résultat en mode déployé ..................................................36
Figure 28 Exemple de texte statique par défaut ...................................................39
Figure 29 Exemple de texte statique "localisé" Fr................................................40
Figure 30 Exemple de messages paramétrés par défaut ....................................41
Figure 31 Exemple de messages paramétrés "localisé" Fr................................41

Page 43
8. Glossaire

ARIA : Accessibility for Rich Internet Application....................................................... 37

AST : Abstract Syntax Tree..........................................................................................7

AWT : Abstract Window Toolkit..................................................................................13

CSS : Cascade Style Sheet......................................................................................... 3

DTO : Data Transfert Object...................................................................................... 15

JRE : Java Runtime Environment................................................................................ 3

JSNI : JavaScript Native Interface............................................................................. 42

REST : Representational state transfert...................................................................... 8

RIA : Rich Internet Application..................................................................................... 4

RPC : Remote Procedure Call..................................................................................... 3

SOAP : Simple Object Access Protocol....................................................................... 8

URI : Uniform Resource Identifier.............................................................................. 31

Page 44