msgbartop
ChemHack.com中文版
msgbarbottom

09 九 10 Grails文档之GWT插件

英文原文来自Grails官方网站,本人原创翻译,转载请注明来自xia3hua4 

GWT插件

Google Web Toolkit(GWT)是一个可以用Java语言开发富用户界面的高级AJAX框架,也就是说你可以充分利用Java的类型检查和代码重用特性。GWT会编译你的Java代码以生成执行迅速且跨平台的Javascript代码,你可以将其用于任意的Web页面。

本插件既简化了GWT和GSP页面协作的过程,又简化了服务器端RPC请求的处理。如果你以前没有用过GWT,请阅读GWT官方网站的文档来了解如何使用GWT。

要求:Grails 0.5.6以上版本

安装

  1. 这里下载并安装GWT1.4,请确认选择了正确平台的版本。
  2. 将环境变量GWT_HOME设置位GWT解压后的目录,例如:/home/sinbad/dev/gwt-linux-1.4.60。
  3. 在任意Grails项目中运行grails install-plugin gwt命令安装本插件。

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

上述命令会创建文件:

  • src/java/org/example/MyApp.gwt.xml
  • src/java/org/example/client/MyApp.java

创建宿主页面

创建了一个模块之后,你需要创建一个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服务。虽然这样你会失去自动同步的便利,但是使得你可以完全控制接口定义。

  • src/java/example/client/MyService.java
  • src/java/example/client/MyServiceAsync.java

注意 如果你修改了任意一个接口文件,本插件会停止同步所有的接口文件。这样是为了确保你进行的修改可以得到保留,比如添加'@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发布时此问题能被解决。

编译GWT模块

本插件会在你第一次进行普通Grails编译动作时自动编译GWT模块,比如在运行grails compile 或者 grails run-app时。如果模块已经被编译过,在开发模式下不会被再次编译。如果你使用GWT宿主模式来测试应用程序的话这样很好,不过如果你使用标准浏览器来测试,你做的修改并不会反映出来。所以,如果你想要使用普通浏览器测试开发种的最新修改时,你可以使用下述命令手动编译GWT模块:

grails compile-gwt-modules创建一个WAR

这里很简单,运行下述Grails命令即可:

grails war

本插件会确保在文件打包之前已经编译了GWT模块。完成了之后,你可以将你的web应用程序像通常一样部署到任意的servlet容器中。

   

 

Leave a Comment