Spring Roo 简介,第 6 部分: 使用 Spring Roo 1.2 开发 Spring MVC 和 GWT 应用程序并将它们部署到 Cloud Foundry 上

快速开发和部署 Spring MVC 和 GWT 应用程序

随着 Spring Roo Version 1.2 的发布,Spring Roo 才有了明显的改进。本文将简介当前发行版中的新特性,比如多模块项目、MongoDB 支持、JSF 支持等。然后,将会带您使用 Spring Roo 开发一个多模块的 GWT Web 应用程序,并将该应用程序部署到 Cloud Foundry。

Shekhar Gulati, 高级 Java 顾问, Xebia

Shekar Gulati 的照片Shekhar Gulati 是效力于 Xebia India 的一名 Java 顾问。他拥有 6 年的企业 Java 经验。他在 Spring 产品组合项目(比如 Spring、Spring-WS、Spring Roo 等)方面有丰富的经验。他主要关注 Spring、NoSQL 数据库、Hadoop、SRAD 框架(如 Sring Roo)、云计算(主要是 Google App Engine、CloudFoundry、OpenShift 等 PaaS 服务)和 Hadoop。他是一位活跃的作家,曾为 JavaLobby、Developer.com 和 IBM developerWorks 撰稿,他在 http://whyjava.wordpress.com/ 上拥有自己的博客。您可以在 twitter @ http://twitter.com/#!/shekhargulati 上关注他。



2012 年 10 月 22 日

Spring Release 3.1 中的特性

获得有关 Spring Release 3.1(Spring 框架的最新也是最伟大的版本)中的特性的更多信息:

在本系列的 Spring Roo 简介,第 1 部分:从源代码构建Spring Roo 简介,第 2 部分:使用 Spring Roo 开发应用程序 中,我们使用 Spring Roo 1.1 开发了一个会议应用程序。在 Spring Roo 简介,第 3 部分:开发 Spring Roo 的附加组件Spring Roo 简介,第 5 部分:编写 Spring Roo 的高级附加组件和包装器附加组件 中,我们开发了 Spring Roo 附加组件。而在这两部分之间的 Spring Roo 简介,第 4 部分:用 Spring Roo 和 Cloud Foundry 在云中快速开发应用程序 中,我们查看了 Cloud Foundry 和 Spring Roo 集成。从第 2 部分开始,我们就没有讨论过 Spring Roo 在过去一年中引入的许多新特性和改变。在之前版本中使用的很多命令都已不再工作或已弃用。当前版本的另一个重要方面是 Spring Release 3.1(是 Spring 框架最新也是最棒的发行版)的使用,这个新版本提供了 Profile、Environment abstraction、Cache abstraction 等诸多新特性。使用 Spring Roo 当前版本就意味着使用了 Spring 框架的最新版本。在本文中,我们首先将介绍 Spring Roo 的最新版本,即 Version 1.2.1,然后创建一个多模块的 Google Web Toolkit (GWT) 和 Spring Web Model–View–Controller (MVC) 应用程序并将该应用程序部署到 Cloud Foundry。

Spring Roo 1.2 简介

进一步探索 Spring Roo 的特性

