通过 WebSphere Process Server 和 WebSphere Integration Developer 方便地使用 Java 构件

本文向您介绍 IBM® WebSphere® Process Server 和 IBM WebSphere Integration Developer 最新版本中的新功能,该功能可以大幅度地减少使用 SCA 组件中现有 Java™ 构件所需的工作。 本文来自于 IBM WebSphere Developer Technical Journal

Peter Xu (peteryxu@us.ibm.com), 高级管理顾问, EMC

Peter Xu 是 IBM Software Services for WebSphere 的一位高级管理顾问。



2007 年 7 月 19 日

问题

WebSphere Process Server 是基于服务组件体系结构 (SCA) 和服务数据对象 (SDO) 或业务对象 (BO) 创建和集成服务的平台。在大多数的情况下,在 IBM WebSphere Integration Developer 中使用服务组件、导出和导入时,将会处理与 XML 模式定义(XML Schema Definitions,XSD)组合的 Web 服务描述语言(Web Services Definition Language,WSDL)接口。我将这种类型称为 W 类型的服务。同时,在使用 SCA 和 SDO 之前,已经使用纯 Java 接口和 Java Bean 创建了许多资产和服务。我们将这种类型称为 J 类型的服务。

显然,我们不希望使用新的 SCA 和 SDO 编程模型从头创建所有的服务。相反,我们希望尽可能多地重用 SCA 组件中现有的、基于 Java 的资产。示例是需要调用会话 EJB 的 SCA 组件。此调用需要在 WSDL 类型和 Java 类型之间进行转换。不过,您不能将引用类型为 WSDL 的组件直接连接到具有 Java 接口的另一个组件。这里似乎存在一个缺陷。

版本 6.0.2 之前

在推出 WebSphere Process Server 和 WebSphere Integration Developer 的 6.0.2 版本之前,开发人员主要使用以下两种方法来处理此问题:

  1. 直接的解决方案就是编写 SCA 到 Java 的桥接。这需要手动创建中间 POJO(介绍的 WSDL 端口类型),它可以引用 J 类型的组件。但是您需要手动创建 WSDL 本身和对应于 Java Bean 参数的 BO。最重要和最耗时的一部分工作是反复编写 Java Bean 和数据对象的映射代码。

    此方法的问题是需要太多的手动步骤和自定义代码,这很容易出错。

  2. 另一种方法是利用 WebSphere Integration Developer 中的工具将现有 Java/EJB 资产公开为 Web 服务,这将自动获得 WSDL 接口。获得 SOAP Web 服务接口后,将其与 SCA 组件集成就非常容易了。

    此方法需要的手动步骤比其他方法少,但是将所有 Java 资产转换为 Web 服务可能不是一个实际的解决方案;这还会带来其他性能开销。

改进措拖

上述两种方法都不令人十分满意。幸运的是,WebSphere Process Server 和 WebSphere Integration Developer 的 6.0.2 版本引入了在 W 类型的组件和现有 J 类型的接口构件之间进行自动操作和建立中介的功能:在 WebSphere Integration Developer 组装编辑器中拖放 EJB 或 Java 类时,从引用 WSDL 类型接口的组件桥接调用 Java 类型接口的辅助组件是自动生成的。在调用时,此映射组件将 BO 转换为 Java Bean,在 Java 服务上调用相应的方法,并在返回时将 Java Bean 转换回 BO。

此自动功能还为使用相同基础 WebSphere java2WSDL (JAX-RPC 1.1) 工具的桥接组件和 BO 生成 WSDL。

正如您看到的,这是对前一版本的重要改进,它通过更方便地集成 Java 和 J2EE 基础结构和使用自动生成的辅助组件极大地提高了工作效率。而且您再也不用执行低级数据转换和映射任务,使您能够更多地关注业务逻辑开发。

下一部分将描述一种场景,演示如何轻松地使用这一功能。本文假设您对 WebSphere Process Server 编程模型非常了解。


业务场景阐述

