在 SpringSource dm Server 中部署 GWT 应用程序 - 第 1 部分

工程 | Ben Corrie | 2008年11月7日 | ...

简介

这将是一个由 3 篇博客组成的系列,描述在 SpringSource dm Server™ 中构建和部署 GWT 应用程序的分步方法。这些博客的重点如下
  1. 使用 SpringSource Tool Suite 从头开始构建 GWT StockWatcher 示例应用程序作为 WAR 文件部署到 dm Server 中。
  2. 使用 “共享库” 方法部署:如何从 WAR 中移除 GWT 依赖项并将其作为 OSGi 捆绑包部署到 dm Server 中。
  3. 使用 “共享服务” 方法部署:我们将单个 WAR 文件转换为可由其他应用程序共享和热交换的 OSGi 服务。
值得注意的是,在这些前两篇博客中,我并没有在任何地方使用 Spring Framework。Spring 和 GWT 之间的集成本身就是一个主题,我想尽可能地使每篇博客都保持专注。在第三篇博客中,我将展示如何使用 Spring 发布和使用 OSGi 服务,以及如何将其与 GWT 集成。

背景

该博客将采用一种实用的分步方法来构建 此处 描述的 GWT StockWatcher 示例。Google 教程将引导您完成使用 RPC 从头开始构建 GWT 示例所需的步骤。在进行过程中,我将参考教程中的页面,并讨论各种方法的优缺点。

该博客假设您已安装 SpringSource Tool Suite 1.1.1(我使用的是 Eclipse 3.4 版本)、dm Server 1.0.0GWT 1.5。它还假设您对 Java 编程有很好的理解,并对 Javascript 和 Ajax 有基本的了解。

出于演示中使用的路径的目的,我在以下位置创建了一个新的 Eclipse 工作区:/Users/bcorrie/gwt/workspace。我已经包含了您可以下载的压缩项目,其中包含一个GWT_ROOT_INSTALL变量,我已经定义了它。要使用我的项目,当您导入它们时,导航到“首选项”->“Java”->“构建路径”->“类路径变量”,并定义您自己的GWT_ROOT_INSTALL.

步骤 1:创建一个新的 GWT 项目

目前,创建 GWT Eclipse 项目最简单的方法是使用 GWT 发行版提供的命令行工具projectCreatorapplicationCreator,以及-eclipse参数,如 此处 所述。这些命令行工具创建一个简单的 Java 项目、框架项目文件、一个在托管模式下运行项目的运行配置,以及在 Eclipse 外部运行或编译项目的脚本。

这些工具的一个限制是它们对源代码的存放位置具有规定性。您的源代码必须位于名为/src的项目子目录中,您的客户端代码必须位于以client结尾的包中,您的服务器代码必须位于以server结尾的包中。projectCreatorapplicationCreator无法配置为执行其他操作,因为这通常是GWTShellGWTCompiler期望您的代码所在的位置。稍后,我们将了解一些重组源代码和调整运行配置以使其更灵活的方法。

在命令行上创建项目后,将其导入 STS。

使用“导入”->“常规”->“将现有项目导入工作区”。

步骤 2:完成 Google 教程并开发 Java 源代码

确保您继续完成 “基础知识”,并继续解决 “使用远程过程调用” 部分。有关远程过程调用的部分将确保您在 Web 服务器上运行股票价格更新代码,该代码将每 5 秒动态更新网页一次。这展示了 Ajax 功能和 GWT 以 Java 代码抽象该行为的方式的简单而强大的演示。您最终将获得一个看起来像这样的项目

如果您不想完成开发示例代码的过程,可以 此处 下载我的初始项目的压缩副本。要使用我的项目运行,您需要执行以下步骤

- 解压缩并导入项目(“导入”->“将现有项目导入工作区”)- 定义一个GWT_ROOT_INSTALL变量,如上文背景中所述 - 修改StockWatcher GWTShell.launch包含的运行配置,或使用以下值创建一个新的运行配置

