GWT介绍

以开发应用程序的方式开发Web2.0程序。


AJAX的概念已经流行了很长时间了,目前比较成功的,“如雷贯耳”的AJAX应用有Google Earth,Gmail等。GWT全称Google Web Toolkit。是Google开发的AJAX开发框架,目前已全部开源。(本文基于GWT提供的开发指南(Developer Guide),所采用的图片,例子均出自GWT,可以认为是GWT的学习笔记J)
GWT的核心是通过一个编译器(compiler)把Java代码翻译为JavaScript代码,开发期间,用户以类似开发AWT或SWING应用程序的方式实现所需要的功能,然后通过GWT的编译器可以把您的应用程序翻译为功能相同的Web2.0程序。而且生成的Web2.0程序可以在大部分主流浏览器上运行,如:Internet Explorer, Firefox, Safari。

基本概念
Hosted Mode:当您利用Java IDE编辑,调试,运行应用程序时,处于Hosted Mode。此时应用程序未翻译为Javascript,而是以字节码(bytecode)形式运行在JVM中。GWT提供一个内嵌的浏览窗口 (browser window)运行应用。您可以采用传统的“编码-测试-调试-修改-……”的方式进行开发。

Web Mode:在Host Mode模式下运行正确的应用,可以通过GWT编译器将Java代码翻译为Javascript代码,发布到Web服务器,以浏览器访问,此时您的应用称为处于Web Mode,而不再依赖于JVM或任何浏览器插件(plug-in)来运行。

Host Page:任何HTML页面,都可以包含GWT生成的代码,称为Host Page。

Client-side Code:Javascript代码在客户的浏览器中运行,称为Client-side Processing。GWT应用中部分Java代码将会最终翻译为Javascript,这部分代码称为Client-side Code。

Server-side Code:任何发生Web服务器内部的处理称为Server-side Processing。客户短通过RPC(Remote procedure call)向服务器发起请求,Server-side Code接收请求并处理。
模块(Modules) 模块是GWT中最重要的概念。可以理解为功能模块,即一个模块实现某一特定功能,如:邮件模块可以收,发,阅读邮件等。
模块配置文件以XML文件的格式定义,文件名后缀通常为:gwt.xml。主要属性如下:
入口点类(Entry-Point Classes) 模块的入口点类需要实现EntryPoint接口,并且入口点类需要有一个无参数的构造函数。当模块加载时,实例化入口点类,onModuleLoad()方法将会被调用。我们通常在这时构造用户界面。可以指定多个入口点类。
源路径(Source Path) 指定Client-side Code所在的路径,默认为client。
公共路径(Public Path) 指定公共资源所在的路径,默认为public。
继承(inherits) 指定要继承其属性的模块。可以指定继承多个模块。
通常以逻辑名字引用模块。如:~/src/com/example/cal/Calendar.gwt.xml。其逻辑名字为 com.example.cal.Calendar。
在页面中,通过指定名为gwt:module的meta属性来将页面与模块绑定,如:
<meta name="gwt:module" c>
GWT编译器在处理时,需要指定模块的逻辑名字,通过逻辑名字在当前路径下寻找配置文件,继而确定Client-side Code位置,以及公共资源位置。如:
@java -cp "%~dp0\src;%~dp0\bin;%~dp0\../../gwt-user.jar;%~dp0\../../gwt-dev-windows.jar" com.google.gwt.dev.GWTCompiler -out "%~dp0\www" %* com.example.cal.Calendar
其中:%~dp0表示当前路径。com.example.cal.Calendar为模块逻辑名字。编译器将在~/src/com/example /cal/路径下寻找Calendar.gwt.xml文件。如果该文件采用默认配置,则会将~/src/com/example/cal/client 目录下的Java代码翻译为Javascript代码并保存置~/www/ com.example.cal目录下,~/src/com/example/cal/public下的文件则会全部拷贝到~/www/ com.example.cal目录下。
GWT项目结构 假设要开发的Web2.0应用名称为com.example.call。则推荐的目录结构如下:


目录路径


存放内容


com/example/cal/
模块配置文件(module XML files)

com/example/cal/client/
客户端代码(Client-side Code)

com/example/cal/server/
服务端代码(Server-side Code),如RPC服务的实现代码

com/example/cal/public/
静态文件,如:Html页面,图片,Css文件,脚本文件等

GWT提供的命令行工具 为方便开发GWT应用,提供了几个命令行工具。
ProjectCreator
构造一个初始的Eclipse项目,并可选生成Ant编译文件