假设分派您的任务是实现图书订购流程。进行一些研究和比较之后,您决定使用 WebSphere Process Server BPEL 实现此流程。在流程建模阶段中,您确定该流程需要以下服务:

  1. getRecommendedBooks
  2. checkStock
  3. chargeCreditCard
  4. fullfilRequest

进一步分析表明,您拥有现有的 EJB 服务,该服务提供给出特定目录的图书推荐。由于此服务满足任务 1 的需求,所以您决定在 BPEL 流程中重新使用此 EJB 服务。我们将了解一下 WebSphere Integration Developer 工具如何帮助您实现其他需求。

设置环境

在继续该场景之前,您应该加载和测试初始构件。您需要安装 WebSphere Integration Developer(以下称为 Integration Developer),并将使用嵌入式 WebSphere Process Server(以下称为 Process Server)以供测试使用。

  1. 导入示例。这里您不需要从头开始。相反,首先下载本文包括的示例。

    1. 启动 Integration Developer 和新的工作区。
    2. 在 Business Integration 视图中,选择 File => Import
    3. 在向导窗口中,选择 Project Interchange 作为要导入的类型。
    4. 浏览找到您已下载的项目交换文件,选中所有三个项目,并单击 Finish(图 1)。
    图 1. 导入项目
    图 1. 导入项目
  2. 测试 EJB 服务。您刚才导入的软件包包括 EJB 服务和在本场景中讨论的 BPEL 流程框架。先测试 EJB 服务:

    1. 启动嵌入 Integration Developer 的 Process Server。
    2. 将 BookManager 应用程序添加到该服务器,并单击 Finish(图 2)。
      图 2. 向 Process Server 添加项目
      图 2. 向 Process Server 添加项目
    3. 您现在可以使用统一测试客户端 (Universal Test Client) 测试 BookManager EJB。EJB 具有方法 getRecommendedBooks,它可以返回特定目录中的图书列表(图 3)。
      图 3. 统一测试客户端
      图 3. 统一测试客户端

BPEL 流程概述

让我们简单地看一下 BookOrdering BPEL 流程框架。在 Business Integration 视图中,在流程编辑器中双击以打开它(图 4)。

图 4. BookOrdering BPEL 流程
图 4. BookOrdering BPEL 流程

这个简单的 BPEL 流程可建模图书订购场景,其中包括该场景中提到的若干不同的任务。对于本文而言,您不需要实现所有这些服务,但是一定要利用前面测试的 BookManager EJB 服务来实现任务 GetRecommendedBooks。


简化的方法

如何将 BookManager EJB 服务与 BPEL 流程集成?如果您使用的是 Integration Developer V6.0.1 或更早版本,则需要执行许多手动工作,其中包括为 EJB 方法参数 Java Bean 创建业务对象、创建匹配 EJB 接口的 WSDL 接口和创建 Java 桥接 SCA 组件。(有关如何使用该工具的较早版本实现此目标的信息,请参见参考资料。)该流程非常耗时,并且容易出错,这将大大影响现有 Java 或 EJB 构件的重用。

幸运的是,使用 Integration Developer V6.0.2 中的高级工具支持,可以自动完成所有上述任务,这样可以更容易地使用 SCA 组件的任何 Java 或 EJB 服务。

让我们使用新的方法和工具支持来继续该示例。

拖放

  1. 首先在 BookManagerEJB 外创建 EJB 客户端项目通过选择 Window => Show views => Other... 打开 Navigator 视图,然后右键单击 BookManagerEJB 项目(图 5)。

    图 5. 创建 EJB 客户端项目
    图 5. 创建 EJB 客户端项目
  2. 返回到 Business Integration 视图,打开模块 BookOrderingProcess 的组装图。该图应该是空的。

  3. 打开 Navigator 视图,展开 BookManagerEJBClient 项目,选择 BookManager.java,然后将其拖放到空画布中(图 6)。

    图 6. 向组装图添加项目
    图 6. 向组装图添加项目
  4. 对话框会显示,询问要创建什么类型的组件。本例中为 Import with Stateless Session Bean Binding(图 7)。

    图 7. 创建 EJB 导入
    图 7. 创建 EJB 导入
  5. 单击 OK。再次询问您是否需要创建映射组件。单击 Yes(图 8)。

    图 8. 创建映射组件
    图 8. 创建映射组件
  6. 最后的步骤将询问您是否将 BookManagerEJBClient 项目作为 Java 依赖项添加到流程模块。单击 OK。(图 9)。

    图 9. 管理项目依赖关系
    图 9. 管理项目依赖关系
  7. 图 10 显示了完成拖放后的关系图。您有一个 Java 映射器组件和一个 EJB 导入组件。

    图 10. 完成的组装图
    图 10. 完成的组装图

