Mon premier projet GWT
Date de publication : 29/11/2006
Par
Moritan
Cet article en plusieurs parties est une présentation du framework "Google Web ToolKit".
- Présentation générale de la solution GWT
- Mon premier projet GWT (cet article)
- Comparaison avec SWING et JSP (à venir)
I. Introduction
I-A. Remerciements
I-B. Présentation
II. Mise en place de l'environnement
II-A. Environnement de développement
II-B. Environnement de production
III. Bonjour le monde
IV. On complique un peu
IV-A. Un peu de nettoyage
IV-B. Entrypoint
IV-C. Création des éléments graphiques
IV-C-1. Les Panels
IV-C-2. Les éléments graphiques
IV-D. Utilisation des styles css
V. Activation du filtre
VI. Dialogue avec le serveur
VI-A. Mise en place d'un service
VI-B. Exploitation du service
VII. Déploiement sur Tomcat
VIII. Conclusion
IX. Sources
I. Introduction
I-A. Remerciements
Merci à
Ricky81 pour sa relecture attentive.
I-B. Présentation
Au cours de cet article, nous verrons comment utiliser et intégrer le framework GWT avec Eclipse.
La présentation se fera par la réalisation d'une application permettant la consultation et le filtre d'une liste de contacts.
Les exemples de cet article se feront sous Windows, mais devraient s'adapter à un autre environnement sans trop de difficultés.
II. Mise en place de l'environnement
II-A. Environnement de développement
Pour commencer, il faut créer le répertoire de base du projet.
| Création du répertoire |
mkdir demoGWT |
On se place dans ce répertoire pour travailler.
Création des fichiers projet Eclipse
projectCreator -eclipse demoGWT |
Created directory D:\gwt-windows-1.1.10\demoGWT\test
Created file D:\gwt-windows-1.1.10\demoGWT\.project
Created file D:\gwt-windows-1.1.10\demoGWT\.classpath |
Création de l'arborescence applicative
applicationCreator -eclipse demoGWT com.developpez.exemple.gwt.client.MonApplication |
Created directory D:\gwt-windows-1.1.10\demoGWT\src
Created directory D:\gwt-windows-1.1.10\src\demoGWT\com\developpez\exemple\gwt
Created directory D:\gwt-windows-1.1.10\src\demoGWT\src\com\developpez\exemple\gwt\client
Created directory D:\gwt-windows-1.1.10\src\demoGWT\src\com\developpez\exemple\gwt\public
Created file D:\gwt-windows-1.1.10\src\demoGWT\com\developpez\exemple\gwt\MonApplication.gwt.xml
Created file D:\gwt-windows-1.1.10\src\demoGWT\com\developpez\exemple\gwt\public\MonApplication.html
Created file D:\gwt-windows-1.1.10\src\demoGWT\com\developpez\exemple\gwt\client\MonApplication.java
Created file D:\gwt-windows-1.1.10\demoGWT\MonApplication.launch
Created file D:\gwt-windows-1.1.10\demoGWT\MonApplication-shell.cmd
Created file D:\gwt-windows-1.1.10\demoGWT\MonApplication-compile.cmd |
Maintenant que la structure applicative est créée, on pourrait simplement utiliser un éditeur de texte.
Mais utilisons Eclipse, pourquoi se priver de fonctionnalités avancées?
Pour cela, il suffit d'ouvrir Eclipse.
Dans le menu
file, choisir
import
Choisir
Existing Projects into workspace
Cibler le répertoire demoGWT et importer.
On obtient
II-B. Environnement de production
En production, on aura évidemment besoin d'un serveur applicatif ou d conteneur web tel Tomcat.
Pour l'installation et le fonctionnement de Tomcat, je vous laisse consulter
ce tutoriel.
Ensuite, il vous suffit de déployer votre application comme n'importe quelle autre application Java.
III. Bonjour le monde
Comme tout bon tutoriel, nous allons commencer par un "Hello World !".
Pour cela, lancer le script MonApplication-shell.cmd. Un navigateur va se lancer.
Il vous permettra de voir le rendu de votre application en cours de développement.
La page que vous voyez apparaître devrait ressembler à
celle-ci.
Félicitation, vous venez de réussir votre premier "HelloWorld" avec le framework GWT.
IV. On complique un peu
IV-A. Un peu de nettoyage
Le ménage commence par la page HTML qui sert de support à notre application.
On supprime le surplus du HelloWorld pour ne conserver que le titre de la page et les balises propres à GWT.
On obtient alors la page suivante :
| MonApplication.html |
<head>
<title>MonApplication GWT</title>
<meta name='gwt:module' content='com.developpez.exemple.gwt.MonApplication'>
</head>
<body>
<script language="javascript" src="gwt.js"></script>
<iframe id="__gwt_historyFrame" style="width:0;height:0;border:0"></iframe>
</body>
</html> |
IV-B. Entrypoint
Lorsque l'on développe une application AWT/SWING, on utilise une classe avec une méthode main pour lancer notre application.
Etant donné que les classes Java que nous allons écrire seront converties en code Javascript, l'utilisation d'une méthode main est impossible.
Dans notre cas, notre classe de lancement sera la page html de notre application et notre méthode main la balise meta.
| Déclaration du module |
<meta name='gwt:module' content='com.developpez.exemple.gwt.MonApplication'> |
L'attribut content de la balise permet de faire le lien vers le fichier de configuration de notre module GWT.
| MonApplication.gwt.xml |
<module>
<inherits name='com.google.gwt.user.User'/>
<entry-point class='com.developpez.exemple.gwt.client.MonApplication'/>
</module> |
La balise entry-point permet de spécifier quelle sera la classe principale de notre application.
Cette classe doit implémenter l'interface Entrypoint.
Il est intéressant aussi d'implémenter l'interface WindowResizeListener.
Cette interface permet de recevoir les informations liées à la taille de la fenêtre du navigateur et donc de redimensionner notre application proportionnellement à celle-ci.
Le code de la classe devrait ressembler à ça:
| MonApplication.java |
package com.developpez.exemple.gwt.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.WindowResizeListener;
public class MonApplication implements EntryPoint , WindowResizeListener {
public void onModuleLoad() {
Window.addWindowResizeListener(this);
Window.enableScrolling(false);
Window.setMargin("10px");
}
public void onWindowResized(int width, int height) {
}
} |
On obtient donc une application GWT pleinement fonctionnelle, mais qui ne fait rien.
IV-C. Création des éléments graphiques
Les classes des éléments graphiques de GWT reprennent les noms et comportements que l'on a l'habitude de manipuler quand on réalise une application AWT/SWING.
Avec GWT, nous manipulerons donc des Panels et autres Label et TextBox.
IV-C-1. Les Panels
Les panels se déclinent en plusieurs classes qui ont chacune un comportement spécifique.
Dans cette mise en application nous utiliserons les panels suivants :
- DockPanel
- HorizontalPanel
- VerticalPanel
Le DockPanel servira de base d'accueil pour notre application.
Il contiendra dans sa partie Nord un VerticalPanel et dans sa partie Centre un HorizontalPanel.
Le verticalPanel contiendra les champs de recherche et le VerticalPanel présentera les résultats.
On commence par ajouter le DockPanel à l'application. Ce qui nous donne pour la classe MonApplication.java le code suivant :
| MonApplication.java |
package com.developpez.exemple.gwt.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.WindowResizeListener;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.RootPanel;
public class MonApplication implements EntryPoint , WindowResizeListener {
private DockPanel outer = new DockPanel();
public void onModuleLoad() {
outer.setWidth("100%");
outer.setHeight("100%");
Window.addWindowResizeListener(this);
Window.enableScrolling(false);
Window.setMargin("10px");
RootPanel.get().add(outer);
}
public void onWindowResized(int width, int height) {
}
} |
Nous allons créer deux panels, RechechePanel et ContactsPanel qui étendent respectivement HorizontalPanel et VerticalPanel.
Le fait de ne pas utiliser directement les panels génériques nous permet d'alléger la classe MonApplication et surtout nous permettra d'avoir un code lisible.
Pour la classe ContactsPanel

