级别: 中级 John Hsu (johnhsu@tw.ibm.com), 软件工程师, IBM
2007 年 2 月 02 日 学习如何使用 Lotus Expeditor Toolkit 和 IBM Rational Application Developer V6 以编程方式将运行在 IBM Lotus Expeditor 上的 OSGi 服务作为 Web 服务公开。本文还展示了如何使用 Lotus Expeditor 运行时来部署并测试 OSGi 服务。
IBM Lotus Expeditor(即以前的 IBM WebSphere Everyplace Deployment)是一个客户机中间件框架和工具平台,它启用了连接、独立传递以及应用程序和服务管理。Lotus Expeditor 在 Open Service Gateway initiative (OSGi) 框架上进行构建并为客户机提供 J2EE 服务,例如 Web 服务和 Enterprise JavaBean (EJB),因此您可以将应用程序的关键组件移至客户机。Lotus Expeditor 还允许应用程序在本地执行大多数业务操作,因此即使是在没有网络连接的情况下,移动用户仍可以继续使用应用程序,并在网络连接可用时与服务器保持同步。
Lotus Expeditor 按照 JSR-172(J2ME Web 服务规范)来提供 Web 服务支持,同时提供 JSR-172 规范以外的特性。其中一个特性是 IBM WebSphere Web Services Gateway,此特性将 OSGi 服务映射到 Web 服务,反之亦然。因此通过使用 Java APIs for XML-based Remote Procedure Call (JAX-RPC),运行在 Lotus Expeditor 外部的应用程序可以调用运行在 Lotus Expeditor 上的 OSGi 服务。
Lotus Expeditor 提供了 Web Services Gateway Utility 来帮助用户通过富客户机用户接口将其 OSGi 服务作为 Web 服务公开。但是在某些情况下这不太方便。例如,当您开发应用程序并想将它分发给许多客户机时,显然您并不想告知每一个用户打开其 Web Services Gateway Utility 并手动公开服务。而是想以编程方式完成这些工作,本文将讲述如何开发简单的 OSGi 服务包,以及如何利用 Lotus Expeditor 所提供的开发工具包将这些服务作为 Web 服务公开。
先决条件
为了最大程度地掌握本文介绍的知识,您应熟悉 Java、J2EE、Web 服务、OSGi 框架以及如何利用 IBM Rational Application Developer V6 for WebSphere Software 或 Eclipse 3.x 进行插件开发。在进行以下步骤前,您必须安装 Rational Application Developer V6 或带有 Lotus Expeditor Toolkit V6.1 的 Eclipse 3.2。
您可以从 developerWorks 下载 Rational Application Developer V6 的试用版。
在本文中,将完成以下任务:
- 创建用来注册 OSGi 服务的 Client Services 项目。
- 将 OSGi 服务作为 Web 服务公开。
- 部署 Client Services 项目。
- 测试所部署的 Web 服务。
创建可以注册 OSGi 服务的 Client Services 项目
我们从创建可公开为 Web 服务的 OSGi 服务开始。在 Lotus Expeditor Toolkit 中,这是通过创建 Client Service 项目来实现的。本文假定您已经安装了 Rational Application Developer 和 Lotus Expeditor Toolkit。该工具包扩展了 Rational Application Developer 环境,并允许您构建基于 OSGi 的应用程序和基于 Eclipse 的应用程序。
在 Rational Application Developer 中按照以下步骤来创建 OSGi 服务,但是请记住如果已经安装了 Lotus Expeditor Toolkit,那么可以在 Eclipse 中进行同样的操作:
- 在 Rational Application Developer 中,选择 Window - Open Perspective - Plug-in Development,切换到 Plug-in Development 视图。
- 选择 File - New - Project。
- 在 New Project 向导中,选择 Client Services Project,然后单击 Next(参见图 1)。
图 1. New Project 向导
- 在 Client Service Project 面板的 Project name 字段中,键入 WSGateway,然后单击 Next。
- 在下一个向导面板中,接受默认值并单击 Finish。
- 创建了 Client Service 项目后,选择 File - New - Interface,然后输入接口名称 OSGiService 和包名称 wsgateway。Rational Application Developer 将创建 public interface OSGiService。清单 1 展示了接口代码。getResult 方法是一个测试方法。因为正在开发 OSGi 服务并将它作为 Web 服务公开,所以这两个服务至少需要一个 public 方法以供调用。
清单 1. OSGiService 接口
package wsgateway;
public interface OSGiService {
public String getResult();
} |
- 下一步,选择 File - New - Class,然后输入类 OSGiServiceImpl 和包名称 wsgateway。创建 OSGi 服务或 Web 服务时,一般的做法是创建接口和实现类。这是使您的代码更加灵活的最佳做法,但不是必需的做法。您可以创建类并将其注册为 OSGi 服务和 Web 服务。在 Lotus Expeditor Toolkit 中没有禁止进行上述操作,但是我们不推荐这种做法。清单 2 展示了实现类。
清单 2. OSGiServiceImpl 类
package wsgateway;
public class OSGiServiceImpl implements OSGiService {
public String getResult() {
return "This is OSGiServiceImpl";
}
} |
- 将清单 3 中的代码添加到 Activator.java 的 start()中,以便注册 OSGi 框架的 OSGiService:
清单 3. Activator.java
public void start(BundleContext context) throws Exception {
super.start(context);
Hashtable properties = new Hashtable(7);
properties.put(Constants.SERVICE_PID, wsgateway.OSGiService.class.getName());
context.registerService(wsgateway.OSGiService.class.getName(), new OSGiServiceImpl(),_
|--10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error: The previous line is longer than the max of 90 characters ---------|
properties);
} |
- 然后可以运行 Client Services 项目来确定它是否能够将服务注册到 OSGi 框架。在 Rational Application Developer 中选择 Run - Run。
- 在 Run 对话框中,选择 Client Services,然后单击 New。
- 选择 Plug-ins 附签,取消选中 Workspace Plug-ins,并选择 WSGateway(参见图 2)。
- 单击 Add Required Plug-ins 按钮,然后单击 Run。
图 2. Run 对话框的 Plug-ins 附签
- 选择 Console 附签,然后输入 ss 并找到 WSGateway 的 bundle 号(参见图 3)。
图 3. Console
- 找到 WSGateway bundle 号后,在控制台中输入 start xxx,其中 xxx 是 WSGateway 的 bundle 号。
- 然后在控制台中输入 s,并确保将 wsgateway.OSGiService 注册到 OSGi 框架(参见图 4)。
图 4. 显示 wsgateway.OSGiService 的控制台

 |