检查生成的构件

正如您前面看到的,两个组件是自动生成并放入组装图的。还有一个 SCA POJO 组件,它是前面讨论的桥接/映射代码。它具有 W 类型的接口,但是它还具有连接到 EJB 导入组件的 J 类型引用。如果打开 Navigator 视图,则将看到基础构件(图 11)。

图 11. 组装图背后的构件
图 11. 组装图背后的构件

完成 BPEL

您现在可以完成 BPEL,并使用生成的构件来访问 EJB 服务(图 12)。(BPEL 开发的详细信息不在本文的讨论范围之内,所以这里仅列出主要步骤。)

  1. 在 BPEL 编辑器中打开 BookOrderProcess。在 Business Integration 视图中,找到 BookManager 接口,并将其拖放到引用的合作伙伴调色板。

  2. 创建两个变量:ArrayofBook 类型的 BookList 和 String 类型的 Category

  3. 创建 AssignCategory,它可以将 OrderInput 目录属性映射到变量目录。

  4. 将 GetRecommendedBooks 节点更改为调用活动,并填充属性的详细信息。

    图 12. 完成的 BPEL
    图 12. 完成的 BPEL
  5. 请使用下面的代码作为指导在 DisplayBooks Java 代码片段中输入一些示例数据详细信息,并保存更改。

    System.out.println("Get result from EJB services"); 
    List books = BookList.getList("Book"); 
    
    DataObject bookBO = (DataObject)books.get(0); 
    System.out.println("Book Name: " + bookBO.getString("title")); 
    System.out.println("Book Author: " + bookBO.getString("author"));
  6. 返回到组装图,并将 BPEL 流程组件放在其中。在组装图中,从业务流程组件到桥接组件的 WSDL 接口建立连接。编辑器在 BusinessProcess 组件上创建匹配的 WSDL 引用,以完成桥接。Facade 映射组件不包括任何业务逻辑;它只支持 Java 接口和 WSDL 引用之间的连接。图 13 中的组装图显示了 BusinessProcess 组件通过桥接组件连接到 SLSBImport Java 导入。

    图 13. 完成的业务流程
    图 13. 完成的业务流程

运行和测试完成的应用程序

现在已准备好测试解决方案:

  1. 启动服务器(如果尚未启动)。

  2. BookOrderingProcessApp 项目添加到该服务器。

  3. 在组装图中,右键单击 BookOrderProcess,并选择 Test Component

  4. 在测试窗口的 Configuration 选项卡中,删除模拟器。

  5. Events 选项卡,为目录字段输入值:RCP,并单击 Continue

    图 14. 测试完成的应用程序
    图 14. 测试完成的应用程序
  6. 检查 WebSphere 服务器日志。您应看到类似于下面所示的消息,指示 BPEL 流程已成功调用了 BookManager EJB 服务器,并获得返回的结果。

    [5/18/07 10:56:23:831 EDT] 00000086 SystemOut     O Get result from EJB services
    [5/18/07 10:56:23:831 EDT] 00000086 SystemOut     O Book Name: Eclipse Rich Client
    	Platform - Designing, Coding and Packaging Java Applications
    [5/18/07 10:56:23:831 EDT] 00000086 SystemOut     O Book Author: Jeff McAffer and 
    	Jean-Michel Lemieux

提示和最佳实践