Spring Roo 是构建 Spring 应用程序的一个命令行快速应用程序开发工具。Spring Roo 在过去一年中得到了长足的发展,它的两个主要发行版本 1.1.5 和 1.2 让 Spring Roo 的功能更强大,对企业开发者更加友好。这些发布中引入的主要特性或变更包括:

  1. MongoDB 支持:对于 Spring Roo 的旧版本,Spring Roo 应用程序要求使用 RDBMS(比如 MySQL 或 PostgreSQL)作为后端,Google App Engine BigTable 支持除外(但它从不利用各种关系)。自 Version 1.2 起开始,可以使用 MongoDB 作为数据存储。MongoDB 是一个流行的 NoSQL 文档数据存储。构建 Spring MongoDB 应用程序的能力就凸显了 Spring Roo 的可扩展性。要查看所有的 MongoDB 的相关命令,可以键入:
    help --command mongo
  2. JavaServer Faces (JSF) 2.0 支持:在 Version 1.2 之前,默认情况下,Spring Roo 支持使用 GWT 和 Spring MVC 作为视图选项,但是对于 Version 1.2,Spring Roo 还支持使用 JSF 2.0 作为视图选项之一。Spring Roo 目前支持 Apache MyFaces 和 Oracle Mojarra JSF 实现,还支持使用 PrimeFaces 作为其组件库。这曾经是常见的 JIRA 问题之一,如今也在 Version 1.2 中也得到了解决。要查看 JSF 所有的可用命令,可以键入:
    roo> help --command "web jsf" 
    * web jsf all - Create JSF managed beans for all entities  
    * web jsf media - Add a cross-browser generic player to embed multimedia content  
    * web jsf scaffold - Create JSF managed bean for an entity  
    * web jsf setup - Set up JSF environment

    本文将不会介绍构建 JSF 2.0 应用程序的所有内容,未来的文章中可能会介绍它们。想要构建 JSF 应用程序的开发人员可以尝试使用 bikeshop.roo 应用程序,它是 Spring Roo 捆绑附带的。Roo 分布中有一个样例文件夹。

  3. 多模块 Maven 项目支持:这是社区最强烈要求的流行特性之一,如今已经可用。在 Version 1.2 之前,所有的应用程序代码都必须在一个 Maven 项目中编写。这一点对于构建企业应用程序是不适用的,因为企业应用程序通常有多个子模块来应对不同的应用需求,比如 Web、持久性、服务等。如今,父项目可以为持久性、服务和 Web 定义不同的子模块。在本文后面的有关使用 Spring Roo 构建多模块 Maven 项目的后续部分中,会对这些进行详细介绍。
  4. 存储库和服务层支持:直至 Version 1.2,Spring Roo 才提供了在应用程序中包含存储库(或 DAO)和服务层的方法。默认情况下,它支持 Active Record 模式,以确保存在具有与持久性相关的所有方法的丰富的实体类。这是社区最强烈要求的流行特性之一,如今也已可用。默认情况下,Spring Roo 还支持使用 Active Record 作为实现策略,但是,如果使用 –activeRecord false 创建实体,那么可以选择一个存储库。这也将在本文的后续部分进行详细介绍。
  5. 反向工程支持更强健和更强大的数据库支持:虽然在第 2 部分已经谈及这方面的内容,但这个附加组件在过去一年中有了重大的改进。这些改进包括多模式支持、允许 DBRE 通过 Java Naming and Directory Interface (JNDI) 进行数据库连接、反向工程视图以及对存储库而非 Active Record 实体对象的支持。此外,很多 bug 也得到了修复。DBRE 不在本文的讨论范围之内。有关的更多信息,请参阅 参考资料 部分给出的 Spring Roo 文档。
  6. 改进了的 Spring Roo Add-on API:第 5 部分介绍了 Spring Roo 附加组件的创建。在该本中,我使用了 Spring Roo Version 1.2,因为这个 API 已经有所改进。Version 1.2 之前存在的某些类已经不复存在或是在 Version 1.2 中被弃用。Spring Roo 团队让 API 与当前的 Spring Roo 附加组件的更为一致。将附加组件更新到 Version 1.2 可能会出问题。
  7. 改进了的 GWT 支持:Spring Roo GWT 支持在最新的发布版中得到了改进。早些时候,单个命令 gwt setup 就能够完成从创建代理到向其他与 UI 相关的项发出请求的所有工作。这个单个命令如今已被弃用,并使用 清单 1 中所示的 10 个命令代替了它。GWT 将在本文的后续小节中介绍。
    清单 1. web gwt help 的例子
    roo> help --command "web gwt"
    * web gwt all - Locates all entities in the project and creates GWT requests, 
         proxies, and creates the scaffold
    * web gwt gae update - Updates the GWT project to support GAE
    * web gwt proxy all - Locates all entities in the project and creates GWT proxies
    * web gwt proxy request all - Locates all entities in the project and creates GWT 
         requests and proxies
    * web gwt proxy request type - Creates a proxy and request based on 
         the specified type
    * web gwt proxy type - Creates a GWT proxy based on the specified type
    * web gwt request all - Locates all entities in the project and creates GWT requests
    * web gwt request type - Creates a GWT proxy based on the specified type
    * web gwt scaffold - Creates a GWT request, proxy and scaffold for the specified type
    * web gwt setup - Install Google Web Toolkit (GWT) into your project

除了上述特性和改进之外,我还会在本文提及其他的一些细微变化。我们先来创建一个新的 Spring Roo 1.2 会议应用程序。


Spring Roo 1.2 入门

下载并安装这些先决条件。(请参阅 参考资料。)

  1. Java™ 6 包
  2. Apache Maven 3
  3. Spring Roo 1.2 及其更高版本

本文使用的是 Spring Roo 1.2.1,这是 Spring Roo 的当前版本。

构建会议应用程序

我们将创建与第 1 部分和第 2 部分中相同的会议应用程序。一个 Speaker 可以提供一个或多个 Talk,而 Talk 则只能由一个 Speaker 提供。图 1 给出了这个简单的类图。(Speaker 包含 firstName、lastName、email、organization、birthDate、age 和 gender,Talk 包含 title 和 description。)

图 1. Speaker 和 Talk 表的类图
Speaker 和 Talk 表的类图

创建一个多模块项目

与在一个 Maven 项目中创建整个项目不同,我们将会创建一个包含了两个子模块(core 和 view)的父会议项目。core 模块包含所有的 domain、repository 和服务类。view 子模块也是一个 Project Object Model (POM) 项目,其中又包含两个子模块: MVC and GWT。MVC 项目将包含 Spring MVC 应用程序,GWT 项目则包含 GWT 应用程序。这个会议应用程序有两个 UI:一个基于 Spring MVC,一个基于 GWT。图 2 显示了项目结构。

