Introduzione a GWT

1. Introduzione

GWT o Google Web Toolkit è un framework per la creazione di applicazioni web ad alte prestazioni in Java .

In questo tutorial, ci concentreremo su alcune delle sue capacità e funzionalità chiave.

2. GWT SDK

L'SDK contiene le librerie API Java, un compilatore e un server di sviluppo.

2.1. API Java

L'API GWT dispone di classi per la creazione di interfacce utente, l'esecuzione di chiamate al server, l'internazionalizzazione, l'esecuzione di unit test. Per saperne di più controlla la documentazione java qui.

2.2. Compilatore

In poche parole, il compilatore GWT è un traduttore sorgente dal codice Java al Javascript . Il risultato della compilazione è un'applicazione Javascript.

La logica del suo lavoro include il taglio di classi, metodi, campi inutilizzati dal codice e abbreviazione dei nomi Javascript.

A causa di questo vantaggio, non è più necessario includere le librerie Ajax nel nostro progetto Javascript. Ovviamente è anche possibile impostare suggerimenti durante la compilazione del codice.

Ecco alcuni utili parametri di GWTCompiler :

  • -logLevel - per impostare uno dei livelli di registrazione ERROR, WARN, INFO, TRACE, DEBUG, SPAM, ALL
  • -workdir - directory di lavoro del compilatore
  • -gen - la directory in cui scrivere i file generati
  • -out - la directory dei file di output
  • -optimize - Imposta il livello di ottimizzazione del compilatore da 0 a 9
  • -style - lo stile di output dello script OBF, PRETTY o DETAILED
  • -module [s] - il nome dei moduli da compilare

3. Configurazione

L'ultimo SDK è disponibile nella pagina di download. Il resto della configurazione è disponibile nella pagina iniziale.

3.1. Esperto di

Per impostare il progetto con Maven, dobbiamo aggiungere le seguenti dipendenze a pom.xml :

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

La libreria gwt-servlet supporta i componenti lato server per invocare un endpoint GWT-RPC. gwt-user contiene l'API Java che useremo per creare la nostra applicazione web . gwt-dev ha il codice per il compilatore, la distribuzione o l'hosting dell'applicazione.

Per assicurarci che tutte le dipendenze utilizzino la stessa versione, dobbiamo includere la dipendenza GWT principale:

 com.google.gwt gwt 2.8.2 pom import 

Tutti gli artefatti sono disponibili per il download su Maven Central.

4. Applicazione

Creiamo una semplice applicazione web. Invierà un messaggio al server e visualizzerà la risposta.

In generale, un'applicazione GWT è composta dal server e dalle parti client . Il lato client effettua una richiesta HTTP per connettersi al server. Per renderlo possibile, GWT utilizza Remote Procedure Call o semplicemente il meccanismo RPC.

5. GWT e RPC

Tornando alla nostra applicazione, vediamo come viene realizzata la comunicazione RPC. A tale scopo, creiamo un servizio per ricevere un messaggio dal server.

Creiamo prima un'interfaccia:

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

L' annotazione @RemoteServiceRelativePath mappa il servizio all'URL relativo del modulo / messaggio . MessageService dovrebbe estendersi dall'interfaccia del marker RemoteService per eseguire la comunicazione RPC .

L'implementazione di MessageService è lato server:

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(); } }

La nostra classe server si estende dalla classe servlet di base RemoteServiceServlet . Deserializzerà automaticamente le richieste in arrivo dal client e serializzerà le risposte in uscita dal server .

Ora vediamo come lo usiamo dal lato client. Il MessageService è solo una versione definitiva del nostro servizio .

Per eseguire sul lato client, dobbiamo creare la versione asincrona del nostro servizio:

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

Qui possiamo vedere un argomento extra nel metodo getMessage () . Abbiamo bisogno di asincrono per notificare all'interfaccia utente quando la chiamata asincrona è completa . In questo modo impediamo di bloccare il thread dell'interfaccia utente funzionante.

6. Componenti e loro ciclo di vita

L'SDK offre alcuni elementi dell'interfaccia utente e layout per la progettazione delle interfacce grafiche.

In generale, tutti i componenti dell'interfaccia utente si estendono dalla classe Widget . Visivamente abbiamo i widget degli elementi che possiamo vedere, fare clic o spostare sullo schermo:

  • widget del componente : TextBox , TextArea , Button , RadioButton , CheckBox , ecc ...

e ci sono widget di layout o pannello che compongono e organizzano lo schermo:

  • widget del pannello : HorizontalPanel , VerticalPanel , PopupPanel , TabPanel , ecc ...

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.

Naturalmente, possiamo definire stili personalizzati per i componenti dell'interfaccia utente specifici a livello di programmazione:

sendButton.addStyleName("sendButton");

Qui assegniamo uno stile CSS con il nome della classe sendButton al nostro componente sendButton :

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

13. Risultato

Di conseguenza, abbiamo questa semplice applicazione web:

Qui inviamo un messaggio "Hi there" al server e stampiamo il messaggio "Hello, Hi there!" risposta sullo schermo.

14. Conclusione

In questo rapido articolo, abbiamo appreso le basi di GWT Framework . Successivamente, abbiamo discusso dell'architettura, del ciclo di vita, delle capacità e dei diversi componenti del suo SDK.

Di conseguenza, abbiamo imparato a creare una semplice applicazione web.

E, come sempre, il codice sorgente completo del tutorial è disponibile su GitHub.