下面是一些有帮助意义的提示,以便补充您对此功能的使用:

  • Java 接口要求

    您可以将 Java 类或接口的限制拖到组装编辑器画布,以生成桥接组件:

    • 您可以使用普通 Java 接口。
    • 还可以使用无状态会话 Bean 远程接口。
    • 甚至可以使用 Java 实现类本身。但是,此类需要实现一个接口,而且只实现一个接口。如果该类不能实现一个接口(或者实现多个接口),则组装编辑器将不能向您提供生成桥接组件的选项。
    • 如果您希望生成的 WSDL 具有与 Java 接口中的方法参数对应的有意义的操作参数名称,则工作区中很可能需要接口和类的源代码。
  • Java 输入和输出要求

    如果 Java 构件的输入或返回是用户定义的 Java 类,则它必须符合 JAX-RPC 1.1 中 5.4 部分的约定。JAX-RPC 规范对生成代码具有重要意义。

  • 具有 Java 向量、集合和数组的接口

    Integration Developer 工具依靠基础 Java2WSDL 实用工具才能在 Java 类型和 XML 类型之间进行转换。在缺省情况下,将类型的 Java 数组映射到 ComplexTypes 的 XSD 数组(确切匹配 Java 类型)时,会将集合和向量映射到 anyType 的 XSD 数组。显然,强类型的 XSD 比较容易使用和映射,所以您最好在 Java 接口中使用类型的数组,而不是向量或集合。

  • 带有构造器的 Bean

    如果 Bean 拥用非缺省的构造器,工具似乎不能为您生成正确的 complexType。而是生成 anyType。如果您拥有如下所示的 Java Bean:

    public class Book implements Serializable{
    	public String title;
    	public String author;
    	public String publishDate;
    
    	public Book(String title, String author, String publishDate) {
    		super();
    		this.title = title;
    		this.author = author;
    		this.publishDate = publishDate;
    	}
     
    }

    则生成的 XSD 将与以下所示类似:

    <complexType name="ArrayOfBook">
     <sequence>
      <element maxOccurs="unbounded" minOccurs="0" name="Book"
    	nillable="true" type="xsd:anyType"/>
     </sequence>
    </complexType>

    因此,在您的 Java Bean 中,应避免使用构造器。

  • 重构

    拖放工具将为相应的 Java 接口生成具有内联模式的 WSDL。您无法与其他项目中的其他 WSDL 共享内联模式。现在,在版本 6.0.2 中,可以将 WSDL 文件内部的内联 XSD 定义拆分或外部化,以便更好地使用。Integration Developer V6.0.2 通过突出显示重构上下文菜单中的 Extract Inline Business Objects 会自动认识具有内联模式的 WSDL。总之,这样较容易在模块之间共享 XSD/BO。

  • 覆盖

    有时候,系统在 Java 代码和服务数据对象(Service Data Object,SDO)之间构建的缺省映射可能不能满足您的需求,或者有时您更希望拥有更多自定义或控制的方法来处理映射器中的业务异常。在所有这些情况中,您可以将缺省映射器类实现替换为您自已的——但是您需要使用 Integration Developer 或 genMapper 命令生成 Java 到 WSDL 的类型转换。

    private commonj.sdo.DataObject
    javatodata_getRecommendedBooks_output(java.lang.Object result,
    javax.xml.namespace.QName primitiveNameSpace) {
    
    // User can override this code to do custom mapping.
    // Just comment out the existing code and write your custom code.
    return com.ibm.wbiserver.mediation.jtow.SDOJavaObjectMediator.java2Data(result, 
    primitiveNameSpace);
    }

结束语

本文向您介绍了现在使用SCA 组件中的现有 Java 构件非常容易,这要归功于 WebSphere Process Server 和 WebSphere Integration Developer Version 6.0.2 中的新工具支持。这些增强功能将显著提高部署工作效率,并鼓励重用现有 Java 服务。


下载

描述名字大小
Sample application (Start files)BookOrdering_StartingPI.zip13 KB
Sample application (Completed files)BookOrdering_DonePI.zip20 KB

参考资料

学习

讨论

条评论

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=WebSphere
ArticleID=241592
ArticleTitle=通过 WebSphere Process Server 和 WebSphere Integration Developer 方便地使用 Java 构件
publish-date=07192007