Introducción a GWT

1. Introducción

GWT o Google Web Toolkit es un marco para crear aplicaciones web de alto rendimiento en Java .

En este tutorial, nos centraremos y cubriremos algunas de sus capacidades y funcionalidades clave.

2. SDK de GWT

El SDK contiene las bibliotecas API de Java, un compilador y un servidor de desarrollo.

2.1. API de Java

La API de GWT tiene clases para crear interfaces de usuario, realizar llamadas al servidor, internacionalizar y realizar pruebas unitarias. Para obtener más información, consulte la documentación de Java aquí.

2.2. Compilador

En pocas palabras, el compilador GWT es un traductor de código fuente de Java a Javascript . El resultado de la compilación es una aplicación Javascript.

La lógica de su trabajo incluye recortar las clases, métodos y campos no utilizados del código y acortar los nombres de Javascript.

Debido a esta ventaja, ya no necesitamos incluir bibliotecas Ajax en nuestro proyecto Javascript. Por supuesto, también es posible establecer pistas mientras se compila el código.

Aquí algunos parámetros útiles de GWTCompiler :

  • -logLevel - para establecer uno de los niveles de registro ERROR, WARN, INFO, TRACE, DEBUG, SPAM, ALL
  • -workdir - directorio de trabajo del compilador
  • -gen - el directorio para escribir los archivos generados
  • -out - el directorio de archivos de salida
  • -optimize : establece el nivel de optimización del compilador de 0 a 9
  • -style : el estilo de salida del script OBF, PRETTY o DETAILED
  • -module [s] : el nombre de los módulos para compilar

3. Configuración

El último SDK está disponible en la página de descarga. El resto de la configuración está disponible en la página de inicio.

3.1. Maven

Para configurar el proyecto con Maven, necesitamos agregar las siguientes dependencias a pom.xml :

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

La biblioteca gwt-servlet admite los componentes del lado del servidor para invocar un punto final GWT-RPC. gwt-user contiene la API de Java que usaremos para construir nuestra aplicación web . gwt-dev tiene el código para el compilador, implementación o alojamiento de la aplicación.

Para asegurarnos de que todas las dependencias usen la misma versión, necesitamos incluir la dependencia principal de GWT:

 com.google.gwt gwt 2.8.2 pom import 

Todos los artefactos están disponibles para su descarga en Maven Central.

4. Aplicación

Construyamos una aplicación web sencilla. Enviará un mensaje al servidor y mostrará la respuesta.

En general, una aplicación GWT consta del servidor y del cliente . El lado del cliente realiza una solicitud HTTP para conectarse con el servidor. Para hacerlo posible, GWT utiliza la llamada a procedimiento remoto o simplemente el mecanismo RPC.

5. GWT y RPC

Volviendo a nuestra aplicación, veamos cómo se realiza la comunicación RPC. Para ello, creamos un servicio para recibir un mensaje del servidor.

Primero creemos una interfaz:

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

La anotación @RemoteServiceRelativePath asigna el servicio a la URL relativa del módulo / mensaje . MessageService debe extenderse desde la interfaz de marcador RemoteService para realizar la comunicación RPC .

La implementación de MessageService está en el lado del servidor:

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

Nuestra clase de servidor se extiende desde la clase de servlet base RemoteServiceServlet . Deserializará automáticamente las solicitudes entrantes del cliente y serializará las respuestas salientes del servidor .

Ahora veamos cómo lo usamos desde el lado del cliente. El MessageService es sólo una versión definitiva de nuestro servicio .

Para actuar en el lado del cliente, necesitamos crear la versión asincrónica de nuestro servicio:

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

Aquí podemos ver un argumento adicional en el método getMessage () . Necesitamos async para notificar a la interfaz de usuario cuando se completa la llamada asincrónica . De esta manera evitamos bloquear el hilo de la interfaz de usuario en funcionamiento.

6. Componentes y su ciclo de vida

El SDK ofrece algunos elementos y diseños de la interfaz de usuario para diseñar las interfaces gráficas.

En general, todos los componentes de la interfaz de usuario se extienden desde la clase Widget . Visualmente tenemos los widgets de elementos que podemos ver, hacer clic o mover en la pantalla:

  • widgets de componentes : TextBox , TextArea , Button , RadioButton , CheckBox , etc.

y hay widgets de diseño o panel que componen y organizan la pantalla:

  • widgets de panel : 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.

Por supuesto, podemos definir estilos personalizados para los componentes específicos de la interfaz de usuario mediante programación:

sendButton.addStyleName("sendButton");

Aquí asignamos un estilo CSS con el nombre de clase sendButton a nuestro componente sendButton :

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

13. Resultado

Como resultado, tenemos esta sencilla aplicación web:

Aquí enviamos un mensaje de "Hola" al servidor e imprimimos el mensaje "¡Hola, hola!" respuesta en la pantalla.

14. Conclusión

En este artículo rápido, aprendimos sobre los conceptos básicos de GWT Framework . Luego, discutimos la arquitectura, el ciclo de vida, las capacidades y los diferentes componentes de su SDK.

Como resultado, aprendimos a crear una aplicación web sencilla.

Y, como siempre, el código fuente completo del tutorial está disponible en GitHub.