Приложение на основе GWT обычно состоит из модуля на стороне клиента и модуля на стороне сервера. Код на стороне клиента выполняется в браузере, а код на стороне сервера — на веб-сервере. Код на стороне клиента должен сделать HTTP-запрос через сеть для доступа к данным на стороне сервера.
RPC, Удаленный вызов процедур — это механизм, используемый GWT, в котором клиентский код может напрямую выполнять методы на стороне сервера.
-
GWT RPC основан на сервлетах.
-
GWT RPC является асинхронным, и клиент никогда не блокируется во время связи.
-
Использование GWT RPC Java-объекты можно отправлять напрямую между клиентом и сервером (которые автоматически сериализуются платформой GWT).
-
Сервлет на стороне сервера называется сервисом .
-
Удаленный вызов процедуры, который вызывает методы сервлетов на стороне сервера из кода на стороне клиента, называется вызовом службы .
GWT RPC основан на сервлетах.
GWT RPC является асинхронным, и клиент никогда не блокируется во время связи.
Использование GWT RPC Java-объекты можно отправлять напрямую между клиентом и сервером (которые автоматически сериализуются платформой GWT).
Сервлет на стороне сервера называется сервисом .
Удаленный вызов процедуры, который вызывает методы сервлетов на стороне сервера из кода на стороне клиента, называется вызовом службы .
GWT RPC Компоненты
Ниже приведены три компонента, используемые в механизме связи GWT RPC.
- Удаленная служба (серверный сервлет), работающая на сервере.
- Код клиента для вызова этой службы.
- Объекты данных Java, которые будут передаваться между клиентом и сервером.
Клиент и сервер GWT автоматически сериализуют и десериализуют данные, поэтому разработчикам не требуется сериализовывать / десериализовывать объекты, а объекты данных могут перемещаться по HTTP.
Следующая диаграмма показывает архитектуру RPC.
Чтобы начать использовать RPC, мы должны следовать соглашениям GWT.
Рабочий процесс связи RPC
Шаг 1. Создание класса сериализуемой модели
Определите объект модели Java на стороне клиента, который должен быть сериализуемым.
public class Message implements Serializable { ... private String message; public Message(){}; public void setMessage(String message) { this.message = message; } ... }
Шаг 2 — Создание сервисного интерфейса
Определите интерфейс для службы на стороне клиента, который расширяет RemoteService, перечисляя все методы службы.
Используйте аннотацию @RemoteServiceRelativePath, чтобы сопоставить службу с путем по умолчанию удаленного сервлета относительно базового URL-адреса модуля.
@RemoteServiceRelativePath("message") public interface MessageService extends RemoteService { Message getMessage(String input); }
Шаг 3 — Создайте интерфейс службы Async
Определите асинхронный интерфейс к сервису на стороне клиента (в том же месте, что и сервис, упомянутый выше), который будет использоваться в коде клиента GWT.
public interface MessageServiceAsync { void getMessage(String input, AsyncCallback<Message> callback); }
Шаг 4. Создание класса сервлета реализации службы
Реализуйте интерфейс на стороне сервера, и этот класс должен расширять класс RemoteServiceServlet.
public class MessageServiceImpl extends RemoteServiceServlet implements MessageService{ ... public Message getMessage(String input) { String messageString = "Hello " + input + "!"; Message message = new Message(); message.setMessage(messageString); return message; } }
Шаг 5 — Обновите Web.xml, чтобы включить объявление сервлета
Измените дескриптор развертывания веб-приложения (web.xml), включив в него объявление сервлета MessageServiceImpl.
<web-app> ... <servlet> <servlet-name>messageServiceImpl</servlet-name> <servlet-class>com.tutorialspoint.server.MessageServiceImpl </servlet-class> </servlet> <servlet-mapping> <servlet-name>messageServiceImpl</servlet-name> <url-pattern>/helloworld/message</url-pattern> </servlet-mapping> </web-app>
Шаг 6 — Сделайте удаленный вызов процедуры в коде приложения
Создайте прокси-класс сервиса.
MessageServiceAsync messageService = GWT.create(MessageService.class);
Создайте обработчик AsyncCallback для обработки обратного вызова RPC, при котором сервер возвращает сообщение клиенту
class MessageCallBack implements AsyncCallback<Message> { @Override public void onFailure(Throwable caught) { Window.alert("Unable to obtain server response: " + caught.getMessage()); } @Override public void onSuccess(Message result) { Window.alert(result.getMessage()); } }
Вызов службы Remote, когда пользователь взаимодействует с пользовательским интерфейсом
public class HelloWorld implements EntryPoint { ... public void onModuleLoad() { ... buttonMessage.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { messageService.getMessage(txtName.getValue(), new MessageCallBack()); } }); ... } }
RPC Communication Complete Пример
Этот пример проведет вас через простые шаги, чтобы показать пример Коммуникации RPC в GWT. Выполните следующие шаги, чтобы обновить приложение GWT, которое мы создали в GWT — Глава « Создание приложения» —
шаг | Описание |
---|---|
1 | Создайте проект с именем HelloWorld в пакете com.tutorialspoint, как описано в главе GWT — Создание приложения . |
2 | Измените HelloWorld.gwt.xml , HelloWorld.css , HelloWorld.html и HelloWorld.java, как описано ниже. Сохраните остальные файлы без изменений. |
3 | Скомпилируйте и запустите приложение, чтобы проверить результат реализованной логики. |
Ниже приводится содержимое модифицированного дескриптора модуля src / com.tutorialspoint / HelloWorld.gwt.xml .
<?xml version = "1.0" encoding = "UTF-8"?> <module rename-to = 'helloworld'> <!-- Inherit the core Web Toolkit stuff. --> <inherits name = 'com.google.gwt.user.User'/> <!-- Inherit the default GWT style sheet. --> <inherits name = 'com.google.gwt.user.theme.clean.Clean'/> <!-- Inherit the UiBinder module. --> <inherits name = "com.google.gwt.uibinder.UiBinder"/> <!-- Specify the app entry point class. --> <entry-point class = 'com.tutorialspoint.client.HelloWorld'/> <!-- Specify the paths for translatable code --> <source path = 'client'/> <source path = 'shared'/> </module>
Ниже приводится содержимое измененного файла таблицы стилей war / HelloWorld.css .
body { text-align: center; font-family: verdana, sans-serif; } h1 { font-size: 2em; font-weight: bold; color: #777777; margin: 40px 0px 70px; text-align: center; }
Ниже приведено содержимое модифицированного HTML-файла war / HelloWorld.html .
<html> <head> <title>Hello World</title> <link rel = "stylesheet" href = "HelloWorld.css"/> <script language = "javascript" src = "helloworld/helloworld.nocache.js"> </script> </head> <body> <h1>RPC Communication Demonstration</h1> <div id = "gwtContainer"></div> </body> </html>
Теперь создайте файл Message.java в пакете src / com.tutorialspoint / client и поместите в него следующее содержимое
package com.tutorialspoint.client; import java.io.Serializable; public class Message implements Serializable { private static final long serialVersionUID = 1L; private String message; public Message(){}; public void setMessage(String message) { this.message = message; } public String getMessage() { return message; } }
Теперь создайте файл MessageService.java в пакете src / com.tutorialspoint / client и поместите в него следующее содержимое
package com.tutorialspoint.client; import com.google.gwt.user.client.rpc.RemoteService; import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; @RemoteServiceRelativePath("message") public interface MessageService extends RemoteService { Message getMessage(String input); }
Теперь создайте файл MessageServiceAsync.java в пакете src / com.tutorialspoint / client и поместите в него следующее содержимое
package com.tutorialspoint.client; import com.google.gwt.user.client.rpc.AsyncCallback; public interface MessageServiceAsync { void getMessage(String input, AsyncCallback<Message> callback); }
Теперь создайте файл MessageServiceImpl.java в пакете src / com.tutorialspoint / server и поместите в него следующее содержимое
package com.tutorialspoint.server; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import com.tutorialspoint.client.Message; import com.tutorialspoint.client.MessageService; public class MessageServiceImpl extends RemoteServiceServlet implements MessageService{ private static final long serialVersionUID = 1L; public Message getMessage(String input) { String messageString = "Hello " + input + "!"; Message message = new Message(); message.setMessage(messageString); return message; } }
Обновите содержимое измененного дескриптора развертывания веб-приложения war / WEB-INF / web.xml, включив в него объявление сервлета MessageServiceImpl.
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <!-- Default page to serve --> <welcome-file-list> <welcome-file>HelloWorld.html</welcome-file> </welcome-file-list> <servlet> <servlet-name>messageServiceImpl</servlet-name> <servlet-class>com.tutorialspoint.server.MessageServiceImpl </servlet-class> </servlet> <servlet-mapping> <servlet-name>messageServiceImpl</servlet-name> <url-pattern>/helloworld/message</url-pattern> </servlet-mapping> </web-app>
Замените содержимое HelloWorld.java в пакете src / com.tutorialspoint / client следующим
package com.tutorialspoint.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.dom.client.KeyUpHandler; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.DecoratorPanel; import com.google.gwt.user.client.ui.HasHorizontalAlignment; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.VerticalPanel; public class HelloWorld implements EntryPoint { private MessageServiceAsync messageService = GWT.create(MessageService.class); private class MessageCallBack implements AsyncCallback<Message> { @Override public void onFailure(Throwable caught) { /* server side error occured */ Window.alert("Unable to obtain server response: " + caught.getMessage()); } @Override public void onSuccess(Message result) { /* server returned result, show user the message */ Window.alert(result.getMessage()); } } public void onModuleLoad() { /*create UI */ final TextBox txtName = new TextBox(); txtName.setWidth("200"); txtName.addKeyUpHandler(new KeyUpHandler() { @Override public void onKeyUp(KeyUpEvent event) { if(event.getNativeKeyCode() == KeyCodes.KEY_ENTER){ /* make remote call to server to get the message */ messageService.getMessage(txtName.getValue(), new MessageCallBack()); } } }); Label lblName = new Label("Enter your name: "); Button buttonMessage = new Button("Click Me!"); buttonMessage.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { /* make remote call to server to get the message */ messageService.getMessage(txtName.getValue(), new MessageCallBack()); } }); HorizontalPanel hPanel = new HorizontalPanel(); hPanel.add(lblName); hPanel.add(txtName); hPanel.setCellWidth(lblName, "130"); VerticalPanel vPanel = new VerticalPanel(); vPanel.setSpacing(10); vPanel.add(hPanel); vPanel.add(buttonMessage); vPanel.setCellHorizontalAlignment(buttonMessage, HasHorizontalAlignment.ALIGN_RIGHT); DecoratorPanel panel = new DecoratorPanel(); panel.add(vPanel); // Add widgets to the root panel. RootPanel.get("gwtContainer").add(panel); } }
Когда вы будете готовы со всеми внесенными изменениями, давайте скомпилируем и запустим приложение в режиме разработки, как мы делали в главе GWT — Создание приложения . Если с вашим приложением все в порядке, это даст следующий результат: