Introduction à GWT

1. Introduction

GWT ou Google Web Toolkit est un framework permettant de créer des applications Web hautes performances en Java .

Dans ce didacticiel, nous allons nous concentrer et couvrir certaines de ses capacités et fonctionnalités clés.

2. SDK GWT

Le SDK contient les bibliothèques d'API Java, un compilateur et un serveur de développement.

2.1. API Java

L'API GWT a des classes pour créer des interfaces utilisateur, passer des appels au serveur, internationaliser, effectuer des tests unitaires. Pour en savoir plus, consultez la documentation java ici.

2.2. Compilateur

En termes simples, le compilateur GWT est un traducteur source du code Java vers le Javascript . Le résultat de la compilation est une application Javascript.

La logique de son travail comprend la suppression des classes, des méthodes et des champs inutilisés du code et le raccourcissement des noms Javascript.

En raison de cet avantage, nous n'avons plus besoin d'inclure les bibliothèques Ajax dans notre projet Javascript. Bien sûr, il est également possible de définir des indices lors de la compilation du code.

Voici quelques paramètres utiles de GWTCompiler :

  • -logLevel - pour définir l'un des niveaux de journalisation ERROR, WARN, INFO, TRACE, DEBUG, SPAM, ALL
  • -workdir - répertoire de travail du compilateur
  • -gen - le répertoire pour écrire les fichiers générés
  • -out - le répertoire des fichiers de sortie
  • -optimize - Définit le niveau d'optimisation du compilateur de 0 à 9
  • -style - le style de sortie du script OBF, PRETTY ou DETAILED
  • -module [s] - le nom des modules à compiler

3. Configuration

Le dernier SDK est disponible sur la page de téléchargement. Le reste de la configuration est disponible sur la page de démarrage.

3.1. Maven

Pour configurer le projet avec Maven, nous devons ajouter les dépendances suivantes à pom.xml :

 com.google.gwt gwt-servlet runtime   com.google.gwt gwt-user provided   com.google.gwt gwt-dev provided 

La bibliothèque gwt-servlet prend en charge les composants côté serveur pour appeler un point de terminaison GWT-RPC. gwt-user contient l'API Java que nous utiliserons pour créer notre application Web . gwt-dev a le code pour le compilateur, le déploiement ou l'hébergement de l'application.

Pour nous assurer que toutes les dépendances utilisent la même version, nous devons inclure la dépendance GWT parente:

 com.google.gwt gwt 2.8.2 pom import 

Tous les artefacts sont disponibles au téléchargement sur Maven Central.

4. Application

Construisons une application Web simple. Il enverra un message au serveur et affichera la réponse.

En général, une application GWT se compose du serveur et des parties client . Le côté client fait une requête HTTP pour se connecter au serveur. Pour rendre cela possible, GWT utilise l'appel de procédure à distance ou simplement le mécanisme RPC.

5. GWT et RPC

Revenons à notre application, voyons comment se fait la communication RPC. Pour cela, nous créons un service pour recevoir un message du serveur.

Créons d'abord une interface:

@RemoteServiceRelativePath("greet") public interface MessageService extends RemoteService { String sendMessage(String message) throws IllegalArgumentException; }

L' annotation @RemoteServiceRelativePath mappe le service à l' URL relative du module / message . MessageService doit s'étendre à partir de l' interface de marqueur RemoteService pour effectuer la communication RPC .

L'implémentation de MessageService est côté serveur:

public class MessageServiceImpl extends RemoteServiceServlet implements MessageService { public String sendMessage(String message) throws IllegalArgumentException { if (message == null) { throw new IllegalArgumentException("message is null"); } return "Hello, " + message + "!

Time received: " + LocalDateTime.now(); } }

Notre classe de serveur s'étend de la classe de servlet de base RemoteServiceServlet . Il désérialise automatiquement les demandes entrantes du client et sérialise les réponses sortantes du serveur .

Voyons maintenant comment nous l'utilisons du côté client. Le MessageService n'est qu'une version définitive de notre service .

Pour performer côté client, nous devons créer la version asynchrone de notre service:

public interface MessageServiceAsync { void sendMessage(String input, AsyncCallback callback) throws IllegalArgumentException; }

Ici, nous pouvons voir un argument supplémentaire dans la méthode getMessage () . Nous avons besoin d' async pour notifier l'interface utilisateur lorsque l'appel asynchrone est terminé . De cette façon, nous évitons de bloquer le thread d'interface utilisateur qui fonctionne.

6. Composants et leur cycle de vie

Le SDK propose des éléments d'interface utilisateur et des mises en page pour la conception des interfaces graphiques.

En général, tous les composants de l'interface utilisateur s'étendent de la classe Widget . Visuellement, nous avons les widgets d'élément que nous pouvons voir, cliquer ou déplacer sur l'écran:

  • widgets de composants - TextBox , TextArea , Button , RadioButton , CheckBox , etc.

et il existe des widgets de disposition ou de panneau qui composent et organisent l'écran:

  • widgets de panneau - HorizontalPanel , VerticalPanel , PopupPanel , TabPanel , etc.

Every time we add a widget or any other component to the code, GWT works hard to link the view element with the browser's DOM.

The constructor always initializes the root DOM element. When we attach a child widget to a parent component, it also causes binding at the DOM level. The entry point class contains the loading function which will be called first. This is where we define our widgets.

7. Entry Point

Let's have a close look at the main entry point of the application:

public class Google_web_toolkit implements EntryPoint { private MessageServiceAsync messageServiceAsync = GWT.create(MessageService.class); public void onModuleLoad() { Button sendButton = new Button("Submit"); TextBox nameField = new TextBox(); nameField.setText("Hi there"); sendButton.addStyleName("sendButton"); RootPanel.get("nameFieldContainer").add(nameField); RootPanel.get("sendButtonContainer").add(sendButton); } }

Every UI class implements the com.google.gwt.core.client.EntryPoint interface to mark it as a main entry for the module. It connects to the corresponding HTML document, where the java code executes.

We can define GWT UI components and assign then to HTML tags with the same given ID. Entry point class overrides the entry point onModuleLoad() method, which is called automatically when loading the module.

Here we create the UI components, register event handlers, modify the browser DOM.

Now, let's see how we create our remote server instance. For that purpose, we use GWT.create(MessageService.class) static method.

It determines the requested type at compile-time. Seeing this method, GWT compiler generates many versions of code at compile time, only one of which needs to be loaded by a particular client during bootstrapping at runtime. This feature is widely used in RPC calls.

Here we also define the Button and TextBox widgets. To add attach them into the DOM tree we use the RootPanel class. It is the root panel and returns a singleton value to bind the widget elements:

RootPanel.get("sendButtonContainer").add(sendButton);

First, it gets the root container marked with sendButtonContainer id. After we attach the sendButton to the container.

8. HTML

Inside of the /webapp folder, we have Google_web_toolkit.html file.

We can mark the tag elements with the specific ids so the framework can bind them into Java objects:


    
Please enter your message:

The tags with nameFieldContainer and sendButtonContainer ids will be mapped to the Button and TextBox components.

9. Main Module Descriptor

Let's have a look at the typical configuration of the Google_web_toolkit.gwt.xml main module descriptor file:

We make core GWT stuff accessible by including the com.google.gwt.user.User interface. Also, we can choose a default style sheet for our application. In this case, it is *.clean.Clean.

The other available styling options are *.dark.Dark, *.standard.Standard, *.chrome.Chrome. The com.baeldung.client.Google_web_toolkit is also marked here with the tag.

10. Adding Event Handlers

To manage the mouse or keyboard typing events, GWT will use some handlers. They all extend from EventHandler interface and have a method with the event type argument.

In our example, we register the mouse click event handler.

This will fire the onClick() method every time thebutton is pushed:

closeButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { vPanel.hide(); sendButton.setEnabled(true); sendButton.setFocus(true); } });

Here we can modify the widget state and behavior. In our example, we hide the vPanel and enable the sendButton.

The other way is to define an inner class and implement the necessary interfaces:

class MyHandler implements ClickHandler, KeyUpHandler { public void onClick(ClickEvent event) { // send message to the server } public void onKeyUp(KeyUpEvent event) { if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) { // send message to the server } } }

In addition to ClickHandler, we also include here the KeyUpHandler interface to catch the keypress events. Here, inside of onKeyUp() method we can use the KeyUpEvent to check if the user pressed the Enter key.

And here how we use the MyHandler class to register both event handlers:

MyHandler handler = new MyHandler(); sendButton.addClickHandler(handler); nameField.addKeyUpHandler(handler);

11. Calling the Server

Now, we're ready to send the message to the server. We'll perform a remote procedure call with asynchronous sendMessage() method.

The second parameter of the method is AsyncCallback interface, where the String is the return type of the corresponding synchronous method:

messageServiceAsync.sendMessage(textToServer, new AsyncCallback() { public void onFailure(Throwable caught) { serverResponseLabel.addStyleName("serverResponseLabelError"); serverResponseLabel.setHTML("server error occurred"); closeButton.setFocus(true); } public void onSuccess(String result) { serverResponseLabel.setHTML(result); vPanel.setVisible(true); } });

As we can see, the receiver implementsonSuccess(String result)and onFailure(Throwable)method for each response type.

Depending on response result, we either set an error message “server error occurred” or display the result value in the container.

12. CSS Styling

When creating the project with the eclipse plugin, it will automatically generate the Google_web_toolkit.css file under the /webapp directory and link it to the main HTML file.

Bien sûr, nous pouvons définir des styles personnalisés pour les composants d'interface utilisateur spécifiques par programme:

sendButton.addStyleName("sendButton");

Ici, nous attribuons un style CSS avec le nom de classe sendButton à notre composant sendButton :

.sendButton { display: block; font-size: 16pt; }

13. Résultat

En conséquence, nous avons cette application Web simple:

Ici, nous soumettons un message «Bonjour» au serveur et imprimons le «Bonjour, Bonjour!» réponse à l'écran.

14. Conclusion

Dans cet article rapide, nous avons découvert les bases de GWT Framework . Ensuite, nous avons discuté de l'architecture, du cycle de vie, des capacités et des différents composants de son SDK.

En conséquence, nous avons appris à créer une application Web simple.

Et, comme toujours, le code source complet du didacticiel est disponible à l'adresse over sur GitHub.