ApplicationCreator
构造一个出生的GWT应用,包含编译命令,已经启动命令

JunitCreator
生成Junit测试代码

I18nCreator
生成国际化处理脚本及属性文件

构造用户界面
GWT用户界面开发类似于目前流行的UI框架,如:Awt,SWING。可以用GWT提供的DOM接口来处理浏览器的DOM树,也可以用GWT提供的 Widget树来构造界面,通常来讲后者要简单很多。GWT通过组合Widgets和Panels来构造界面。界面风格用标准的CSS进行定义。
Widgets是单独可复用的界面组件,如按钮(Button),树(Tree),菜单(Menu,MenuItem),文字输入框(TextBox)。
Button


RadioButton


TextArea


MenuBar


Tree


Panels则是用来摆放Widgets的容器,GWT提供了多种Panel。其中RootPanel是每个GWT应用都需要用到的,它是整个UI 树的根节点,可通过RootPanel.get()方法获取。默认的RootPanel与HTML页面的Body对应。其他常用的Panel主要有:
HorizontalPanel


VerticalPanel


FlowPanel


StackPanel


DockPanel


TabPanel


更多的Widgets和Panels请参考GWT提供的API。
和AWT,SWING类似,GWT应用也采用事件-监听者(Events-Listeners)方式进行交互。Widgets发布不同的事件,通过绑定相应的监听者类对事件进行处理。熟悉Java开发或.Net开发的可以很容易理解这一点。
如果觉得GWT提供的组件不满足要求,也可以开发自定义的组件,主要有三种方法开发自定义组件:
1.
继承Composite类,在其中组合需要的Widget
2.
参考GWT提供的Widget实现,从头开始开发
3.
利用JavaScript
通常建议用第一种方法开发自定义组件。GWT所附带的例子程序中有自定义开发组件的例子。

RPC – Remote Procedure Call
GWT应用与传统的HTML Web应用最基本的区别是:GWT应用执行请求时不需要获取整个页面数据,就像运行在浏览器中的一个应用程序,GWT应用可以部分更新用户界面,一个好的 GWT应用可以把大部分用户界面逻辑处理放在客户端执行,只在需要业务数据时与服务器交互,获取合适的数据。显而易见,这种方式可以大大节省通讯流量,提高应用性能,降低Web服务器缚在,改善用户体验。这种客户端与服务器的交互,称为RPC。服务端提供给客户端调用的功能称为服务(Service)。要注意,这里的服务与常说的Web Service完全是两个概念。也许大家能够猜到GWT应用底层是如何实现RPC的,核心就是XMLHttp,一个比较古老的东东,借助与GWT框架,发挥出了强大的能量。



上图为要实现一个Service所要做的工作。
在Client-side Code 声明两个接口:YourService和YourServiceAsync。即一个同步接口和一个异步接口。要求同步接口声明继承 com.google.gwt.user.client.RemoteService接口,异步接口所声明的方法必须与同步接口声明的方法具有相同的名称,返回类型一定为void,且参数比同步方法的参数多一个AsyncCallback对象,异步接口的名字为同步接口名+Async。
假设我们声明一个同步接口:com.example.foo.client.FooService如下:

public
interface FooService extends RemoteService

{


ReturnType fooMethod(ParamType1 start, ParamType2 end,……);


}
则异步接口要声明为:

public
interface FooServiceAsync

{

void fooMethod(ParamType1 start, ParamType2 end,……, AsyncCallback callback);


}

在Server-side Code实现具体的处理类:YourServiceImpl。该类需要具体实现上述同步接口声明的方法,同时要继承 RemoteServiceServlet类,该类继承自HttpServlet,即所实现的具体处理类实际上为一个标准的Servlet,在产品发布到应用服务器时,要在web.xml文件中对该Servlet进行配置。在开发过程中,可以利用GWT提供的嵌入Tomcat环境,通过在模块配置文件中配置<servlet>标签来对RPC服务进行测试。
从客户端发起RPC调用的过程如下:
1.
通过GWT.Create()方法获取服务接口
2.
通过ServiceDefTarget类指定服务入口地址(Service entry poin URL)
3.
构造一个AsyncCallback类
4.
传人上面的AsyncCallback类,调用服务接口方法
假设服务接口定义为:
public interface MyEmailService extends RemoteService
{

void emptyMyInbox(String username, String password);
}
则对应的异步接口定义为:
public interface MyEmailServiceAsync
{

void emptyMyInbox(String username, String password,

AsyncCallback callback);
}
客户端调用过程如下:
……
//1。获取服务接口代理类
MyEmailServiceAsync emailService = (MyEmailServiceAsync) GWT.create(MyEmailService.class);
//2。指定服务入口地址
ServiceDefTarget endpoint = (ServiceDefTarget) emailService;
String moduleRelativeURL = GWT.getModuleBaseURL() + "email";
endpoint.setServiceEntryPoint(moduleRelativeURL);
//3。构造AsyncCallback类
AsyncCallback callback = new AsyncCallback() {

public void onSuccess(Object result) {

// do some UI stuff to show success

}

public void onFailure(Throwable caught) {

// do some UI stuff to show failure

}

};
//4。调用服务接口
emailService.emptyMyInbox(fUsername, fPassword, callback);
……