图 2. Maven 项目结构
Maven 项目的文件结构

图 2 所示的结构展示了具有多个子模块的企业应用程序。现在让我们使用 Spring Roo 来创建它。

  1. 打开操作系统的命令行 shell。
  2. 使用 mkdir 命令创建一个名为 conference 的目录。
  3. 转到 shell 中的 conference 目录。
  4. 键入 roo。此命令将会初始化 Roo shell。
  5. 在 Roo shell 上输入的第一个命令是 project 命令。对于 Version 1.2,此命令已经被更新为支持 POM 项目。POM 项目本身并不包含任何代码;它们只有一个 pom.xml 文件。这些项目被打包成 POM 而非 JAR 或 WAR。要创建一个会议 POM 项目,请键入以下内容:
    project --topLevelPackage org.xebia.conference --projectName conference 
            --java 6  --packaging POM

    这个命令看上去类似于 Spring Roo 简介,第 1 部分:从源代码构建 中使用的 project 命令,只有一点不同:它有另一个称为 packaging 的属性。这个 packaging 属性接受的值是 BUNDLE、JAR、POM 或 WAR 中的一个。对于父项目,该值为 POM。自 Version 1.2 开始,此 project 项目命令可以多包含一个称为 parent 的属性。从名称可以看出,对于继承自其他 POM 的一个项目 POM,可以使用 parent 属性。在创建子模块时,会展示这个属性的用法。请查看由此命令生成的 pom.xml 文件,并验证此 pom.xml 具有打包 POM。

  6. 创建这个会议 POM 项目之后,就可以使用 module 命令创建 core 和 view 子模块了。module 命令类似于 project 命令,只不过它创建的是 Maven 模块而非 Maven 项目。要创建这个 core 模块,请键入以下命令:
    module create --moduleName core --topLevelPackage org.xebia.conference.core 
         --parent org.xebia.conference:conference:0.1.0.BUILD-SNAPSHOT

    module create 命令要求使用两个强制属性:moduleNametopLevelPackagemoduleName 属性用于指定模块的名称,topLevelPackage 属性用于指定模块的打包名称。topLevelPackage 仍然是此模块的 groupId。除了这些强制属性外,还有三个可选属性:

    • –-java 用于指定 Java 版本
    • --packaging 用于指定模块的 Maven 打包
    • --parent 用于指定模块是否继承自其他的 Maven 项目

    在上面所示的命令中,core 模块继承自 conference 项目。parent 属性接受 groupId:artifactId:version 格式的值。这些值可以从 conference/pom.xml 中文件获得。core 模块的 pom.xml 文件显示它具有 parent 标记(如 清单 2 所示)。

    清单 2. pom.xml 文件的 Parent 部分
       <parent> 
            <groupId>org.xebia.conference</groupId> 
            <artifactId>conference</artifactId> 
            <version>0.1.0.BUILD-SNAPSHOT</version> 
        </parent>

    还可以看看 parent 项目 pom.xml,即 conference/pom.xml,并验证它具有包含了 core 模块 module 标记(如 清单 3 所示)。
    清单 3. pom.xml 文件的模块部分
    <modules> 
       <module>core</module> 
    </modules>
  7. 接下来,我们将创建 view 子模块。在开始创建前,不妨将注意力转至使用此 module focus 命令的 root 项目:
    module focus --moduleName ~

    这个波浪符号 (~) 用来指定 root 项目。您可以选择键入 Maven 项目或 Maven 模块的名称。例如,以下命令也可以获得转至 core 项目的相同结果:

    module focus --moduleName core
  8. 现在创建 view 模块。这个模块也具有两个子模块:MVC 和 GWT 的 POM 项目。要创建 view 模块,请键入以下内容:
    module create --moduleName view --topLevelPackage org.xebia.conference.view 
         --packaging POM --java 6
  9. 要创建 GWT 和 MVC 子模块,请执行 清单 4 中所示的命令:
    清单 4. 创建 GWT 和 MVC
    module create --moduleName gwt --topLevelPackage org.xebia.conference.view.gwt 
       --java 6 --parent org.xebia.conference.view:view:0.1.0.BUILD-SNAPSHOT 
    
    module focus --moduleName view 
    
    module create --moduleName mvc --topLevelPackage org.xebia.conference.view.mvc
       --java 6 --parent org.xebia.conference.view:view:0.1.0.BUILD-SNAPSHOT

上述九个步骤的结果就是一个具有四个子模块的多模块项目,这四个子模块是:core、view、GWT 和 MVC。GWT 和 MVC 是 view 子模块的子模块。现在,从 Roo shell 中发出 perform package 命令,以执行所有子模块的全部构建。

添加持久性

创建了 Maven 模块结构后,就可以添加持久性支持了。可以使用 Java Persistence API (JPA) setup 命令来设立与持久性相关的配置。persistent setup 命令已被弃用,所以不再建议使用 persistent setup 命令。Persistence setup 之所以被弃用,是因为 Spring Roo 现在支持不同类型的像 RDBMS 这样的持久数据存储解决方案,以及像 MongoDB 这样的文档数据存储。Persistence setup 是一个比较通用的名称,因此,在将来,如果 Spring Roo 决定添加对其他 NoSQL 数据库(比如 Cassandra)的支持,那么使用的命令将会是 Cassandra setup。要向应用程序添加持久性支持,请键入 清单 5 中的命令。这些需要在 core 模块中完成,所以先使用 module focus 命令转到 core 模块。

清单 5. 用来添加持久性支持的命令
module focus --moduleName core 
jpa setup --database DERBY_EMBEDDED --provider HIBERNATE

Spring Roo 现在支持 15 种数据库,所以您可以选择您喜欢的数据库。JPA setup 命令与 persistence setup 命令类似,具有两个必要属性:database 和 provider,后者是一个 JPA 供应商,比如 Hibernate,或是在使用 Google App Engine 的情况下是 Datanucleus。其余的属性与 persistence 命令相同,所以我在这里就不再讨论。

清空 Roo Shell

在以前,您可能会想要尝试使用 clear 或 cls 命令清空 Roo shell。但是现在,要运行操作系统命令,请键入 ! <os command>。要清空此命令,请键入以下内容:

core roo> ! clear

创建 Speaker 和 Talk 实体

如果输入 hint 命令,系统会建议您创建一个实体。entity 命令已经更改为 entity JPA,以区别于 MongoDB 实体,MongoDB 实体是使用 entity mongo 命令创建的。对 entity 命令的另一个重要更改是:是否选择使用 Active Record 实体。在本文中,将使用 Repositories 而非 Active Record 实体。要创建 Speaker 和 Talk 实体,请键入 清单 6 中的命令:

清单 6. 创建实体
entity jpa --class ~.domain.Speaker --testAutomatically 
     --activeRecord false --serializable 
entity jpa --class ~.domain.Talk --testAutomatically 
     --activeRecord false –serializable

清单 6 明确要求 Roo 不要生成 activeRecord 实体。默认机制仍然是 activeRecord,因此,必须指定 activeRecord false,否则还会生成 Active Record 实体。

向实体添加字段

Field 命令仍然不变,语法也没有任何变化。请键入 清单 7 中的命令,向实体类添加字段。

清单 7. 向实体类添加字段
field string --fieldName firstname --class ~.domain.Speaker --notNull 
field string --fieldName lastname --notNull 
field string --fieldName email --class ~.domain.Speaker --unique --notNull --regexp 
     ^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})
field string --fieldName organization 
field date --fieldName birthdate --type java.util.Date --past --notNull 
field number --type java.lang.Long --fieldName age --min 25 --max 60 
field date --fieldName created --type java.util.Date --notNull 
field string --fieldName title --class ~.domain.Talk --notNull 
field string --fieldName description --notNull --sizeMax 4000 
field date --fieldName created --type java.util.Date --notNull 
field set --fieldName talks --type ~.domain.Talk --class ~.domain.Speaker 
     --cardinality ONE_TO_MANY 
field reference --fieldName speaker --type ~.domain.Speaker --class ~.domain.Talk 
     --notNull

请注意 email 中正则表达式的用法,该表达式用于针对这个正则表达式验证 email。此外还要注意的是,这里还创建了字段名。使用类型 date 创建了名称的字段是不可更新的。YouThis 虽然只是一个小改进,但十分有用。在 清单 8 中的代码片断显示了 column 注释中的可更新的属性值被设为 false。

清单 8. 将可更新属性值设置为 false 的示例
@NotNull 
@Column(updatable = false) 
@Temporal(TemporalType.TIMESTAMP) 
@DateTimeFormat(style = "M-") 
private Date created = new Date();

添加存储库层和服务层

深入探索 Spring JPA 和 Spring 数据

Spring Roo 社区要求提供一种实现 ActiveRecord 模式的可选方式,因为存储库层和服务层在企业应用程序中更为常用,而且开发人员更习惯使用它们。Spring Roo 1.2 通过 Spring JPA 项目使 Repositories 成为了可能。Spring JPA 是 Spring Data 项目旗下的一部分,这就使得实现基于 JPA 的存储库变得很容易。Spring Roo 使用 Spring JPA 存储库,只需为它们编写 repository 接口,Spring JPA 为它们提供了相应的实现。除了基本 CRUD 操作之外,它还支持添加定制的 finder 方法。可以采用以下方法在 repository 接口中定义一个 finder 方法:

List<Person> findPersonByNameAndCountry(String name, String country)

Spring JPA 通过突破此方法名称提供了该方法的一种实现,并返回具有给定名称和国家的所有人员的列表。它减少了代码,但需要确保方法名称务必与实体属性保持一致。如果 Person 类没有名称和国家属性,则会失败。本文没有讨论 Spring Data JPA 项目,但您可以考虑阅读有关它的一些文档。

要向 Speaker 和 Talk 实体添加 Repository 接口,请键入 清单 9 中的命令:

清单 9. 添加 Repository 接口
repository jpa --interface ~.repository.SpeakerRepository --entity ~.domain.Speaker 
repository jpa --interface ~.repository.TalkRepository --entity ~.domain.Talk

repository jpa 命令有两个属性:一个是接口的名称,另一个将为之创建存储库的实体。在本例中,我指定了在 com.xebia.conference.core.repository 包中为 Speaker 实体创建一个 SpeakerRepository。对于 Talk 实体也是如此。在命令的输出中(如 清单 10 所示),可以看到它在 pom.xml 中添加了 spring-data-jpa 依赖项,并创建了 SpeakerRepository.java 接口和相应的 SpeakerRepository_Roo_Jpa_Repository.aj ITD 文件。

清单 10. 示例输出
Created core|SRC_MAIN_JAVA/org/xebia/conference/core/repository 
Created core|SRC_MAIN_JAVA/org/xebia/conference/core/repository/SpeakerRepository.java 
Created core|SPRING_CONFIG_ROOT/applicationContext-jpa.xml 
Updated core|ROOT/pom.xml 
             [added dependency org.springframework.data:spring-data-jpa:1.0.2.RELEASE] 
Created core|SRC_MAIN_JAVA/org/xebia/conference/core/repository/
                                       SpeakerRepository_Roo_Jpa_Repository.aj
Created core|SRC_TEST_JAVA/org/xebia/conference/core/domain/
                                       SpeakerDataOnDemand_Roo_DataOnDemand.aj 
Created core|SRC_TEST_JAVA/org/xebia/conference/core/domain/
                                       SpeakerIntegrationTest_Roo_IntegrationTest.aj

由 repository jpa 命令生成的最为有趣的工件是 *Repository_Roo_Jpa_Repository.aj ITD。类型间声明 (inter-type declaration, ITD) 文件包含了三个声明,如 清单 11 所示。

清单 11. ITD 文件中的声明
privileged aspect SpeakerRepository_Roo_Jpa_Repository { 

 declare parents: SpeakerRepository extends JpaRepository<Speaker, Long>; //1
    
 declare parents: SpeakerRepository extends JpaSpecificationExecutor<Speaker> ; //2
    
 declare @type: SpeakerRepository: @Repository; //3
    
}

第一行是说 SpeakerRepository 接口应该扩展 JpaRepository 接口。JpaRepository 接口包含面向所有 CRUD 方法和其他常用方法的声明。第二行是说 SpeakerRepository 接口应该扩展 JpaSpecificationExecutor 接口。此接口允许基于 JPA 条件 API 执行 Specifications。第三行也是最后一行确保了 SpeakerRepository 接口应该具有 @Repository 注释。

添加服务层

虽然对于使用 Repositories 时有无服务层并没有明确要求,但在大多数场景中,添加一个具有所有业务逻辑的服务层还是有意义的。在您逐渐脱离 Roo 生成的 CRUD 应用程序时,就会发现需要使用服务类,因此,为实体类添加服务类是很有意义的。要为 Speaker 和 Talk 实体创建服务,请在 Roo shell 上执行 清单 12 中的命令:

清单 12. 创建服务
service --interface ~.service.SpeakerService --entity ~.domain.Speaker 
service --interface ~.service.TalkService --entity ~.domain.Talk

用于 SpeakerService 的 service 命令生成了 清单 13 中所示的输出:

清单 13. 来自 SpeakerService 的输出
Created core|SRC_MAIN_JAVA/org/xebia/conference/core/service 
Created core|SRC_MAIN_JAVA/org/xebia/conference/core/service/SpeakerService.java
Created core|SRC_MAIN_JAVA/org/xebia/conference/core/service/SpeakerServiceImpl.java
Created core|SRC_MAIN_JAVA/org/xebia/conference/core/service/
                                       SpeakerService_Roo_Service.aj
Updated core|SRC_TEST_JAVA/org/xebia/conference/core/domain/
                                       SpeakerDataOnDemand_Roo_DataOnDemand.aj
Updated core|SRC_TEST_JAVA/org/xebia/conference/core/domain/
                                       SpeakerIntegrationTest_Roo_IntegrationTest.aj
Created core|SRC_MAIN_JAVA/org/xebia/conference/core/service/
                                       SpeakerServiceImpl_Roo_Service.aj

除了创建一个 service 文件夹和修改 test 类之外,还创建了 SpeakerService、implementation SpeakerServiceImpl 和两个 ITD:SpeakerService_Roo_Service.aj 和 SpeakerServiceImpl_Roo_Service.aj。SpeakerService_Roo_Service.aj 是 SpeakerService 接口的 ITD,确保了 SpeakerService 接口包含了所有必要的方法声明。SpeakerServiceImpl_Roo_Service.aj 包含了在 SpeakerService_Roo_Service.aj ITD 中定义的实现方法,并在编译时将所有实现添加到 SpeakerServiceImpl 类。

