让你的RCP应用程序运行在B/S架构上 收藏在此贴上我发表在2008年10月份《程序员》杂志的一篇技术文章。
在Web2.0大行其道的今天,有很多桌面应用程序已经运行到浏览器上面,这其中有Microsoft Office Live, Google Docs等等。自从Eclipse 3.0引入Rich Client Platform(后面简称RCP)以来,RCP应用程序得到了广泛的应用,自然,人们期望RCP应用程序也能够运行在浏览器上面,尽管这是一个挑战,但总是有人能挑战成功,Eclipse下面的子项目Rich Ajax Platform(后面简称RAP)就做到了,这篇文章就是告诉你如何用RAP将你的RCP应用程序移植到B/S架构上。
前提 l 熟悉Java语言 l 熟悉Eclipse IDE和RCP应用程序开发 l 机器上安装了Eclipse 3.3 或者 Eclipse 3.4
RAP简介 RAP使得开发人员只需要做很少的修改就可以将RCP应用程序移植到B/S架构,开发人员甚至不需要了解Web应用程序开发技术,他(她)依然可以用Eclipse开发模式来开发RCP应用程序,依然可以利用扩展点机制来扩展RCP的Workbench,依然可以使用SWT(Standard Widget Toolkit), JFace来构建用户界面, 然后再做一点修改,请相信我,确实只需要做一点修改,就可以将RCP应用程序变成一个具有Ajax特性的Web应用程序。以下是RCP应用程序和RAP应用程序的架构对比图,RAP基于Ajax框架qooxdoo 做了一个特殊的SWT实现,目前只实现了SWT的一个子集,叫做RWT(RAP Widget Toolkit), 以此来构建用户再浏览器里面看到的界面,另一边,RAP将OSGi R4核心框架的实现Equinox作为RAP应用程序的服务器端,是的,RAP需要把Equinox嵌入Servlet Container。
图1 —— RCP应用程序和RAP应用程序的架构对比(出自Eclipse网站)
安装RAP 像安装其他Eclipse插件一样, 你可以用Eclipse自带的软件安装界面来安装RAP, RAP的update site是http://download./technology/rap/update-site ,装完之后,你还需要去RAP的网站http://www./rap/downloads 下载一个RAP的目标平台,假设你将其下载并解压到c:\rap\eclipse目录,由于RAP和RCP不能同时存在于Eclipse IDE里面,(为什么不能?因为这两者有太多同名的 Java class, RAP的RWT的类名跟RCP的SWT的类名一样), 所以你需要修改Eclipse的目标平台,使其指向RAP目标平台, 点击Window > Preferences... > Plug-in Development > Target Platform, 将Location设置为c:\rap\eclipse,并点击Reload按钮将RAP目标平台的插件加载进来,如图2所示
图2 ——修改Eclipse的目标平台为RAP
好了,到此你把环境准备好了,下面将要介绍如何将RCP程序运行在B/S架构上,正如你猜到的,下面介绍的其实就是如何将一个RCP应用程序转换成RAP应用程序,首先,你需要创建一个RCP应用程序。
创建一个模板RCP应用程序 你可以自己创建一个很简单的Hello World RCP应用程序,也可以复杂一点,比如加一个树控件,弄一些菜单进来。但是我建议用Eclipse自带的RCP模板应用程序,既然Eclipse自带了,而且这样也可以节省不少时间,那为什么不用呢? 点击File->New->Project…, 选择Plug-in Project, 点击Next按钮,为这个将要导入的RCP样本应用程序取名,然后点击Next按钮,在此,将Would you like to create a rich client application设置为Yes,如图3所示,这样在下一页就能看到Eclipse自带的RCP模板应用程序了。
图3——设置Rich Client Application
再次点击Next按钮,选择RCP Mail Template,如图4所示,点击Finish按钮,这样你就得到了一个比较复杂的RCP应用程序了。
图4——选择RCP Mail Template
转换RCP应用程序为RAP应用程序 为了让上面的RCP应用程序运行在B/S架构上,需要将其转换为RAP应用程序。下面分三步修改这个RCP应用程序,使其转换成RAP应用程序。 第一步:修改MANIFEST.MF文件。用Plug-in Manifest Editor打开plugin.xml或者META-INF/MANIFEST.MF文件,切换到Dependencies选项页,在Required Plug-ins列表里面,将里面二个条目org.eclipse.ui和org.eclipse.core.runtime全删掉,增加一个新的条目org.eclipse.rap.ui。插件org.eclipse.rap.ui包含了插件org.eclipse.ui中的绝大多数类和扩展点,而且全名(full qualified name)是一样的。这样可以确保依赖插件org.eclipse.ui的RCP应用程序能够在几乎不做修改的情况下跑在RAP平台中。以下是修改前和修改后的MANIFEST.MF文件,以供对比。
清单1——修改前的MANIFEST.MF文件 Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Mail Plug-in Bundle-SymbolicName: mail; singleton:=true Bundle-Version: 1.0.0 Bundle-Activator: mail.Activator Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime Eclipse-LazyStart: true
清单2——修改后的MANIFEST.MF文件 Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Mail Plug-in Bundle-SymbolicName: mail; singleton:=true Bundle-Version: 1.0.0 Bundle-Activator: mail.Activator Require-Bundle: org.eclipse.rap.ui Eclipse-LazyStart: true
第二步:修改入口程序。由于RCP应用程序的入口是实现了接口org.eclipse.equinox.app.IApplication的类,在这个RCP模板应用程序里,这个类是mail.Application,为了让Eclipse知道这个类就是RCP应用程序的运行入口点,还需要用如清单3所示的扩展点注册该类。
清单3——RCP应用程序入口注册 <extension id="application" point="org.eclipse.core.runtime.applications"> <application> <run class="mail.Application"> </run> </application> </extension>
RAP应用程序的入口是实现了接口org.eclipse.rwt.lifecycle.IEntryPoint的类,所以你需要将mail.Application修改成如清单4所示的样子,剩下的界面相关的类ApplicationWorkbenchAdvisor,ApplicationWorkbenchWindowAdvisor,Perspective,View都不需要做修改(请注意这里没有包括类ApplicationActionBarAdvisor,后面会对其做一点微小的修改)。
清单4——RAP应用程序入口点 public class Application implements IEntryPoint { public int createUI() { Display display = PlatformUI.createDisplay(); return PlatformUI.createAndRunWorkbench( display, new ApplicationWorkbenchAdvisor()); } }
同时,你需要删除清单3所示的扩展,同样,为了让RAP运行环境知道修改后的mail.Application是RAP应用程序运行入口点,你还需要用如清单5所示的扩展点注册该类
清单5——RAP应用程序入口注册 <extension point="org.eclipse.rap.ui.entrypoint"> <entrypoint class="mail.Application" id="mail.Application" parameter="rapMail"> </entrypoint> </extension>
上面的parameter可以为任意值,只要没有被其他的RAP应用程序用过,后面你运行RAP应用程序的时候会用到parameter。
第三步:修改其他有编译错误的地方。剩下还有二个地方出现错误,一个是plugin.xml中的扩展org.eclipse.ui.bindings,这个只是将快捷键绑定到菜单的扩展点,而且目前在RAP中不被支持,你可以将其注释掉或干脆删掉。另外一个是类ApplicationActionBarAdvisor,由于目前RAP目标平台中的的类ActionFactory没有ABOUT成员,为简单起见,直接将makeActions方法中的两条相关语句注释掉,同时,将fillMenuBar方法中的最后一条语句注释掉,清单6是修改后的ApplicationActionBarAdvisor类
清单6——修改后的ApplicationActionBarAdvisor protected void makeActions(final IWorkbenchWindow window) { exitAction = ActionFactory.QUIT.create(window); register(exitAction); // aboutAction = ActionFactory.ABOUT.create(window); // register(aboutAction); newWindowAction = ActionFactory.OPEN_NEW_WINDOW.create(window); register(newWindowAction); openViewAction = new OpenViewAction(window, "Open Another Message View", View.ID); register(openViewAction); messagePopupAction = new MessagePopupAction("Open Message", window); register(messagePopupAction); }
protected void fillMenuBar(IMenuManager menuBar) { MenuManager fileMenu = new MenuManager("&File", IWorkbenchActionConstants.M_FILE); MenuManager helpMenu = new MenuManager("&Help", IWorkbenchActionConstants.M_HELP); menuBar.add(fileMenu); // Add a group marker indicating where action set menus will appear. menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); menuBar.add(helpMenu); // File fileMenu.add(newWindowAction); fileMenu.add(new Separator()); fileMenu.add(messagePopupAction); fileMenu.add(openViewAction); fileMenu.add(new Separator()); fileMenu.add(exitAction); // Help // helpMenu.add(aboutAction); } 好了,到此大功告成了,确实只需要很少的修改,不是吗?下面就是让其运行起来
运行RAP应用程序 打开运行配置对话框,创建一个RAP Application运行配置,将Entry Point设为清单5里面parameter属性的值,如图5所示
图5——RAP应用程序的运行配置
在Eclipse IDE里面运行后,如图6所示
图6——运行中的RAP应用程序
你可以比较一下图7所示的RCP应用程序,形似而且神似。
图7——运行中的RCP应用程序
部署 现在只是在Eclipse IDE里面将转换后的RAP程序跑起来了,你当然不想让RAP只在Eclipse IDE运行,你肯定会想要将其部署在自己的Web应用服务器里面,我也是这么想的。这需要我们将RAP应用程序做成一个WAR包,但可惜现阶段Eclipse还没有提供向导和工具来将RAP应用程序做成WAR包,我们不得不手工来做这件事情L。以下网页介绍了如何来手工打包RAP应用程序,不再赘述。 http://help./ganymede/index.jsp?topic=/org.eclipse.rap.help/help/html/advanced/deployment.html
结束语 RAP让开发人员只需做很小的修改就可以将手边已有的RCP应用程序跑在浏览器里面,只是现阶段看起来部署比修改麻烦。 但对于那些想将遗留RCP应用程序迁移到B/S架构的开发人员或者独立软件开发商,RAP不啻是一种性价比很高的解决方案。 |
|