GWT有两种与服务端进行交互的技术:GWT RPC和基于普通AJAX的远程交互技术。这里只介绍GWT RPC技术。
一个完整的RPC服务至少包含三个Java文件:
1、客户端远程接口类,需要继承RemoteService类
2、客户端远程接口类的异步类,异步类的名称格式是: 客户端远程接口类名 + Async 后缀
3、服务器端的远程接口类,需要继承RemoteServiceServlet类和实现客户端远程接口类
客户端相关的类必须位于client包及其子包下,服务器端相关的类必须位于server包及其子包下。
1、客户端远程接口类 源码
/** * 客户端远程接口类需要继承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、客户端远程接口类的异步类 源码
/** * 异步接口的方法返回值均为void,并且其对应的每个方法都比原接口多一个类型为AsyncCallback的参数 */ public interface PersonServiceAsync { public void getPerson(String name, int age, AsyncCallback callback) throws RuntimeException; }
3、服务器端的远程接口类 源码
/** * 实现类要继承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、交互过程中传递的对象
/** * 在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接口,其源码如下
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应用入口点类关联起来
<servlet path="/PersonService" class="com.cjm.server.PersonServiceImpl"/>
7、在web.xml文件增加以下配置信息