至此,core 模块有了本文所需的所有代码。现在,将使用 Spring Roo 创建 GWT 和 MVC UI。

构建一个 GWT 用户界面

Google Web Toolkit (GWT)(参阅 参考资料)是一个开源开发工具箱,通过该工具箱,可以使用 Java 编程语言构建复杂而又丰富的 JavaScript 应用程序。有了 GWT,Java 开发人员编写复杂的启用了 Ajax 的 Web 应用程序就不会很困难,因为它支持开发人员使用 Java 代码来编写代码。此外,GWT 可以通过编译代码来生成高度优化的 JavaScript。

Spring Roo 支持根据域模型创建 GWT 应用程序。

在以前的版本中,单个名为 gwt setup 的命令就能完成从设立 GWT 到为实体创建视图再到确保 Google App Engine 兼容性的所有操作。现在 gwt setup 命令被拆分成 10 个不同的命令,这赋予了开发人员更多的控制权。 清单 14 显示了这些命令。

清单 14. web gwt 的帮助输出
view/gwt roo> help --command "web gwt" 
* web gwt all - Locates all entities in the project and creates GWT requests, proxies 
     and creates the scaffold 
* web gwt gae update - Updates the GWT project to support GAE 
* web gwt proxy all - Locates all entities in the project and creates GWT proxies 
* web gwt proxy request all - Locates all entities in the project and creates GWT 
     requests and proxies 
* web gwt proxy request type - Creates a proxy and request based on the specified type 
* web gwt proxy type - Creates a GWT proxy based on the specified type 
* web gwt request all - Locates all entities in the project and creates GWT requests 
* web gwt request type - Creates a GWT proxy based on the specified type 
* web gwt scaffold - Creates a GWT request, proxy and scaffold for the specified type
* web gwt setup - Install Google Web Toolkit (GWT) into your project

要为域模型创建一个 GWT 前端,需要使用两个命令:web gwt setup 和 web gwt all。可以使用其他命令执行以下操作:

  • 创建代理和请求,或者在不想创建 UI 时同时创建这二者
  • 创建代理和请求,或者同时创建这二者以及 UI
  • 更新 GWT 项目来支持 Google App Engine

本文只介绍了 web gwt setup 和 web gwt all。您可以根据对这两个命令的工作原理轻松使用其他命令。

设立 GWT 项目

Spring Roo 如今遵从一个约定,即它所有的 view 附加组件(比如 GTW、MVC 和 JSF)均有一个 setup 命令。此 setup 命令的责任包括添加必要的 Maven 依赖项、某些配置文件和一些哑类,并创建 view 技术所需的文件夹结构。要设立 GWT 项目,请键入 清单 15 中的命令,其中还显示了此命令的输出。

清单 15. web gwt setup 的样例输出
view/gwt roo> web gwt setup 

Created view/gwt|ROOT/src/main/webapp/WEB-INF/spring 
Created view/gwt|ROOT/src/main/webapp/WEB-INF/spring/webmvc-config.xml 
Created view/gwt|ROOT/src/main/webapp/WEB-INF/web.xml 
Updated view/gwt|ROOT/src/main/webapp/WEB-INF/spring/webmvc-config.xml 
Created view/gwt|SRC_MAIN_JAVA/org/xebia/conference/view/gwt 
Created view/gwt|SRC_MAIN_JAVA/org/xebia/conference/view/gwt/App.gwt.xml 
Created view/gwt|SRC_MAIN_JAVA/org/xebia/conference/view/gwt/client 
Created view/gwt|SRC_MAIN_JAVA/org/xebia/conference/view/gwt/client/AppEntryPoint.java 
Updated view/gwt|ROOT/src/main/webapp/WEB-INF/web.xml 
Updated view/gwt|ROOT/pom.xml 
   [added dependencies org.springframework:spring-webmvc:${spring.version}, 
   org.springframework.webflow:spring-js-resources:2.2.1.RELEASE, 
   commons-digester:commons-digester:2.1, commons-fileupload:commons-fileupload:1.2.2, 
   javax.servlet.jsp.jstl:jstl-api:1.2, org.glassfish.web:jstl-impl:1.2, 
   javax.el:el-api:1.0, joda-time:joda-time:1.6, javax.servlet.jsp:jsp-api:2.1, 
   commons-codec:commons-codec:1.5; updated project type to war; 
   added repository http://maven.springframework.org/external; 
   added dependencies com.google.gwt:gwt-servlet:2.4.0, com.google.gwt:gwt-user:2.4.0, 
   org.json:json:20090211, com.google.gwt.inject:gin:1.5.0, 
   javax.validation:validation-api:1.0.0.GA, 
   javax.validation:validation-api:1.0.0.GA:sources, xalan:xalan:2.7.1; 
   added plugin org.codehaus.mojo:gwt-maven-plugin:2.2.0; 
   added plugin org.codehaus.mojo:exec-maven-plugin:1.2]