注意:接口参数,和返回值必须为serializable。即可序列化。具体要求请参考GWT文档。

国际化
GWT应用提供多个接口及类,以辅助进行国际化处理。这些辅助接口及类都定义在com.google.gwt.i18n.client包内。一个国际化的应用必然要包含针对不同Locale的定义文件,其本地化处理方法,定义文件的命名方式,查找顺序与Java应用程序相同,请参考Java相关文档。。
Constants 一个标记接口,本身未定义任何方法。用于对一些应用中用到常量进行国际化处理。实际应用中需要定义需要的接口类,继承该接口,并声明与常量同名的方法。通过GWT.create(Class)实例化接口,GWT编译器会自动生成接口定义类,并根据本地化设置实现合适的方法。假设有常量定义文件:MyConstants.properties,其内容如下:

firstName = First Name
lastName = Last Name
则需要声明接口MyConstants,同时继承Constants接口,并要声明以下方法:

String firstName();

String lastName();
即方法名与常量定义的名称相同。注意:方法名默认需要与常量相同,但可以在源代码中添加 @gwt.key constantName来指定匹配的常量,然后给方法取任意的名字,如:

/**

* Translated "First Name".

*

* @return translated "First Name"

* @gwt.key firstName

*/

String
anotherfirstName();

声明的常量接口通过GWT.Create(MyConstants.class)实例化,GWT会自动生成代理类实现常量接口。
常量接口中声明的方法必须未以下格式:

Type methodName();
Type可以为多种类型:String,String[],int,float,boolean,Map。具体每种类型对应的常量定义格式请参考GWT提供的API文档。
ConstantsWithLookup 该接口与Constants类似。但该接口同时定义了一些查找常量的方法,如:getString(methodName)。其中methodName的规则与Constants相同。显而易见,该类提供的额外功能是可以传人可变的方法名(methodName)以获取常量,更加的“动态”。
Messages 前面两种接口处理的常量定义文件为完全静态不变的,即其常量访问方法都是无参数的。Message接口则可以在此基础上提供“参数化”的处理。其方法声明为如下格式:

String methodName(optional-params)
假设常量定义文件内容如下:

requiredField = ''{0}'' is a required field.
即声明了一个可变参数,则对应的方法为:

String requiredField(String text);
Dictionary
Dictionary不是接口,而是类。用于处理定义在HTML文件中的“键/值”变量。具体使用方法请参考GWT的API文档。
Localizable
Localizable也是一个标签接口。通过如下方式获取具体的类:
Type localized = (Type)GWT.create(Type.class);
其中Type是一个继承了Localizable的接口。根据实际应用可以定义多个实现了该接口的类,如:Type_,Type_fr,Type_en 等。GWT根据客户端指定的本地化属性实例化具体的类。即:如果指定了fr,则会实例化Type_fr类,如果该类不存在,则实例化Type_类。其处理方法类似与Java中的ListResourceBundle类。
运行时本地化属性
Java应用程序通过一个Locale类来指定应用运行时特定的本地化属性,GWT应该则通过在页面中指定属性或通过页面参数指定。如在页面中包含如下语句:

<meta name="gwt:property" c>
或http://www.example.org/myapp.html?locale=fr_CA 。
模块定义 要利用GWT的国际化功能,相应的模块必须要继承com.google.gwt.i18n.I18N,即模块定义文件中必须有<inherits name="com.google.gwt.i18n.I18N"/>这样的定义。同时根据实际需要在模块定义文件中添加<extend- property>标签以包含所有可能的本地化属性。格式如下:

<extend-property name="locale" values="x_Y" />


关于利用GWT开发Web应用的介绍到此为止,具体的应用例子可以参考GWT附带的几个Samples,涉及了几乎全部的GWT开发场景。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值