英文原文来自Grails官方网站,本人原创翻译,转载请注明来自xia3hua4
GWT插件
Google Web Toolkit(GWT)是一个可以用Java语言开发富用户界面的高级AJAX框架,也就是说你可以充分利用Java的类型检查和代码重用特性。GWT会编译你的Java代码以生成执行迅速且跨平台的Javascript代码,你可以将其用于任意的Web页面。
本插件既简化了GWT和GSP页面协作的过程,又简化了服务器端RPC请求的处理。如果你以前没有用过GWT,请阅读GWT官方网站的文档来了解如何使用GWT。
要求:Grails 0.5.6以上版本
Mac OS X 10.5(leopard)用户请使用下列GWT版本。
http://google-web-toolkit.googlecode.com/files/gwt-leopard-1.4.61.tar.gz
开始使用GWT的时候,第一件事情就是创建一个模块。模块将一系列客户端代码封装为一个单元。
创建一个模块
grails create-gwt-module <module>
上述命令会在项目的src/java目录下生成一个模块文件以及一个对应的客户端类文件。如果模块的名称中有包(package),那么文件会在相应的目录路径中创建。例如:
grails create-gwt-module org.example.MyApp
上述命令会创建文件:
创建了一个模块之后,你需要创建一个HTML页面来放置该模块所定义的UI元素。运行下述Grails命令即可:
grails create-gwt-page <page> <module>
第一个参数指定了要创建的页面,第二个参数指定了页面中所要放置的GWT模块。页面需要使用文件的相对路径指定,路径的结尾可以是"html"或者"gsp”或者其他。如果路径由目录名称和GSP文件名组成,则会被当作控制器的视图。如果不是则当作普通的web页面。
// 下述命令会创建视图文件: grails-app/views/main/index.gsp grails create-gwt-page main/index.gsp org.example.MyApp
// 下述命令会创建文件: web-app/dir/main.html grails create-gwt-page dir/main.html MyModule
// 下述命令会创建文件: web-app/index.gsp grails create-gwt-page index.gsp org.example.AnotherModule
如果使用第一个方法并且指定的控制器不存在的话,grails脚本会提示是否自动创建。
GWT中有个叫做宿主模式的东西,使得你可以在一个特殊的浏览器中测试、调试你的web界面。本插件中同样提供了此项功能。只需运行下述命令即可:
grails run-gwt-client
上述命令会启动宿主模式浏览器并将其指向你正在运行的web应用程序。(你可以在一个命令行窗口中运行)grails run-app并在另一个命令行窗口中运行上述命令。如果你的web应用程序不是在本机运行的,或者不是在默认端口运行的,你可以向脚本传递参数来将宿主模式浏览器指向其他的URL。
// 运行在8080端口上的非本机主机
grails run-gwt-client myServer
// 本机非默认端口。 grails run-gwt-client 9090
// 两种情况同时存在 grails run-gwt-client myServer:9090服务器端RPC
几乎所有的实用GWT应用程序都需要在某些地方用到RPC支持。GWT通常需要为你定义的每个服务接口编写一个servlet,不过本插件简化了这个过程,使得你可以使用普通的Grails服务实现RPC的服务器端。通过添加expose属性,任何服务都可以为GWT进行配置,这和使用Remoting等插件是差不多的。
class MyService {
static expose = [ 'gwt:example.client' ]
List listUsers() {
…
}
…
}
GWT expose 属性的格式是很简单的:gwt:<package> ,相关RPC会创建在<package> 所指定的java包中。这通常和某个模块的入口点包相同。
你现在需要运行应用程序(grails run-app)以便生成需要的RPC接口。该插件同样也会在你修改服务时更改接口文件,只要你不自己修改这些接口。如果你修改了这些接口,本插件就不会同步接口和Grails服务。虽然这样你会失去自动同步的便利,但是使得你可以完全控制接口定义。
注意 如果你修改了任意一个接口文件,本插件会停止同步所有的接口文件。这样是为了确保你进行的修改可以得到保留,比如添加'@gwt.typeArgs'这样的javadoc注解。
在从客户端GWT代码中访问服务是,可以使用下述示例中的URL:
MyServiceAsync myService = (MyServiceAsync) GWT.create(MyService.class);
ServiceDefTarget endpoint = (ServiceDefTarget) myService;
// 注意RPC服务所在的URL String moduleRelativeURL = GWT.getModuleBaseURL() + "rpc";
endpoint.setServiceEntryPoint(moduleRelativeURL);
// 调用服务种的方法 List users = myService.listUsers()
…集合和映射类型
GWT既支持list、set这样的集合,也支持映射作为方法的参数和返回值。不过,GWT并不支持使用泛型指定集合或者映射中包含的数据类型,用户必须想RPC接口定义中加入自定义的javadoc注解'@gwt.typeArgs'。如果你使用1.5或者以上版本的JVM的话,本插件可以稍稍简化此项过程,自动添加CollectionTypeArg 和 MapTypeArg。这既可以用来指定参数类型也可以指定返回值类型,如下所示:
class MyService {
static expose = [ 'gwt:example.client' ]
// The return list contains objects of type java.lang.String. @CollectionTypeArg(String)
List listUsers() {
…
}
// 'arg' 参数是一个映射,其中的键是java.lang.Integers类型, // 值是java.lang.Strings类型。 void processMap(@MapTypeArg(key=Integer, value=String) Map arg) {
…
}
…
}
注意 在编写本文档时,注解还不支持方法签名。希望在Grails 1.0发布时此问题能被解决。
本插件会在你第一次进行普通Grails编译动作时自动编译GWT模块,比如在运行grails compile 或者 grails run-app时。如果模块已经被编译过,在开发模式下不会被再次编译。如果你使用GWT宿主模式来测试应用程序的话这样很好,不过如果你使用标准浏览器来测试,你做的修改并不会反映出来。所以,如果你想要使用普通浏览器测试开发种的最新修改时,你可以使用下述命令手动编译GWT模块:
grails compile-gwt-modules创建一个WAR
这里很简单,运行下述Grails命令即可:
grails war
本插件会确保在文件打包之前已经编译了GWT模块。完成了之后,你可以将你的web应用程序像通常一样部署到任意的servlet容器中。