Введение в GWT

Введение в GWT

1. Вступление

GWT илиGoogle Web Toolkit is a framework for building high-performance web applications in Java.

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

2. GWT SDK

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

2.1. Java API

GWT API имеет классы для создания пользовательских интерфейсов, выполнения серверных вызовов, интернационализации, выполнения модульных тестов. Чтобы узнать больше, проверьте java-документациюhere.

2.2. составитель

Simply put, GWT compiler is a source translator from Java code into the Javascript. Результатом компиляции является приложение Javascript.

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

Благодаря этому преимуществу нам больше не нужно включать библиотеки Ajax в наш проект Javascript. Конечно, также можно задавать подсказки при компиляции кода.

Вот несколько полезных параметровGWTCompiler:

  • -logLevel - установить один из уровней логированияERROR, WARN, INFO, TRACE, DEBUG, SPAM, ALL

  • -workdir - рабочий каталог компилятора

  • -gen - каталог для записи сгенерированных файлов

  • -out - каталог выходных файлов

  • -optimize - устанавливает уровень оптимизации компилятора от 0 до 9

  • -style - стиль вывода скриптаOBF, PRETTY илиDETAILED

  • -module[s] - имя модулей для компиляции

3. Настроить

Последний SDK доступен на страницеdownload. Остальная часть настройки доступна на страницеgetting started.

3.1. специалист

Чтобы настроить проект с Maven, нам нужно добавить следующие зависимости вpom.xml:


    com.google.gwt
    gwt-servlet
    runtime


    com.google.gwt
    gwt-user
    provided


    com.google.gwt
    gwt-dev
    provided

The gwt-servlet library supports the server-side components for invoking a GWT-RPC endpoint. gwt-user contains the Java API which we’ll use to build our web application. gwt-dev содержит код для компилятора, развертывания или размещения приложения.

Чтобы убедиться, что все зависимости используют одну и ту же версию, нам нужно включить родительскую зависимость GWT:


    com.google.gwt
    gwt
    2.8.2
    pom
    import

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

4. заявка

Давайте создадим простое веб-приложение. Он отправит сообщение на сервер и отобразит ответ.

In general, a GWT application consists of the server and the client parts. Клиентская сторона отправляет HTTP-запрос на соединение с сервером. Чтобы сделать это возможным, GWT использует удаленный вызов процедур или просто механизм RPC.

5. GWT и RPC

Возвращаясь к нашему приложению, давайте посмотрим, как осуществляется связь RPC. Для этого мы создаем сервис для получения сообщения с сервера.

Давайте сначала создадим интерфейс:

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

The @RemoteServiceRelativePath annotation maps the service to the module’s /message relative URL. MessageService should extend from RemoteService marker interface to perform RPC communication.

Реализация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.It will automatically deserialize incoming requests from the client and serialize outgoing responses from the server.

Теперь посмотрим, как мы его используем на стороне клиента. The MessageService is only a definitive version of our service.

Чтобы выполнить на стороне клиента, нам нужно создать асинхронную версию нашего сервиса:

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

Здесь мы видим дополнительный аргумент в методеgetMessage(). We need async to notify the UI when the asynchronous call is complete. Таким образом мы предотвращаем блокировку рабочего потока пользовательского интерфейса.

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

SDK предлагает некоторые элементы пользовательского интерфейса и макеты для проектирования графических интерфейсов.

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

  • component widgets -TextBox,TextArea,Button,RadioButton,CheckBox и т. д.

и есть виджеты макета или панели, которые составляют и организуют экран:

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

Конструктор всегда инициализирует корневой элемент DOM. When we attach a child widget to a parent component, it also causes binding at the DOM level. Класс точки входа содержит функцию загрузки, которая будет вызываться первой. Здесь мы определяем наши виджеты.

7. Входная точка

Давайте внимательно посмотрим на основную точку входа в приложение:

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. Он подключается к соответствующему документу HTML, где выполняется код Java.