et pour la classe RecherchePanel

Il ne nous reste plus qu'à les insérer dans le DockPanel.
| MonApplication.java |
package com.developpez.exemple.gwt.client;
import com.developpez.exemple.gwt.client.panel.ContactsPanel;
import com.developpez.exemple.gwt.client.panel.RecherchePanel;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.WindowResizeListener;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.RootPanel;
public class MonApplication implements EntryPoint , WindowResizeListener {
private DockPanel outer = new DockPanel();
public void onModuleLoad() {
HorizontalPanel recherchePanel =new RecherchePanel();
VerticalPanel contactsPanel =new ContactsPanel();
outer.setWidth("100%");
outer.setHeight("100%");
Window.addWindowResizeListener(this);
Window.enableScrolling(false);
Window.setMargin("10px");
outer.add(recherchePanel, DockPanel.NORTH);
outer.add(contactsPanel, DockPanel.CENTER);
RootPanel.get().add(outer);
}
public void onWindowResized(int width, int height) {
}
} |
IV-C-2. Les éléments graphiques
Maintenant que la structure d'accueil de notre application est prête, nous allons pouvoir mettre un peu de contenu.
En plus des composants graphiques de base, nous utiliserons aussi la classe Composite.
La classe Composite permet d'envelopper un ou plusieurs autres éléments graphiques. Ce groupe de composant agit alors comme un seul et même élément.
Nous allons commencer par créer une classe Texte que héritera de Composite. Cette classe nous permettra de gérer les zones de saisie utilisateur.
Elle gèrera le libellé et la zone de saisie. on utilisera la classe Label pour le libélé et la classe TextBox pour la zone de saisie.