|
将 OSGi 服务作为 Web 服务公开
创建了 OSGi 服务并使用 OSGi 框架对其进行成功注册后,可以将 OSGi 服务作为 Web 服务公开。将清单 4 中的代码添加到 Activator.java 的 start() 方法中:
清单 4. Activator.java
public void start(BundleContext context) throws Exception {
super.start(context);
Hashtable properties = new Hashtable(7);
WebServiceProvider provider;
String providerName = "com.ibm.pvcws.osgi.proxy.WebServiceProvider";
ServiceReference ref = context.getServiceReference(providerName);
provider = (ref == null) ? null : (WebServiceProvider)context.getService(ref);
properties.put(Constants.SERVICE_PID, wsgateway.OSGiService.class.getName());
context.registerService( wsgateway.OSGiService.class.getName(), new OSGiServiceImpl(),_
properties);
/* provider.exportPid(wsgateway.OSGiService.class.getName());
System.out.println(wsgateway.OSGiService.class.getName() + " exposed as a Web Service at_
http://localhost:8777/ws/pid/" + wsgateway.OSGiService.class.getName());*/
ref = context.getServiceReference (wsgateway.OSGiService.class.getName());
String sid = ref.getProperty("service.id").toString();
provider.exportSid(sid);
System.out.println(wsgateway.OSGiService.class.getName() + "
exposed as Web Service at http://localhost:8777/ws/sid/" + sid);
} |
请注意有两种方法用于将 OSGi 服务作为 Web 服务公开:service sid 或 pid。上述清单中的粗体代码是两种方法的共有代码,以 ref = context.getServiceReference (wsgateway.OSGiService.class.getName()); 开头的最后几行代码用于 sid 方法。注释的代码用于 pid 方法。
导入 Activator.java 中的 com.ibm.pvcws.service.WebServiceProvider,然后打开 META-INF 文件夹下的 MANIFEST.MF,并切换到 Dependencies 附签(参见图 5)。
图 5. Dependencies 附签
在 Required Plug-ins 部分中,单击 Add 按钮。在 Plug-in Selection 对话框的 Select a Plug-in 字段中输入 com.ibm.pvcws.osgi,然后单击 OK。
部署 Client Services 项目
为了使 OSGi 服务成为 Web 服务,您已经添加了所需代码和配置。现在需要将 Client Services 项目部署到 Lotus Expeditor 运行时(常见的 J2SE 应用程序需要使用 java.exe 来运行,而大多数 J2EE 应用程序必须部署到 J2EE 应用服务器。在本文中,我们将 J2EE 应用程序部署到 Lotus Expeditor 运行时,Lotus Expeditor 运行时提供了一些 J2EE 应用服务器功能)。
按照以下步骤来部署 Client Services 项目:
- 重复执行上述“创建可以注册 OSGi 服务的 Client Services 项目”一节中的步骤 9 到步骤 13(因为已经进行了配置,所以跳过步骤 10)。在步骤 11 中,选择 Arguments 附签并将 -Dcom.ibm.pvc.webcontainer.port=0 更改为 -Dcom.ibm.pvc.webcontainer.port=8777(参见图 6)。
图 6. Arguments 附签
- 在控制台中,找到 com.ibm.pvcws.osgi 和 org.eclipse.equinox.http,然后启动它们。
- 还是在控制台中,找到 WSGateway,然后启动它。
- 打开 Web 浏览器,并输入控制台中所示的 URL。如果成功执行的话,应看到 Web 服务描述语言(Web Services Description Language,WSDL)(参见图 7)。
图 7. Web 浏览器中的 WSDL
测试所部署的 Web 服务
部署了 Web 服务之后,您一定想确保自己进行了成功操作。Lotus Expeditor Toolkit 为此提供了一个简单的方法。只要有 WSDL 文件,Lotus Expeditor Toolkit 就可以对它进行分析并按照 JSR 172 生成必需的 stub 代码,然后您可以使用这些 stub 来测试 Web 服务。
按照以下步骤来测试所部署的 Web 服务:
- 重复执行上述“创建可以注册 OSGi 服务的 Client Services 项目”部分中的步骤 1 到步骤 5,创建项目名为 WSGatewayClient 的另一个 Client Services 项目。
- 选择 File - New - Other。
- 选择 Client Services - Mobile Web Services - Mobile Web Services Client,然后单击 Next(参见图 8)。
图 8. New 向导
- 在 Mobile Web Service Client 对话框中指定以下字段值(参见图 9):
- Source folder 指定为:/WSGatewayClient/src
- Package 指定为:wsgatewayclient
- WSDL location 指定为: http://localhost:8777/ws/pid/wsgateway.OSGiService
图 9. Mobile Web Services Client 对话框
- 单击 Next,然后单击 Finish。
- 在 WSGatewayClient 内的 Activator.java 的 consumeService() 中,添加清单 5 中的代码。此代码将调用由 Lotus Expeditor Toolkit 生成的 stub。
清单 5. consumeService()
private void consumeService() throws Exception {
wsgatewayclient.OSGiServiceSoap_Stub stub = new wsgatewayclient.OSGiServiceSoap_Stub();
|--10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error: The previous line is longer than the max of 90 characters ---------|
System.out.println(stub.getResult());
} |
- 请确保 WSGateway 服务使用 pid 方法来公开 Web 服务。如果使用 sid 方法,则必须确保在创建客户机时,WSDL URL 中的 sid 编号是正确的,因为如果添加 -clean 作为程序参数,则 sid 编号可能会更改。
- 停止在上述部分中启动的 Lotus Expeditor 运行时,然后重复执行“部署 Client Services 项目”一节中的步骤 1 到步骤 3 来再次运行 Lotus Expeditor 运行时,在步骤 1 中选择 WSGateway 和 WSGatewayClient。
- 键入 ss 来找到 WSGatewayClient 的 bundle ID 并启动它。在 console 附签上可以看到打印出的结果(参见图 10)。
图 10. Console

 |

|
结束语
本文展示了如何使用安装在 Rational Application Developer 上的 Lotus Expeditor Toolkit 以编程方式将运行在 Lotus Expeditor 上的 OSGi 服务作为 Web 服务公开。虽然您可以在单个客户机上使用 GUI 工具来实现上述任务,但是编程方式对自动执行大量安装操作或更新多个客户机上的此类服务有很大的帮助。此特性还有助于将运行在 Lotus Expeditor 上的每一个服务作为 Web 服务公开,因此可以从 Lotus Expeditor 的外部调用这些服务。这意味着 Lotus Expeditor 提供了与其它应用程序间的很好的互操作性 —— 这也是 Lotus Expeditor 之所以能够成为一种很好的用以构建面向服务架构解决方案的框架的原因之一。
参考资料
关于作者  | |  | John Hsu 是中国台北 IBM China Software Development Lab 的软件工程师。John 拥有软件开发和测试方面的经验,最近正在从事 Lotus Expeditor 开发方面的工作。 |
对本文的评价
|