此命令的输出显示它刚刚创建了一个模板 GWT 项目,该项目包含所需的 Maven 依赖项和插件、一个样例 AppEntryPoint 类、一个样例 GWT 模块描述符 App.gwt.xml 以及所有 Web 应用程序都需要的 web.xml。web gwt setup 命令执行的操作不是很有趣,所以让我们来看看 web gwt all 命令吧。要为这个域创建一个 GWT UI,请执行以下命令:

web gwt all --proxyPackage ~.client.proxy --requestPackage ~.client.request

web gwt all 命令负责完成全部困难的工作,创建了 GWT 模块部署描述符 ApplicationScaffold.gwt.xml、GWT 入口点 Scaffold.java、Proxy 类 SpeakerProxy 和 TalkProxy、Speaker 和 Talk 实体的各种 Activity 类、Speaker 和 Talk 的 RequestFactory 类以及各种 Place 类。

要为 GWT 项目设置 log4j 登录,请键入以下内容:

logging setup --level INFO

要退出 shell,请键入 qquit。这些命令最终创建了一个功能完善的 GWT 前端会议应用程序。

要运行这个应用程序,请从命令行转至 gwt 目录,然后键入 mvn gwt:run(启动 jetty 服务器并加载 GWT 部署模式)。要在默认的浏览器中打开这个应用程序,请单击 Launch Default Browser,也可以将此 URL 复制到剪贴板,然后在另一个浏览器中打开此应用程序。

此应用程序将在 http://127.0.0.1:8888/ApplicationScaffold.html?gwt.codesvr=127.0.0.1:9997 处运行。图 3 中所示的屏幕将会出现。单击 TalksSpeaker 来查看所有的会谈和发言人。

图 3. 运行 GWT 应用程序
在浏览器中运行的 GWT 应用程序

构建 Spring MVC 用户界面

本节将简要介绍如何为刚刚在本文中创建的这个域模型创建 Spring MVC Web 视图。在 Spring Roo 简介,第 1 部分:从源代码构建 中提及的 'controller all' 命令现已被弃用,不建议使用它。在开始使用新的命令之前,先来关注一下 mvc 模块。在 Roo shell 上键入以下命令:

module focus --moduleName view/mvc

Spring Roo 新的 setup 命令负责进行与设置 Spring MVC 应用程序相关的全部配置。现在,如果您想创建控制器,或者只是想设置控制器,那么需要提供一个控制器。要在应用程序中设置 Spring MVC,请键入以下内容:

view/mvc roo> web mvc setup

此命令的输出显示,此命令进行了与添加 Spring webmvc-config.xml context 文件相关的设置,添加了 Maven 依赖项和静态源文件,还添加了 Spring Roo 标签库。该命令并不会为实体创建视图。这一点对于不想为实体创建视图的人而言非常有用。您可以手动创建控制器并公开 RESTful Web 服务。

在完成了会议应用程序的基础设置之后,下一步就是为实体创建控制器和视图。键入以下命令:

view/mvc roo> web mvc all --package ~.web

web mvc all 命令为所有实体创建控制器和 jspx 视图。要想创建单个实体,请使用 web mvc scaffold 命令提供该实体的名称和控制器的完全限定名。清单 16 显示了其他很多 web mvc 命令。 Spring Roo 简介,第 2 部分:使用 Spring Roo 开发应用程序 介绍了其中的一些命令,这里就不再累述。

清单 16. web mvc 的帮助输出
view/mvc roo> help --command "web mvc" 
* web mvc all - Scaffold Spring MVC controllers for all project entities 
     without an existing controller 
     * web mvc controller - Create a new manual Controller (where you write the methods)
* web mvc embed document - Embed a document for your WEB MVC application 
* web mvc embed generic - Embed media by URL into your WEB MVC application 
* web mvc embed map - Embed a map for your WEB MVC application 
* web mvc embed photos - Embed a photo gallery for your WEB MVC application 
* web mvc embed stream video - Embed a video stream into your WEB MVC application 
* web mvc embed twitter - Embed twitter messages into your WEB MVC application 
* web mvc embed video - Embed a video for your WEB MVC application 
* web mvc embed wave - Embed Google wave integration for your WEB MVC application 
* web mvc finder add - Adds @RooWebFinder annotation to MVC controller type 
* web mvc finder all - Adds @RooWebFinder annotation to existing MVC controllers 
* web mvc install language - Install new internationalization bundle for MVC 
     scaffolded UI.
* web mvc install view - Create a new static view. 
* web mvc json add - Adds @RooJson annotation to target type 
* web mvc json all - Adds or creates MVC controllers annotated with @RooWebJson 
     annotation 
* web mvc json setup - Set up Spring MVC to support JSON 
* web mvc language - Install new internationalization bundle for MVC scaffolded UI. 
* web mvc scaffold - Create a new scaffold Controller (that is where Roo maintains CRUD 
     functionality automatically) 
* web mvc setup - Setup a basic project structure for a Spring MVC / JSP application 
* web mvc update tags - Replace an existing application tagx library with the latest 
     version (use --backup option to backup your application first) 
* web mvc view - Create a new static view.

部署到 Cloud Foundry

创建了会议应用程序后,自然要部署它了。无需做任何修改,即可将 Spring 应用程序部署到 Cloud Foundry 公共云。Spring Roo 简介,第 4 部分:用 Spring Roo 和 Cloud Foundry 在云中快速开发应用程序 详细介绍了 Cloud Foundry,包括如何使用 Spring Roo Cloud Foundry 附加组件从 Roo shell 部署 Spring Roo 应用程序。在版本 1.2.1 中,这一支持似乎遭到了破坏。因此,在本文中,我们会使用 vmc ruby gem 将此会议应用程序部署到 Cloud Foundry。具体步骤如下:

  1. 安装 vmc 客户端。有关 “Installing the Command-Line Interface (vmc)” 的分步教程,请参阅 参考资料
  2. 使用在 Cloud Foundry 注册的身份凭证登录 Cloud Foundry 公共云。键入 vmc login 命令,系统会要求您输入电子邮件和密码,如 清单 17 所示。
    清单 17. vmc login 的示例
    shekhar@shekhar:~/dev/conference/view/mvc/target$ vmc login 
    Attempting login to [http://api.cloudfoundry.com] 
    Email: shekhargulati84@gmail.com 
    Password: ************* 
    Successfully logged into [http://api.cloudfoundry.com]
  3. 安装了 vmc 客户端后,进行会议应用程序的完整 Maven 构建。为此,请键入以下内容:
    mvn clean install
  4. 构建项目后,将此会议应用程序推向 Cloud Foundry。在本文中,将会推送两个应用程序:一个是面向 Spring MVC,一个是面向 GWT。要想推送 Spring MVC 会议应用程序,请转到 conference/view/mvc/target 文件夹,并键入 vmc push,如 清单 18 所示。
    清单 18. 推送 Spring MVC 应用程序的示例
    shekhar@shekhar:~/dev/conference/view/mvc/target$ vmc push  
    Would you like to deploy from the current directory? [Yn]: Y 
    Application Name: mvcconference  
    Application Deployed URL [mvcconference.cloudfoundry.com]:  
    Detected a Java SpringSource Spring Application, is this correct? [Yn]: Y  
    Memory Reservation (64M, 128M, 256M, 512M, 1G) [512M]:  
    Creating Application: OK  
    Would you like to bind any services to 'mvcconference'? [yN]: N  
    Uploading Application:  
    Checking for available resources: OK  
    Processing resources: OK  
    Packing application: OK  
    Uploading (91K): OK  
    Push Status: OK  
    Staging Application: OK  
    Starting Application: OK

    Cloud Foundry vmc 客户端会询问应用程序的名称、应用程序的类型、要部署的 URL、内存保留以及是否要绑定任何服务,并会最终会上载该应用程序,将它部署到 Cloud Foundry。可以从 http://mvcconference.cloudfoundry.com/ 查看运行的这个 Spring MVC 应用程序。

  5. 将此 GWT 应用程序推送到 Cloud Foundry。请转到 conference/view/gwt/target 文件夹,并键入 vmc push,如 清单 19 所示。
清单 19. 推送 GWT 应用程序的示例
shekhar@shekhar:~/dev/conference/view/gwt/target$ vmc push 
Would you like to deploy from the current directory? [Yn]: Y 
Application Name: gwtconference 
Application Deployed URL [gwtconference.cloudfoundry.com]: 
Detected a Java SpringSource Spring Application, is this correct? [Yn]: Y 
Memory Reservation (64M, 128M, 256M, 512M) [512M]: 
Creating Application: OK 
Would you like to bind any services to 'gwtconference'? [yN]: N 
Uploading Application: 
  Checking for available resources: OK 
  Processing resources: OK 
  Packing application: OK 
  Uploading (5M): OK   
Push Status: OK 
Staging Application: OK                                                         
Starting Application: OK

查看在 http://gwtconference.cloudfoundry.com/ 上运行的应用程序。

下载会议应用程序的源代码


结束语

本文重新介绍了 Spring Roo。您了解了一些新特性,比如多模块 Maven 项目、Spring Roo 1.2 中引入的存储库层和服务层,之后使用 Roo 1.2 创建了一个融入了这些新特性的应用程序。此外,我们还了解了如何使用 Spring Roo 创建 GWT 应用程序。最后,我们将 Spring MVC 和 GWT 应用程序部署到 Cloud Foundry。本文中并未评论像 JSF 和 MongoDB 支持这类新特性。

本系列的 第 7 部分 将探讨如何使用 Spring Roo 创建 Spring MongoDB 应用程序并将它部署到 Cloud Foundry。


下载

描述名字大小
样例代码conference.zip340KB

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Open source, Java technology
ArticleID=841892
ArticleTitle=Spring Roo 简介,第 6 部分: 使用 Spring Roo 1.2 开发 Spring MVC 和 GWT 应用程序并将它们部署到 Cloud Foundry 上
publish-date=10222012