Въведение в GWT

1. Въведение

GWT или Google Web Toolkit е рамка за изграждане на високопроизводителни уеб приложения в Java .

В този урок ще се съсредоточим върху и ще разгледаме някои от ключовите му възможности и функционалност.

2. GWT SDK

SDK съдържа Java API библиотеки, компилатор и сървър за разработка.

2.1. API на Java

GWT API има класове за изграждане на потребителски интерфейси, извършване на сървърни разговори, интернационализация, извършване на модулни тестове. За да научите повече, проверете документацията за java тук.

2.2. Съставител

Най-просто казано, GWT компилаторът е преводач на източник от Java код в Javascript . Резултатът от компилацията е приложение на Javascript.

Логиката на работата му включва изрязване на неизползвани класове, методи, полета от кода и съкращаване на имената на Javascript.

Поради това предимство вече не е необходимо да включваме библиотеки на Ajax в нашия проект на Javascript. Разбира се, възможно е също да задавате подсказки, докато компилирате кода.

Ето някои полезни параметри на GWTCompiler :

  • -logLevel - за да зададете едно от нивата на ГРЕШКА, ПРЕДУПРЕЖДЕНИЕ, ИНФОРМАЦИЯ, ПРОСЛЕДЯВАНЕ, ОТЛАГАНЕ, СПАМ, ВСИЧКИ
  • -workdir - работната директория на компилатора
  • -gen - директорията за писане на генерираните файлове
  • -out - директорията на изходните файлове
  • -optimize - Задава нивото на оптимизация на компилатора от 0 до 9
  • -style - стил на извеждане на скрипта OBF, PRETTY или ПОДРОБНО
  • -module [s] - името на модулите за компилация

3. Настройка

Най-новият SDK е достъпен на страницата за изтегляне. Останалата част от настройката е достъпна на началната страница.

3.1. Мейвън

За да настроим проекта с Maven, трябва да добавим следните зависимости към pom.xml :

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

Библиотеката gwt-servlet поддържа сървърните компоненти за извикване на GWT-RPC крайна точка. gwt-user съдържа Java API, който ще използваме за изграждане на нашето уеб приложение . gwt-dev има код за компилатор, внедряване или хостинг на приложението.

За да сме сигурни, че всички зависимости използват една и съща версия, трябва да включим родителската GWT зависимост:

 com.google.gwt gwt 2.8.2 pom import 

Всички артефакти са достъпни за изтегляне от Maven Central.

4. Приложение

Нека да изградим просто уеб приложение. Той ще изпрати съобщение до сървъра и ще покаже отговора.

Като цяло приложението GWT се състои от сървърната и клиентската части . Клиентската страна прави HTTP заявка за свързване със сървъра. За да стане възможно, GWT използва Remote Procedure Call или просто RPC механизъм.

5. GWT и RPC

Връщайки се към нашето приложение, нека видим как се осъществява RPC комуникацията. За тази цел създаваме услуга за получаване на съобщение от сървъра.

Нека първо създадем интерфейс:

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

В @RemoteServiceRelativePath анотацията карти услугата на модула / съобщение относителен URL адрес. MessageService трябва да се простира от интерфейса на маркера RemoteService за извършване на RPC комуникация .

Изпълнението на MessageService е от страна на сървъра:

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

Нашият клас сървъри се простира от базовия клас сървлети RemoteServiceServlet . Той автоматично ще десериализира входящите заявки от клиента и ще сериализира изходящите отговори от сървъра .

Сега нека видим как го използваме от страна на клиента. В MessageService е само на окончателен вариант на нашата услуга .

За да работим от страна на клиента, трябва да създадем асинхронната версия на нашата услуга:

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

Тук можем да видим допълнителен аргумент в метода getMessage () . Имаме нужда от асинхронизация, за да уведомим потребителския интерфейс, когато асинхронното повикване завърши . По този начин предотвратяваме блокирането на работещата нишка на потребителския интерфейс.

6. Компоненти и техният жизнен цикъл

SDK предлага някои елементи и оформления на потребителския интерфейс за проектиране на графичните интерфейси.

Като цяло, всички компоненти на потребителския интерфейс се простират от класа Widget . Визуално разполагаме с приспособления за елементи, които можем да видим, щракнем или преместим на екрана:

  • приспособления за компоненти - TextBox , TextArea , Button , RadioButton , CheckBox и др ...

и има джаджи за оформление или панел, които съставят и организират екрана:

  • приспособления за панел - HorizontalPanel , VerticalPanel , PopupPanel , TabPanel и др ...

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.

Разбира се, можем програмно да дефинираме персонализирани стилове за конкретните компоненти на потребителския интерфейс:

sendButton.addStyleName("sendButton");

Тук ние присвояваме CSS стил с името на класа sendButton на нашия компонент sendButton :

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

13. Резултат

В резултат на това имаме това просто уеб приложение:

Тук изпращаме съобщение „Здравей там” на сървъра и отпечатваме „Здравей, здравей!” отговор на екрана.

14. Заключение

В тази кратка статия научихме за основите на GWT Framework . След това обсъдихме архитектурата, жизнения цикъл, възможностите и различните компоненти на Неговия SDK.

В резултат научихме как да създадем просто уеб приложение.

И както винаги, пълният изходен код на урока е достъпен в GitHub.