用GWT简化AJAX开发(1)(2)
现在可以为应用程序添加服务器端功能了。对BookSearch应用程序而言,需要调用远程API,才能检索与给定的搜索词语相匹配的图书列表。GWT提供了RPC框架,可用于把服务提供给客户端,还可以调用它进行实际搜索。 图中显示了BookSearch应用程序的通信机制。

实现服务器端代码的第一步就是为搜索服务定义接口。该接口必须扩展com.google.gwt.user.client.rpc.RemoteService接口,并含有将提供给GWT客户端代码的方法。下列代码显示了搜索服务接口。其惟一的一个方法将搜索词语作为输入,并返回一组含有表示匹配列表的数据的Book对象:
| publicinterfaceSearchService extendscom.google.gwt.user.client.rpc.RemoteService { Book[]getBooks(StringsearchTerm,intstartIndex,intmaxCount); } |
来自JavaScript的AJAX调用是异步的,因此,必须定义与RemoteService接口相对应的异步接口。该异步接口的方法签名与远程接口的方法签名相匹配,不过多了类型com.google.gwt.user.client.rpc.AsyncCallback这个参数。异步服务完成后,就会调用该参数。返回类型也被清除,因为回调对象将用于传送响应。下列代码显示了SearchService的异步接口:
|
publicinterfaceSearchServiceAsync com.google.gwt.user.client.rpc.AsyncCallbackcallback); |
AsyncCallback类有两个方法:onSuccess()和onFailure(),远程服务成功或失败后,就会调用这两个方法。
现在可以为SearchService类创建异步实现类。只要使用Apache HTTPClient框架,通过与搜索相关的远程API,调用HTTP GET方法,就可以为实际搜索操作的逻辑提供便利。这里,搜索API由Safari Books Online提供,并由URL:http://my.safaribooksonline.com/xmlapi/search=来调用。从Safari Books Online搜索API返回的结果是一个XML文档。该文档作为文档对象模型(DOM)文档,使用Java API for XML Processing(JAXP)框架来处理。
下列代码显示了使用Apache Commons HttpClient类调用搜索API,并使用JAXP API将结果作为DOM文档来处理:
| HttpClientclient=newHttpClient(); GetMethodget=newGetMethod(url); org.w3c.dom.DocumentxmlDoc=null; try { //调用远程搜索API intresultCode=client.executeMethod(get); if(resultCode==200) { InputStreamin=get.getResponseBodyAsStream(); DocumentBuilderbuilder=builderFactory.newDocumentBuilder(); xmlDoc=builder.parse(in); } else { thrownewIOException("HTTPerrorwithresponsecode:"+resultCode); }} finally { //释放连接 get.releaseConnection();} |
| org.w3c.dom.NodeListnodeList=xmlDoc.getElementsByTagName("book"); if(nodeList!=null) { intlen=nodeList.getLength(); for(inti=0;i { org.w3c.dom.ElementbookElement=(org.w3c.dom.Element)nodeList.item(i); org.w3c.dom.Elementtitle=(org.w3c.dom.Element)bookElement.getElementsByTagName("title").item(0); StringtitleStr=(title!=null?title.getTextContent():""); org.w3c.dom.Elementisbn=(org.w3c.dom.Element)bookElement.getElementsByTagName("isbn").item(0); StringisbnStr=(isbn!=null?isbn.getTextContent():""); org.w3c.dom.Elementedition=(org.w3c.dom.Element)bookElement.getElementsByTagName("edition").item(0); StringeditionStr=(edition!=null?edition.getTextContent():""); org.w3c.dom.Elementmsrp=(org.w3c.dom.Element)bookElement.getElementsByTagName("msrp").item(0); StringmsrpStr=(msrp!=null?msrp.getTextContent():""); books.add(newBook(titleStr,isbnStr,editionStr,msrpStr)); } |
从客户端代码调用搜索服务
由于搜索服务类和接口已实现,就可以增强客户端类,以便调用服务,处理响应。步骤如下:首先创建SearchServiceAsync类的实例,如下所示:
| searchService=(SearchServiceAsync)GWT.create(SearchService.class); |
然后,根据SearchServiceAsync实例设定入口点的URL,如下所示:
| ServiceDefTargettarget=(ServiceDefTarget)searchService; StringmoduleRelativeURL=GWT.getModuleBaseURL()+"booksearch"; target.setServiceEntryPoint(moduleRelativeURL); |
第三步,为搜索按钮SearchTermWidget类的onClick方法添加逻辑,并且用SearchTermWidget类的文本框里面的搜索词语来更新相关的BookListWidget类,如下所示:
| ButtonsearchBtn=newButton("Search",newClickListener() { publicvoidonClick(Widgetsender) {booklistWidget.setSearchTerm(searchTermTxtBox.getText());}} |
Data方法――它会调用搜索服务的getBooks方法,用新的搜索词语更新BookSearchProvider。
最后,搜索服务执行及调用通过getBooks方法传送给它的AsyncCallback实例的onFailure或者onSuccess方法:
| searchService.getBooks(searchTerm,startRow,maxRows,newAsyncCallback() { publicvoidonFailure(Throwablecaught) {//处理失败} publicvoidonSuccess(Objectresult) {//用结果更新com.google.gwt.user.client.ui.Grid窗口组件}} |
onSuccess方法被调用后,com.google.gwt.user.client.ui.Grid窗口组件的实例可以用新的图书列表来更新。
GWT消除Web应用难题
Google Web工具包是面向AJAX应用开发的一种Java开发框架。GWT消除了基于AJAX的RPC通信机制的许多技术细节,并提供了窗口组件库,可用于构建丰富的UI。GWT让开发人员可以使用常用的Java开发工具,实现及调试用Java开发的基于AJAX的应用程序,然后把应用程序作为客户端的HTML和JavaScript以及服务器端的Java来编译及部署。
GWT利用Java作为通用语言,把客户端代码和服务器代码融合在一起。这种通用环境以及增强的调试功能等特性确实也存在几个缺点。譬如说,GWT完全依赖JavaScript的可用性。要是没有JavaScript,UI根本无法正常工作。而且,只要是传统Web客户端开发技术力图找出有安全漏洞的地方,都会因为GWT使用Java开发客户端和服务器端代码而将漏洞隐藏起来,因而给人以安全运行的虚假感。
GWT的抽象构成了一种黑盒框架,消除了Web应用开发面临的许多难题,因为它让开发人员转向AJAX风格的开发模型。不过,这种黑盒环境给集成其他非AJAX技术的工作增添了复杂性。因而,GWT最适用于围绕丰富GUI、单一页面模式开发的应用程序。
(责任编辑:铭铭 mingming_ky#126.com TEL:(010)-68476636)