- 右键单击 StockWatcher 项目 ->“以...方式运行”->“运行配置”- 对于“主类”,输入com.google.gwt.dev.GWTShell- 在“程序参数”中,输入-out www com.google.gwt.sample.stockwatcher.StockWatcher/StockWatcher.html- 仅在 Mac OS X 上,在“VM 参数”中,输入-XstartOnFirstThread- 在“类路径”->“用户条目”中

- 添加gwt-dev-<os>.jar(例如gwt-dev-mac.jar)- 添加 StockWatcher 项目/src文件夹,使用“高级”->“添加文件夹”。

请注意,将/src文件夹添加到类路径是 GWTShell 的一项要求,因为它需要在 Java 类路径上具有元数据,例如其 .xml 文件。

步骤 3:在托管模式下运行 - 检查它是否有效!

托管模式允许您在 GWT 应用程序的“预编译”Java 状态下运行和调试它,然后再部署。 此处 阅读有关托管模式的信息。重要的是要记住,StockWatcher 应用程序的客户端类最终将被编译成 javascript 和 html 以部署到客户端,而服务器类将在服务器上作为普通的 Java 代码运行。令人困惑的是,一些客户端代码在服务器上用作支持类,在客户端用作编译后的 javascript。当我们稍后开始拆分项目时,这一点会变得更加清晰。

单击选定的 StockWatcher 项目的“运行”按钮,或选择在步骤 2 中创建的运行配置。

另请注意,当您在托管模式下运行时,GWTShell创建一个/www输出文件夹到您的项目以及一个/tomcat文件夹来配置嵌入式 Tomcat。测试后,如果您刷新 StockWatcher 项目,您将看到这些文件夹。

步骤 4:创建一个新的动态 Web 项目

要创建 WAR 文件,我们需要一个动态 Web 项目……但我们已经有了一个 Java 项目!那么管理此需求的最明智方法是什么?Google 建议将编译后的代码生成到 Eclipse Java 项目中,然后将 GWT 编译器和生成的 .class 文件的输出剪切粘贴到单独的 WAR 项目中。我更倾向于将 GWT 编译器设置为将部署的代码直接构建到 WAR 项目中,并将源代码拆分到这两个项目中,以便客户端代码位于 Java 项目中,而服务器代码位于 WAR 项目中。

那么为什么不只是将所有内容复制到 WAR 项目中并从那里运行呢?好吧,我认为将两个单独的项目分开有很多原因

首先,您不希望托管模式将/www/tomcat文件夹生成到 WAR 项目中。

其次,将 javascript 和 html 从托管模式项目生成到 WAR 项目中具有使两个项目都更干净和分离关注点的优势。它消除了生成的代码的重复,这会导致版本控制混乱,尤其是在生成的代码被混淆的情况下。

第三,如步骤 1 中所述,GWTShellGWTCompiler规定您的源代码必须位于名为/src的子目录中。这限制了 WAR 项目与 Maven 和 Ant 等工具的集成。

最后,它允许 Java 代码也分离,以便您不会将冗余的客户端代码复制到 WAR 文件中。

虽然这看起来像是多余的额外工作,但随着我们继续采用不同的方法,您将看到在早期拆分代码如何使以后将其部署为共享服务变得更容易。

因此,让我们创建一个新的动态 Web 项目,并同时创建一个 dm Server 的服务器实例。

如果您在工作区中还没有 dm Server 实例,则需要点击“目标运行时”文本字段旁边的“新建”按钮,然后选择“创建新的本地服务器”。请注意,我还选择了src/main/javasrc/main/webapp分别作为“Java 源代码目录”和“内容目录”。您可以使用默认值,但建议使用这些路径,因为它们与 Maven 等构建工具很好地集成。

接下来,我们将 Java 代码拆分到这两个项目之间