| Texte.java |
package com.developpez.exemple.gwt.client.panel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
public class Texte extends Composite {
private Label label = new Label();
private TextBox textBox = new TextBox();
public Texte() {
HorizontalPanel panel =new HorizontalPanel();
panel.add(label);
panel.add(textBox);
initWidget(panel);
}
public void setLabel(String texte){
label.setText(texte+" : ");
}
public void setTexte(String texte){
textBox.setText(texte);
}
public String getTexte(){
return textBox.getText();
}
} |
Ensuite, il suffit d'ajouter ce composant à notre RecherchePanel, pour avoir nos zones de filtre.
| RecherchePanel.java |
package com.developpez.exemple.gwt.client.panel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HorizontalPanel;
public class RecherchePanel extends HorizontalPanel {
public RecherchePanel(){
this.setTitle("Recherche");
this.setWidth("100%");
Texte tb = new Texte();
tb.setLabel("Nom");
add(tb);
Texte tb2 = new Texte();
tb2.setLabel("Prénom");
add(tb2);
}
} |
Avant de compléter notre application, nous allons créer une classe utilitaire Contact.
Ce sera la représentation objet des différentes personnes de notre application.
Afin d'avoir quelques éléments graphiques pour la démonstration, on rajoute une méthode getAllContacts() sur la classe.
Cette méthode va nous renvoyer un tableau de contacts à afficher, le temps que l'on implémente le service d'accès à une base de données.
A terme cette méthode disparaîtra.
Les différents contacts connus seront affichés sous forme de tableau.
Nous utiliserons pour cela la classe FlexTable. Le contenu d'un tableau se positionne par ses coordonées.
Nous utiliserons la première ligne pour afficher les entêtes de tableau.
| ContactsPanel.java |
package com.developpez.exemple.gwt.client.panel;
import com.developpez.exemple.gwt.client.util.Contact;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.VerticalPanel;
public class ContactsPanel extends VerticalPanel {
private FlexTable t = new FlexTable();
public ContactsPanel() {
t.setTitle("Contacts");
t.setText(0, 0,"Nom");
t.setText(0, 1,"Prénom");
t.setText(0, 2,"Email");
t.setText(0, 3,"Tel");
t.setWidth("100%");
t.setCellSpacing(2);
for (int i = 0; i < Contact.getAllContacts().length; ++i)
addContact(Contact.getAllContacts()[i],i+1);
this.add(t);
this.setWidth("100%");
}
private void addContact(Contact contact,int i) {
t.setText(i, 0,contact.getNom());
t.setText(i, 1,contact.getPrenom());
t.setText(i, 2,contact.getEmail());
t.setText(i, 3,contact.getTel());
}
} |
Une fois compilée, notre application donne
ça.
IV-D. Utilisation des styles css
Maintenant que l'on a tous nos éléments, on va leur donner un aspect un peu plus convivial.
Pour cela, on va utiliser un fichier css.
On ajoute donc un fichier MonApplication.css au répertoire public de notre arborescence.
Afin que ces styles soient disponibles dans les classes GWT, il faut éditer le fichier MonApplication.gwt.xml, et déclarer le fichier css dans notre module.
Pour cela il suffit d'ajouter la ligne suivante dans la déclaration du module.
| MonApplication.gwt.xml |
<stylesheet src='MonApplication.css'/> |
Les différentes classes graphiques du framework GWT héritent toutes de la classe UIObject.
Cette classe nous donne la méthode setStyleName sur tous nos composants et nous permet donc d'assigner un style précis à chacun de nos objets.
Par exemple, pour changer le style du RecherchePanel, il nous suffit d'ajouter le code suivant à son constructeur pour en modifier l'apparence.
this.setStyleName("gwt-RecherchePanel"); |
Bien évidemment le style
gwt-RecherchePanel a été défini dans le fichier css.
Par convention, les noms de style sont composés du nom du module tiret l'élément grahique auquel il s'applique.
En appliquant nos styles à nos différents éléments, on obtient
ça.
Mais bien sûr, nous n'avons encore aucun composant actif dans notre page.
V. Activation du filtre
Nous allons commencer à mettre un peu d'intelligence dans notre application. Pour cela, nous allons écouter les événements sur les zones de saisie et modifier le contenu du tableau en conséquence.
On va commencer par se donner des accesseurs à nos Panels en leur appliquant le pattern Singleton.
Puis on va rajouter les méthodes getNom et getPrenom sur le RecherchePanel et la méthode filtre sur le contactsPanel.
Les méthodes getNom et getPrenom retourneront les valeurs saisies tandis que filtre modifiera le contenu du tableau de résultats.
Ensuite, on va écouter les événements clavier qui surviennent dans nos zones de saisie en ajoutant le code suivant à notre classe Texte.
| Texte.java |
textBox.addKeyboardListener(new KeyboardListener() {
public void onKeyDown(Widget sender, char keyCode, int modifiers) {}
public void onKeyPress(Widget sender, char keyCode, int modifiers) {}
public void onKeyUp(Widget sender, char keyCode, int modifiers) {
ContactsPanel.instance.filtre();
}
}); |
On remplit la méthode filtre.
| ContactsPanel.java |
public void filtre(){
String nom = RecherchePanel.instance.getNom();
String prenom = RecherchePanel.instance.getPrenom();
for (int i = t.getRowCount()-1; i >0 ; i--) {
t.removeRow(1);
}
int next =1;
for (int i = 0; i < Contact.getAllContacts().length; ++i){
Contact contact =Contact.getAllContacts()[i];
if (contact.getNom().toUpperCase().startsWith(nom.toUpperCase())
&& contact.getPrenom().toUpperCase().startsWith(prenom.toUpperCase())) {
addContact(contact,next);
next++;
}
}
} |
Une fois nos classes modifiées, on obtient
ça.
VI. Dialogue avec le serveur
L'application semble fonctionnelle, mais la liste des contacts reste encore contenue dans la classe Contact, ce qui est peu satisfaisant.
Nous allons donc dans un premier temps créer un package server qui recevra les classes distantes et supprimer la méthode static getAllContact de la classe Contact.
VI-A. Mise en place d'un service
Le framework GWT dispose de sa propre solution de communication
entre le client et le serveur, basée sur le principe d'appel de procédure distante (RCP).
Le serveur et le client dialogue dialoguent en Asynchrone (vous savez le premier A de AJAX ).
Il faut donc deux flux de communication, le premier direct vers le serveur
pour émettre les requêtes, le second asynchrone pour recevoir les réponses du serveur.
Le flux ascendant est modélisé par une interface qui doit étendre l'interface RemoteService.
On définit dessus les différentes méthodes que l'on souhaite obtenir du serveur.
On va donc créer une interface ContactService.
Afin que le client puisse recevoir la réponse du serveur,
on va créer une seconde interface ContactServiceAsync.
Cette interface doit répondre à plusieurs critères :
- Le nom de l'interface doit être le même que celui pour le flux ascendant avec à la fin "Async".
- Toutes ses méthodes sont de type void.
- Le nombre et le nom de ses méthodes sont identiques à ceux pour le flux ascendant.
- Chacune de ses méthodes doit prendre les mêmes paramètres que pour le flux montant plus un paramètre supplémentaire de la classe AsyncCallback.
C'est au travers de l'objet AsyncCallback que le serveur retournera sa réponse au client.
Maintenant que nous avons nos flux de communication avec le serveur,
il nous faut ensuite créer une servlet sur le serveur capable de recevoir notre demande et d'y répondre.
Pour cela dans le package server, on va créer une classe ContactServiceImpl qui étendra RemoteServiceServlet et impémentera notre interface ContactService.
Hériter de la classe RemoteServiceServlet permet de faire abstraction de l'élaboration de l'objet AsyncCallback.
Le mécanisme RCP fonctionne comme un miroir, les méthodes appelées coté client seront exécutées coté serveur sur notre servlet.
C'est donc dans le corps des méthodes issues de l'implémentation de notre interface
que l'on placera le code que l'on souhaite exécuter sur le serveur.
Notre classe servlet elle aussi doit répondre à plusieurs critères :
- Le nom de la servlet doit être le même que celui pour le flux ascendant avec à la fin "Impl".
- La servlet doit implémenter RemoteServiceServlet.
- La servlet doit implémenter l'interface du service ascendant.
| ContactServiceImpl.java |
package com.developpez.exemple.gwt.server;
import com.developpez.exemple.gwt.client.ContactService;
import com.developpez.exemple.gwt.client.util.Contact;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
public class ContactServiceImpl extends RemoteServiceServlet implements
ContactService {
public Contact[] getAllContact() {
return ContactData.getAllContacts();
}
} |
La classe ContactData est une classe utilitaire chargée de fournir la liste des contacts.
La méthode d'obtention des contacts importe peu, jdbc, Hibernate, fichier XML, LDAP, libre à vous d'utiliser celle qu'il vous plait.
Dernière action pour finaliser la création de notre service, la déclaration dans le fichier MonApplication.gwt.xml.
Pour cela, il suffit d'ajouter la ligne suivante à la déclaration du module.
| MonApplication.gwt.xml |
<servlet path="/contactService" class="com.developpez.exemple.gwt.server.ContactServiceImpl"/> |
VI-B. Exploitation du service
Maintenant que le service est créé, nous allons pouvoir l'utiliser. On va l'appeler directement dans notre classe ContactsPanel.
On rajoute une méthode getAllContacts sur notre classe, qui après quelques modifications ressemble à ça :
| ContactsPanel.java |
package com.developpez.exemple.gwt.client.panel;
import com.developpez.exemple.gwt.client.ContactService;
import com.developpez.exemple.gwt.client.ContactServiceAsync;
import com.developpez.exemple.gwt.client.util.Contact;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.VerticalPanel;
public class ContactsPanel extends VerticalPanel {
private FlexTable t = new FlexTable();
private Contact[] contacts;
public static ContactsPanel instance;
public ContactsPanel() {
getAllContacts();
t.setTitle("Contacts");
t.setText(0, 0,"Nom");
t.setText(0, 1,"Prénom");
t.setText(0, 2,"Email");
t.setText(0, 3,"Tel");
t.setWidth("100%");
t.setCellSpacing(2);
for (int i = 0; i < 4; i++) {
t.getCellFormatter().addStyleName(0, i, "contact-ContactPanel");
}
this.add(t);
this.setWidth("100%");
instance=this;
}
private void addContact(Contact contact,int i) {
t.setText(i, 0,contact.getNom());
t.setText(i, 1,contact.getPrenom());
t.setText(i, 2,contact.getEmail());
t.setText(i, 3,contact.getTel());
for (int j = 0; j < 4; j++) {
if(i%2==0)
t.getCellFormatter().addStyleName(i, j, "contact-ContactPanel-line1");
else
t.getCellFormatter().addStyleName(i, j, "contact-ContactPanel-line2");
}
}
public void filtre(){
String nom = RecherchePanel.instance.getNom();
String prenom = RecherchePanel.instance.getPrenom();
for (int i = t.getRowCount()-1; i >0 ; i--) {
t.removeRow(1);
}
int next =1;
for (int i = 0; i < contacts.length; ++i){
Contact contact =contacts[i];
if (contact.getNom().toUpperCase().startsWith(nom.toUpperCase())
&& contact.getPrenom().toUpperCase().startsWith(prenom.toUpperCase())) {
addContact(contact,next);
next++;
}
}
}
private void getAllContacts(){
contacts = new Contact[0];
ContactServiceAsync svc =
(ContactServiceAsync) GWT.create(ContactService.class);
ServiceDefTarget endpoint = (ServiceDefTarget) svc;
String moduleRelativeURL = GWT.getModuleBaseURL() + "contactService";
endpoint.setServiceEntryPoint(moduleRelativeURL);
AsyncCallback callback = new AsyncCallback() {
public void onSuccess (Object result)
{
contacts = (Contact[]) result;
filtre();
}
public void onFailure (Throwable ex)
{
contacts = new Contact[0];
filtre();
}
};
svc.getAllContact(callback);
}
} |
Si on détaille un peu la méthode getAllContacts() :
| Déclaration du service que l'on souhaite appeler |
ContactServiceAsync svc = (ContactServiceAsync) GWT.create(ContactService.class); |
| On définit ou trouver le service, son url |
ServiceDefTarget endpoint = (ServiceDefTarget) svc;
String moduleRelativeURL = GWT.getModuleBaseURL() + "contactService";
endpoint.setServiceEntryPoint(moduleRelativeURL); |
| On définit le comportement de retour |
AsyncCallback callback = new AsyncCallback() {
public void onSuccess (Object result)
{
contacts = (Contact[]) result;
filtre();
}
public void onFailure (Throwable ex)
{
contacts = new Contact[0];
filtre();
}
}; |
J'ai utilisé une classe interne car le comportement voulu était très simple, mais dans un cadre plus complexe, il serait souhaitable d'utiliser une classe externe.
| on appelle le service |
svc.getAllContact(callback); |
Dans notre exemple la mise place et l'appel du service sont fait dans la même méthode car l'appel du service n'est fait qu'une seule fois au chargement de la page.
Néanmoins, on peut très bien placer notre service sur un slot et y faire ensuite appel en différente occasion.
Chaque appel à un service génère un aller retour serveur. Il faut donc prévoir les temps de latence possible.
De plus il est intéressant comme dans notre application, de stocker en cache côté client un certain nombre d'information, afin d'alléger le nombre de requète au serveur.
Typiquement dans notre exemple, il était inutile de faire un aller/retour serveur pour le filtre (à la volumétrie près).
Notre application est maintenant terminée et nous obtenons la liste des contacts d'un serveur distant.
VII. Déploiement sur Tomcat
La structure standard d'une application sous Tomcat est la suivante :
La structure de notre projet sous Eclipse est la suivante :
Pour déployer dans une arborescence tomcat il faut :
- Créer une webapp avec le nom de notre service.
- Copier le contenu du répertoire bin dans le repertoire classes de notre webapps.
- Placer le jar gwt-servlet.jar dans le répertoire lib de notre application ou dans le répertoire common/lib à la racine de tomcat.
- Copier le contenu du répertoire www à la racine de notre webapp.
 |