Мы можем определить компоненты пользовательского интерфейса GWT и назначить их затем тегам HTML с тем же заданным идентификатором. Entry point class overrides the entry point onModuleLoad() method, which is called automatically when loading the module.

Здесь мы создаем компоненты пользовательского интерфейса, регистрируем обработчики событий, модифицируем DOM браузера.

Теперь давайте посмотрим, как мы создаем экземпляр удаленного сервера. Для этого мы используем статический методGWT.create(MessageService.class).

Он определяет запрашиваемый тип во время компиляции. Увидев этот метод,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. Эта функция широко используется в вызовах RPC.

Здесь мы также определяем виджетыButton иTextBox. To add attach them into the DOM tree we use the RootPanel class. Это корневая панель, которая возвращает одноэлементное значение для привязки элементов виджета:

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

Сначала он получает корневой контейнер, помеченный идентификаторомsendButtonContainer. После прикрепляемsendButton to к контейнеру.

8. HTML

Внутри папки/webapp находится файлGoogle_web_toolkit.html.

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


    

Sample GWT Application

Please enter your message:

Теги<td> с идентификаторамиnameFieldContainer иsendButtonContainer будут сопоставлены с компонентамиButton иTextBox.

9. Дескриптор основного модуля

Давайте посмотрим на типичную конфигурацию файла дескриптора основного модуляGoogle_web_toolkit.gwt.xml:


    
    
    

We make core GWT stuff accessible by including the com.google.gwt.user.User interface. Также мы можем выбрать таблицу стилей по умолчанию для нашего приложения. В данном случае это*.clean.Clean.

Другие доступные параметры стиля:*.dark.Dark,*.standard.Standard,*.chrome.Chrome. com.example.client.Google_web_toolkit  также отмечен здесь тегом<entry-point />.

10. Добавление обработчиков событий

Для управления событиями ввода с клавиатуры или мыши GWT будет использовать некоторые обработчики. They all extend from EventHandler interface and have a method with the event type argument.

В нашем примере мы регистрируем обработчик события щелчка мышью.

Это будет запускать методonClick() каждый раз, когда нажимается кнопка :

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

Здесь мы можем изменить состояние и поведение виджета. В нашем примере мы скрываемvPanel и включаемsendButton.

Другой способ - определить внутренний класс и реализовать необходимые интерфейсы:

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
        }
    }
}

ПомимоClickHandler, мы также включаем сюда интерфейсKeyUpHandler для отслеживания событий нажатия клавиш. Здесьinside of onKeyUp() method we can use the KeyUpEvent to check if the user pressed the Enter key.

А вот как мы используем классMyHandler для регистрации обоих обработчиков событий:

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

11. Вызов сервера

Теперь мы готовы отправить сообщение на сервер. Мы выполним удаленный вызов процедуры с помощью асинхронного методаsendMessage().

The second parameter of the method is AsyncCallback<String> 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);
    }
});

Как видим,receiver implementsonSuccess(String result)and onFailure(Throwable)method for each response type.

В зависимости от результата ответа мы либо устанавливаем сообщение об ошибке «произошла ошибка сервера», либо отображаем значение результата в контейнере.

12. CSS Styling

При создании проекта с помощью плагина eclipse он автоматически сгенерирует файлGoogle_web_toolkit.css в каталоге/webapp и свяжет его с основным файлом HTML.

Конечно, мы можем программно определять пользовательские стили для конкретных компонентов пользовательского интерфейса:

sendButton.addStyleName("sendButton");

Здесь мы назначаем стиль CSS с именем классаsendButton нашему компонентуsendButton:

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

13. Результат

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

image

Здесь мы отправляем на сервер сообщение «Привет!» И выводим на экран ответ «Привет, привет!».

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

In this quick article, we learned about the basics of GWT Framework. Затем мы обсудили архитектуру, жизненный цикл, возможности и различные компоненты своего SDK.

В результате мы узнали, как создать простое веб-приложение.

И, как всегда, доступен полный исходный код учебникаover on GitHub.