请注意,如果您只是将 GWT 代码导出为普通的 WAR 文件,则此代码划分不是必需的。实现此目的最简单的方法是将您的 Java 项目创建为 WAR 项目的 Java EE 依赖项,Eclipse 将把您的 Java 项目转换为 JAR 文件,并将其添加到 WAR 中的 WEB-INF/lib 目录下。但是,这种方法的问题在于,您将冗余的客户端代码打包到 WAR 中,并且这使得以后将应用程序拆分为服务变得更加困难。

因此,我们的项目中有 3 种类型的 Java 代码:仅编译为 javascript 和 html 的代码、仅在服务器端使用的代码以及同时支持这两种用途的代码。将后两种类型的代码移到我们的 WAR 项目中是有意义的。将我们的“通用”类(客户端和服务器都使用的类)放在一个单独的包中也是有意义的(同样,对此的需求将在博客 3 中变得更加清晰),我们将称之为com...client.api。最后,GWT 要求我们的 Async 接口与 RemoteService 接口位于同一个包中,因此将其重构到com...client.api包中。完成后,它应该如下所示

分解代码所需的最后一件事是将 StockWatcherWar 项目添加到 StockWatcher 项目的构建路径中,以便它可以访问其中的类com...client.api包(属性 -> Java 构建路径 -> 项目 -> 添加...)。

如果您愿意,可以通过下载我的两个已完成项目的 zip 文件以及各种运行配置来跳过所有这些繁琐的工作,此处(有关导入和设置的说明,请参阅步骤 2 和背景)。如果您有一个干净的工作区,则需要创建一个 dm Server 运行时实例(新建 -> 服务器 -> SpringSource ...),并且您可能需要为 WAR 项目在“属性” -> “目标运行时”中选择服务器运行时,因为它可能与我的不匹配。

步骤 5:配置 GWTCompiler 将客户端代码生成到 WAR 项目中

我们需要设置 GWT 编译器,以便将 StockWatcher 项目中的代码生成到 StockWatcherWar 项目中。这与步骤 2 中设置 GWTShell 的过程几乎相同。修改StockWatcher GWTCompiler.launch项目 zip 文件中包含的脚本(在步骤 4 中),或使用以下值创建一个新的脚本

- 右键单击 StockWatcher 项目 -> “以...运行” -> “运行配置”,并创建一个新的配置 - 对于“主类”,输入com.google.gwt.dev.GWTCompiler- 在“程序参数”中,输入-out <您的工作区路径>/StockWatcherWar/src/main/webapp com.google.gwt.sample.stockwatcher.StockWatcher- 仅在 Mac OS X 上,在“VM 参数”中,输入-XstartOnFirstThread- 在“类路径”->“用户条目”中

- 添加gwt-dev-<os>.jar(例如gwt-dev-mac.jar)- 添加 StockWatcher 项目/src文件夹和 StockWatcherWar/src/main/java文件夹,使用“高级”->“添加文件夹”。

请注意,将源文件夹添加到类路径是 Google 编译器的要求。

现在,运行您刚刚创建的编译器配置并刷新 StockWatcherWar 项目以查看生成的 文件。您应该会看到如下内容

步骤 6:配置 WAR 项目

您会注意到 Google 编译器将输出生成到 2 个文件夹中,这些文件夹反映了 GWT 项目的名称。编译器假设目标文件夹与源文件夹相同,并且无法取消配置此设置,因此您必须将生成的文件拖到src/main/webapp文件夹中,然后删除这两个 Google 目录。这实际上是 Google 自己建议您执行的操作 此处

接下来,我们需要将所需的依赖项添加到我们的项目中。

- 添加 Web 模块依赖项gwt-servlet.jar(“属性” -> “Java EE 模块依赖项” -> “添加外部 JAR”)。请注意,此模块依赖于javax.servletAPI。- 修改web.xml文件,按照 Google 的说明操作。也值得添加StockWatcher.html<welcome-file-list>以便它在部署时自动显示(尽管在 Eclipse 中部署时这并不总是有效,因为浏览器窗口通常在服务器完全初始化之前打开)。