Dans notre exemple le répertoire www contient un sous répertoire com.developpez.exemple.gwt.MonApplication.
Lors d'un déploiement, il est possible de ne pas conserver ce sous répertoire en ne copiant que son contenu à la racine de la webapps.
Cela permet de simplifier l'adresse de notre application.
|
Enfin, il faut déclarer notre servlet. Il faut donc placer un fichier web.xml dans le répertoire WEB-INF.
| web.xml |
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>GWT</display-name>
<description>
GWT example
</description>
<servlet>
<servlet-name>ContactService</servlet-name>
<servlet-class>com.developpez.exemple.gwt.server.ContactServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ContactService</servlet-name>
<url-pattern>/contactService</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>MonApplication.html</welcome-file>
</welcome-file-list>
</web-app> |
VIII. Conclusion
Au cours de cet article, nous avons vu tout l'intérêt du framework GWT.
Nous avons réalisé une application web interactive, dialoguant avec un serveur, en faisant abstraction de tout autre language à part Java.
De plus le code généré est compatible avec la majorité des navigateurs.
Le framework GWT apporte au développement WEB tous les avantages du développement d'un client lourd, en permettant notamment la modélisation des classes gérant l'interface graphique.
IX. Sources
Fichiers sources de la première partie du tutoriel
ici ou
ici.
Fichiers sources du chapitre VI
ici ou
ici.


Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur.
La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.