Google 网页工具包——GWT 提供了一组基于Java语言的开发包,这个开发包的设计参考Java AWT包设计,类命名规则、接口设计、事件监听等都和AWT非常类似。开发出来的Java应用将由GWT开发包提供的编译工具编译后声生成对应的、应用了Ajax技术的Web应用,Java应用中出现的、和服务器之间的交互动作被自动生成的异步调用代码所代替。下面对GWT的异步交互进行说明。
一、简介
GWT有两种与服务端进行交互的技术:GWT RPC和基于普通AJAX的远程交互技术。这里只介绍GWT RPC技术。
一个完整的RPC服务至少包含三个Java文件:
1、客户端远程接口类,需要继承RemoteService类
2、客户端远程接口类的异步类,异步类的名称格式是: 客户端远程接口类名 + Async 后缀
3、服务器端的远程接口类,需要继承RemoteServiceServlet类和实现客户端远程接口类。
客户端相关的类必须位于client包及其子包下,服务器端相关的类必须位于server包及其子包下。
二、实例
1、客户端远程接口类 源码
JAVA代码
/**
* 客户端远程接口类需要继承RemoteService类
*/
public interface PersonService extends RemoteService {
public Person getPerson(String name, int age) throws RuntimeException;
//使用内部类创建客户端远程接口类的异步类
public static class Utils{
private static PersonServiceAsync serviceAsync;
public static PersonServiceAsync getInstance(){
if(serviceAsync==null){
serviceAsync = (PersonServiceAsync) GWT.create(PersonService.class);
}
return serviceAsync;
}
}
}
2、客户端远程接口类的异步类 源码
JAVA代码
/**
* 异步接口的方法返回值均为void,并且其对应的每个方法都比原接口多一个类型为AsyncCallback的参数
*/
public interface PersonServiceAsync {
public void getPerson(String name, int age, AsyncCallback callback) throws RuntimeException;
}
3、服务器端的远程接口类 源码
JAVA代码
/**
* 实现类要继承RemoteServiceServlet类
*/
public class PersonServiceImpl extends RemoteServiceServlet implements PersonService {
public Person getPerson(String name, int age) throws RuntimeException {
//与HTTP的交互
HttpServletRequest request = this.getThreadLocalRequest();
HttpServletResponse response = this.getThreadLocalResponse();
HttpSession session = request.getSession();
return new Person(name, age);
}
}
4、交互过程中传递的对象
JAVA代码
/**
* 在GWT RPC中,如果要交互的数据(方法的参数和返回值)是一个复杂类型的话,
* 那么这个类要实现IsSerializable接口,来使该类能被正常序列化和反序列化。
*/
public class Person implements IsSerializable {
private String name;
private int age;
public Person(){
}
public Person(String name, int age){
this.name = name;
this.age = age;
}
//省略getter、setter方法
}
5 、 GWT 应用入口点类需要实现 EntryPoint 接口,其源码如下
JAVA代码
public class Index implements EntryPoint {
public void onModuleLoad() {
Button button = new Button("Click me");
VerticalPanel vPanel = new VerticalPanel();
vPanel.setWidth("100%");
vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
vPanel.add(button);
RootPanel.get().add(vPanel);
//按钮的单击事件
button.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
//初始化Service接口
PersonServiceAsync personService = PersonService.Utils.getInstance();
//为Service代理描述Service接入点的URL
ServiceDefTarget target = (ServiceDefTarget)personService;
String path = GWT.getModuleBaseURL() + "PersonService";
target.setServiceEntryPoint(path);
//发出RPC请求
personService.getPerson("cjm", 100, new AsyncCallback(){
public void onSuccess(Object result) {
Person person = (Person)result;
Window.alert(person.getName());
}
public void onFailure(Throwable caught) {
Window.alert(caught.getMessage());
}
});
}
});
}
}
6
、在
Index.gwt.xml
文件中增加以下配置信息
将RPC服务与GWT应用入口点类关联起来
XML代码
<servlet path="/PersonService" class="com.cjm.server.PersonServiceImpl"/>
7、在
web.xml
文件增加以下配置信息
XML代码
<!-- 在宿主模式下启动应用时,此servlet是必须的 -->
<servlet>
<servlet-name>shell</servlet-name>
<servlet-class>com.google.gwt.dev.shell.GWTShellServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>shell</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- RPC服务配置 -->
<servlet>
<servlet-name>PersonService</servlet-name>
<servlet-class>com.cjm.server.PersonServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PersonService</servlet-name>
<url-pattern>/PersonService</url-pattern>
</servlet-mapping>