如果您遇到问题,请查看步骤 4 中我的压缩项目。

步骤 7:部署到 STS 中的 dm Server

现在我们已经创建了新的 WAR 项目,让我们将其部署到 STS 中的 dm Server。只需右键单击 StockWatcherWar 项目,然后选择“以...运行” -> “在服务器上运行”。如果欢迎页面没有自动显示,请刷新页面或手动将/StockWatcher.html添加到 URL 中。

成功运行 WAR 项目后,您可以将托管模式配置为使用 dm Server 作为其服务器,而不是其嵌入式 Tomcat。为此,您只需修改GWTShell的运行配置,并将程序参数更改为-noserver -out www https://127.0.0.1:8080/StockWatcherWar/。这使您可以快速测试客户端更改。服务器端更改会自动重新部署到正在运行的服务器上。不错!

需要说明的是,如果您想在嵌入式 Tomcat 托管模式下使用我提倡的设置运行,则需要暂时取消选择 WAR 项目属性中的 dm Server 作为目标运行时。这是因为将 StockWatcherWar 添加到 StockWatcher 的构建路径也会引入 dm Server 运行时包(例如javax.servlet),这会弄乱GWTShell.

的构建路径。假设这成功了,现在让我们打包我们的 WAR 并将其部署到工具之外。

步骤 8:导出并在 STS 外部部署

首先,我们需要将项目导出为 WAR 文件。这可以通过右键单击 StockWatcherWar -> “导出” -> “Web” -> “WAR 文件”来实现。如果您想知道“覆盖现有文件”复选框在哪里,那是因为似乎存在一个 Eclipse 错误,该错误会将其隐藏,直到您调整 WAR 导出对话框的大小。您可以下载我导出的 WAR 此处(请注意,它是压缩的)。

导出 WAR 后,我们需要在 STS 外部启动 dm Server。

首先,确保 STS dm Server 已停止,否则它们将在端口上发生冲突。然后,在命令行上,运行 dm Server 启动脚本。在我的情况下,这是bin/startup.sh。您可以添加-clean选项以确保您从干净的设置开始。您应该会看到以下消息

[2008-10-27 14:14:44.468] server-dm-10             <SPPM0002I> 服务器已开放,使用配置文件“web”。

成功启动后,在 Web 浏览器中打开管理控制台,使用以下 URL

https://127.0.0.1:8080/admin/web/applications/list.htm

默认用户名是admin密码是springsource。有关运行和配置 dm Server 的更多详细信息,请参阅用户指南

您现在应该会看到以下内容

在“应用程序位置”文本字段中浏览您导出的 WAR 文件,然后单击上传。这将上传并部署 WAR 文件,然后该文件应出现在“已部署的应用程序”中

在终端输出中,您应该会看到以下消息

[2008-10-27 14:07:44.380] server-tomcat-thread-5   <SPSC1000I> 创建 Web 应用程序“/StockWatcherWar”。[2008-10-27 14:07:44.396] async-delivery-thread-1  <SPSC1001I> 启动 Web 应用程序“/StockWatcherWar”。[2008-10-27 14:07:44.684] server-tomcat-thread-5   <SPDE0010I> “StockWatcherWar.war”版本“0”的部署已完成。

最后,剩下的就是单击/StockWatcherWar上面显示的链接,您现在正在使用您的 GWT 应用程序!

期待第 2 部分

在下一个博客中,我们将了解如何利用 dm Server 的 OSGi 功能将 GWT 依赖项从 WAR 中提取出来,并将它们转换为可以由服务器上运行的所有 GWT 应用程序共享的捆绑包。我们还将简要了解一下底层,看看我们的 OSGi 捆绑包是如何交互的。

获取 Spring 新闻通讯

与 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,以加速您的进步。

了解更多

获取支持

Tanzu Spring 在一个简单的订阅中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部