级别: 初级 Wilbert Kho (wilbert@us.ibm.com), 软件 IT 咨询认证专家, IBM
2004 年 11 月 01 日 本文向您介绍了如何使用 IBM® WebSphere® Studio Enterprise Developer V5.1.1 去改编现存的 CICS® COBOL 应用程序,使之能够作为一个使用用于 CICS 的 SOAP(用于 z/OS® V2 的 CICS Transaction Server 的一个特性)的 Web 服务而被访问。本文还讨论了如何用基于 Java™ 和 Microsoft® .NET 的客户端去测试和调用该 Web 服务。
引言
在本教程中,您将使用
IBM WebSphere Studio Enterprise Developer(以后称为 Enterprise Developer) 中的 XML Enablement Tool 工具来改编一个现有的 CICS COBOL 应用程序,使之能够作为一个通过用于 CICS 的 SOAP(用于 z/OS® V2 的 CICS Transaction Server 的特性)来实现的 Web 服务而被访问。在改编完现有的 CICS COBOL 应用程序以后,您将使用 Enterpise Developer 创建用于描述这个基于 CICS 的 Web 服务的 Web 服务描述语言(WSDL)文件。接下来,您将使用 Enterpise Developer 中的基于 Java 的 Web Service Explorer 工具来测试在 WSDL 文件中描述的 Web 服务。最后,您将用运行在 Microsoft .NET Framework 之上的 C# 客户端调用 WSDL 文件以及生成的代理。
本文没有涉及使用 WebSphere Studio 的细节,而是假设您知道如何操作 WebSphere Studio Enterprise Developer 并且熟悉工作区、透视图、编辑器、视图等概念。它也不是关于 CICS、COBOL、Web 服务或者 C# 的入门课程,而是假设您对于开发这些应用程序已经有一定的应用知识。本文并没有广泛涉及用于 CICS 的简单对象访问协议(Simple Object Access Protocol,SOAP)以及 Microsoft .NET。 如果您对这些主题感兴趣,并且想了解更多内容,请参阅
参考资料部分。
本教程的目的是演示如何改编一个现有的 CICS COBOL 应用程序,使之成为 Web 服务,使用在 Enterprise Developer 中的工具来:
- 创建并部署将运行在用于 CICS 的 SOAP 环境下的适配器代码(以下称为消息适配器)。
- 用 Web 服务描述语言(WSDL)文件来创建以及描述此基于 CICS 的 Web 服务。这个 Web 服务可以被基于 Java 或者是 Microsoft .NET 的开发工具使用,从而创建基于 Java 或者是 Microsoft .NET 的客户端。
开始前您需要些什么
在开始之前,您需要 WebSphere Studio Enterprise Developer V5.1.1 以及 Microsoft .NET Framework SDK V1.1。您同样需要访问用于 z/OS V2 的 CICS Transaction Server,并且其已经安装了用于 CICS 的 SOAP 功能。Microsoft .NET Framework SDK V1.1 在(
Microsoft Developer Network)上是可以免费使用的,并且可以演示如何从一个 Microsoft .NET 客户端去访问基于 CICS 的 Web 服务。确认您已经获取了该 SDK 而不仅仅是运行时框架。
本教程中的范例使用了被称为 DEMOMVS 的 z/OS VIR4 系统,它运行在用于 z/OS V2R3 的 CICS Transaction Server 上,并且用于 CICS 的 SOAP 功能是可以使用的。另外, Enterprise Developer 的 z/OS 组件也同样已经安装并且可以使用。
在本教程中,您所需要的构件包含在
wseds4c.zip 文件中,并且作为本文的
下载提供。把它放在
\wseds4c\artifacts 子目录里面。在本文后面的部分中,我将在描述构件目录时提到它。
WebSphere Studio Enterprise Developer
WebSphere Studio Enterprise Developer V5.1.1 使开发基于 Java 和 z/OS 的应用程序更加容易。它支持和利用不同种类的技能集(COBOL、PL/I 以及 Java),从而降低了创建混合工作量的应用程序所需的复杂性并减少了工作量。特别是,Enterprise Developer 包含了一些工具,这些工具支持 Web 服务开发和现有 Z/OS COBOL 应用程序的 XML 实现。这使创建分布式、基于 Z/OS 的组件更加容易,这些组件构成了面向服务体系结构(SOA)的一部分。
XML 实现工具采用输入 COBOL 数据声明,该数据声明为 COBOL 应用程序定义输入输出接口。XML 的构造以及数据类型来源于 COBOL 数据声明。基于此,XML 实现工具生成了以下构件集(参照图 1):
-
输入转换器 - 一个 COBOL 程序,用来接收 XML 文档,并且将其映射到相应的 COBOL 数据结构中,这个数据结构是现有 COBOL 应用程序所期望的。
-
输出转换器 - 一个 COBOL 程序,用来接收从现有 COBOL 应用程序中返回的 COBOL 数据,并且将其映射到 XML 文档中。
-
驱动程序 - 一个模板 COBOL 程序,说明了输入输出转换器如何与现有的 COBOL 应用程序互操作。这个程序必须在运行以前被修改。
-
输入文档 schema 定义 - 一个 XML schemas,描述由输入转换器处理的引入 XML 文档。
-
输出文档 schema 定义 - 一个 XML schemas,描述由输出转换器产生的输出 XML 文档。
图 1. WebSphere Studio Enterprise Developer 中的 XML 实现
输入转换器、输出转换器以及自定义的驱动程序一起组成了适配器代码,使之与现有的 COBOL 应用程序连接,并且使 COBOL 应用程序(没有做修改)能更有效的消费和生成 XML 文档。适配器代码成为消息适配器,当完成一个现有 CICS COBOL 应用程序的 Web 服务请求后,用于 CICS 的 SOAP 将传递控制给此消息适配器。
用于 CICS 的 SOAP
用于 CICS 的 SOAP 使现有的用于 z/OS V2 的 CICS Transaction Server 能处理进出站的 SOAP 请求。它允许现有的 CICS 应用程序处理服务请求,使它们成为有效服务提供者。您也可以编写新的 CICS 应用程序,使服务请求运行在其他系统上的 Web 服务。SOAP 请求既可以用 HTTP(Hypertext Transfer Protocol)来传输,也可以用 WebSphere MQ 来传输。用于 CICS 的 SOAP 管道处理这些请求(图 2),最后传递包含 XML 请求的 SOAP 主体到消息适配器中。消息适配器将 XML 请求映射到 CICS COMMAREA ,该 CICS COMMAREA 将被传递到一个现有的 CICS 应用程序。消息适配器也将任何 COMMAREA 格式的返回数据映射到 XML,并且将这个 XML 请求返回到用于 CICS 的 SOAP 管道流程。合成的 XML 响应形成了 SOAP 响应主体的一部分,该部分被返回到发出请求的 SOAP 客户端。
图 2. 用于 CICS 的 SOAP
开发任务概述
为了完成本教程,您将完成以下的任务:
-
将 COBOL 数据声明导入到一个 z/OS 本地项目中
-
使用 XML 实现工具来生成消息适配器和 XML schemas
-
构造消息适配器并部署到 z/OS 的 CICS 上
-
创建 WDSL 来描述基于 CICS 的 Web 服务
-
使用 Web Services Explorer 来测试基于 CICS 的 Web 服务
-
使用 Microsoft .NET WSDL 工具来为基于 CICS 的 Web 服务生成 C# 代理
-
创建、编译并执行一个简单的 Microsoft .NET 客户端。
本文在一个连接到 z/OS DEMOMVS 系统上的 Windows XP 工作站开发并测试。教程的其他部分假设您已经启动了 Enterprise Developer 并且熟悉它主要组件的使用。本教程的一部分需要您建立了到 z/OS 系统的连接,该系统包含了运行着的用于 z/OS V2 的 CICS Transaction Server, 并具备用于 CICS 的 SOAP 能力。在本教程的开发和测试过程中,我会与运行在 DEMOMVS 上的名为 CICSA 的 CICS 系统进行通信。
任务 1. 导入 COBOL 数据声明到一个 z/OS 本地项目中
在第一个任务中,导入现有的 CICS COBOL 应用程序到一个 z/OS 本地项目中。Enterprise Developer 的 XML 可用性工具既可以同一个完整的 COBOL 源程序工作,也可以同一个包含描述该应用程序接口的数据声明的 COBOL 习字簿一起工作。这个 CICS COBOL 源程序是 WBCSCUST。给定一个客户号码,WECSCUST 将返回关于这个客户的信息。其源文件是在构件目录中的
WBCSCUST.cbl 文件。清单 1 显示了 WEBCSCUST 的接口:
清单 1. WBCSCUST 的接口(DFHCOMMAREA)
01 DFHCOMMAREA.
02 CustNo PIC S9(9) COMP-5.
02 LastName PIC A(25).
02 FirstName PIC A(15).
02 Address1 PIC X(20).
02 City PIC A(20).
02 State PIC A(5).
02 Country PIC X(15).
02 RetCode PIC S9.
|
WBCSCUST 是相对简单的 CICS COBOL 应用程序,没有与数据库的交互,因此,可以很容易构造和部署在您的目的 z/OS 系统上。用 WBCSCUST 来执行本教程,您必须构造和部署它到目的 z/OS 系统上的 CICS 区域。
- 在 z/OS Projects 透视图中,用本地项目创建向导创建名为 CICSWS 的 z/OS 本地项目。接受其它选项的默认值并单击
完成。
图 3. 创建 z/OS 本地项目
- 从构件目录中导入
WBCSCUST.cbl 到刚创建的 CICSWS 本地项目中。
任务 2. 使用 XML 可用性工具生成消息适配器和 XML schemas
接下来,使用生成 XML 转换器向导来生成 COBOL 程序,该程序组成了 WBCSCUST 使用的用于 CICS 的 SOAP 消息适配器。您也需要生成 XML schemas 来描述输入和输出的 XML 消息。
- 在 CICSWS 中右键单击
WBCSCUST.cbl ,并且选择
Enable XML => Generate XML converter 来启动生成 XML 转换器向导。
- 在文件选择面板上,核实源文件
WBCSCUST.cbl 是否是从 CICSWS 本地项目中获取。选中复选框,以命令该向导生成转换器并驱动到一个物理文件。大多数情况下您需要这么做,因为它使构造和部署适配器代码到您的目标 z/OS 系统更加简化。我们所期望实现是把用于 CICS 的 SOAP 作为消息适配器来部署。修改输入转换器文件的名字,使其文件名少于或等于 8 个字符。对于本教程,我指定了
WBCSCUSD.cbl 作为它的名字。最后,我修改了输入和输出消息的 XSD 文件的文件名,使其开始的 7 个字符与输入转换器文件名的头 7 个字母相匹配。用图 4 来作为指导。
图 4. 为生成 XML 转换器指定文件选项
单击
下一步继续。
- 在 XML 转换器选项面板上,指定一个少于或等于 7 个字符的程序名。在生成 COBOL 转换器以及驱动时,向导用其在作为程序名的一部分。在本教程中,我指定
WCUST 作为其程序名。该向导生成名为
WCUSTD 的 COBOL 驱动程序和名为
WCUSTI 的 COBOL 输入转换器。对于驱动类型,从下拉式列表框中选择
CICS SOAP,因为我们生成的是将部署在用于 CICS 的 SOAP 环境下的消息适配器。对于入站命名空间,将
WBCSCUSTI 改为
WBCSCUSI,换句话说,移除“T”。在出站命名空间上做同样的改变,从
WBCSCUSTO 中移除“T”。接受其余选项的默认值,如图 5 中所示。
图 5. 指定 XML 转换器选项
单击
下一步继续。
- 在数据结构面板上,选择那些将分别映射到输入输出 XML 消息中的输入以及输出数据结构。记住,现有的名为 WBCSCUST 的程序将接收一个客户号码作为输入,并返回关于该客户的信息。因此,我在
DFHCOMMAREA 数据结构中选择
CUSTNO 作为输入。对于输出,我选择完整的
DFHCOMMAREA 数据结构,如图 6 中所示:
图 6. 为转换选择数据结构
单击
完成以生成 COBOL 转换器、驱动以及描述输入输出 XML 消息的 XML schemas。
- 一旦完成了生成操作,检验您的 CICSWS 项目是否包含三个附加的构件:
WBCSCUSD.cbl,
WBCSCUSI.xsd 以及
WBCSCUSO.xsd,如图 7 所示。
图 7. 由生成 XML 转换器向导生成的构件

 |

|
任务 3. 构造消息适配器并部署到 z/OS 上的 CICS
在这个任务中,您修改生成的驱动程序,使其能恰当的调用现有程序,并且可以被正确构造。随后您将构造和部署它。上一个步骤中生成的构件是
WBCSCUSD.cbl,它是一包含 COBOL 驱动程序、输入转换器以及输出转换器的物理文件。我们让生成 XML 转换器向导来将这些生成到单独的物理文件中,使在 z/OS 上的构造和部署工作更加容易。您将在 z/OS 项目透视图下工作,并且修改
WBCSCUSD.cbl 文件。
- 在 z/OS 项目视图中,从 CICSWS 中双击
WBCSCUSD.cbl 。将打开 z/OS LPEX 编辑器。您可以用大纲视图(图 8)来理解 WBCSCUSD 的结构以及操纵这个应用程序的不同部分。WBCSCUSD 中您要修改的唯一部分是驱动,它含有 WCUSTD 的 Program-Id。您可以学习其他部分,比如输入(WCUSTI)以及输出(WCUSTO)转换器,为使用生成 XML 转换器向导节省时间和提高效率,但是注意不要修改这些内容。
图 8. 用 z/OS LPEX 编辑器编辑 WBCSCUSD.cbl
- 使用 outline 视图,扩展 WCUSTD 的 Data Division,直到您看到其 Local-Storage 部分。滚动 outline 视图直到您看到 DFHCOMMAREA。选择
DFHCOMMAREA 在 DFHCOMMAREA 上定位编辑器。(参阅图 9 以及 图 10)。
图 9. WCUSTD Local-Storage
图 10. 在 Local-Storage 部分中的 DFHCOMMAREA
- 将
DFHCOMMAREA 更改为
CustInterface。因为这是 CICS COBOL 程序,它必须由 CICS 变换器来处理。CICS 变换器将在 WCUSTD 的 Linkage 部分为 DFHCOMMAREA 插入声明,这将会导致编译错误,因为关于 DFHCOMMAREA 的声明已经包含在 Local-Storage 部分中。因此,您需要修改在 Local-Storage 部分中的 DFHCOMMAREA 声明。既然已经改变其名称,取如 CustInterface 这样更加具备描述性的名字这样会更好,如图 11 所示。
图 11. CustInterface
按下
Ctrl+S 来保存修改。
- 在 WCUSTD 中其他的三个地方也引用了 DFHCOMMAREA,我们需要将其改为
CustInterface:
- 现有业务程序的调用,如
CURRBUS 被生成(参阅清单 2)。
- 输入转换器
WCUSTI 的调用(参阅清单 3)。
- 输出转换器
WCUSTO 的调用(参阅清单 4)。
使用编辑器,用
CustInterface 替换
DFHCOMMAREA。另外,用
WBCSCUST 替换
CURRBUS,它是现有程序的名字。确信您仅仅在 WCUSD 中改变了这些引用。
清单 2. 执行当前的业务程序
* -------------------------------------------------------------
* Execute Current Business Program
* -------------------------------------------------------------
exec cics link
program ('CURRBUS')
commarea (DFHCOMMAREA)
end-exec
|
清单 3. 输入转换器 WCUSTI 的调用
w-inbound-conversion.
call 'WCUSTI'
using
DFHCOMMAREA
w-xml-int-len
w-xml-int-txt
omitted
* w-optional-feedback-code
returning
w-converter-return-code
|
请求 4. 输出转换器 WCUSTO 的调用
w-outbound-conversion.
call 'WCUSTO'
using
DFHCOMMAREA
w-xml-int-len
w-xml-int-txt
omitted
* w-optional-feedback-code
returning
w-converter-return-code
|
按
Ctrl+S 来保存这些修改。
- 现在,已经对驱动程序 WCUSTD 做了必要更改,您便可以构造和部署消息适配器到 z/OS 上。记住,消息适配器是由驱动程序、输入转换器以及输出转换器组成的,并且包含在名为
WBCSCUSD.cbl 物理文件中。构造消息适配器,需要编译 WBCSCUSD 程序并且链接到可执行的加载模块。在我的 DEMOMVS 系统中,安装了用于 z/OS V3.3 的 IBM Enterprise COBOL,它支持集成的 CICS 转换器。这意味着仅需要一个 COBOL 编译步骤来替代通常的 CICS 转换后的 COBOL 编译步骤。
有许多种方式可转移 WBCSCUSD COBOL 源程序到目的 z/OS 系统上,使之能够构造并且部署到 CICS 系统上;Enterprise Developer 可以简化这些操作。我不会叙述使用 Enterprise Developer 的每个细节,而是描述那些在高的级别上您需要做的事情。接下来的步骤假定您已经用 Enterprise Developer 连接到 z/OS 系统上,并且已经从 CICSWS 本地项目中复制
WBCSCUSD.cbl 到您的目的系统中的库成员。在测试本教程时,我连接到 DEMOMVS 系统并且复制
WBCSCUSD.cbl 到名为
DNET017.CICSWS.COBOL的 MVS 库中。
- 连接到目的 z/OS 系统上后,创建 z/OS MVS 项目并且从该 z/OS 系统中添加 WBCSCUSD 程序到此项目中。在本范例中,我创建了名为 CICSWZ 的 z/OS MVS 项目,并从数据集
DNET017.CICSWS.COBOL 中添加成员 WBCSCUSD 到 CICSWZ(参阅图 12)。我已归集了用于 CICSWZ 项目的属性文件以供您的参考;即在构件目录中的
CICSWSZ_properties.xml 文件。
图 12. CICSWZ MVS 项目
- 在 CICSWZ 项目中右键单击
WBCSCUSD ,并且选择
Generate JCL => For Compile Link 生成您可以提交到目的 z/OS 系统上的任务。CICSWZ 项目已经被建立,因此生成的任务将包含所有步骤,实现用集成的 CICS 转换器来编译该程序以及链接该程序到可执行的加载模块中。
- 一旦生成结束,附加的构件将显示在 CICSWZ 项目中,即编译以及链接任务。在本范例中,生成的任务也叫 WBCSCUSD,并且包含在数据集
DNET017.STEW.JCL 中。您可以在该任务上双击来在 z/OS LPEX 中查看并且做其它的修改(图 13)。
图 13. 编译以及链接 WBCSCUSD 的 WBCSCUSD 任务
- 保存更改后,您要用 Enterprise Developer 来提交任务。您可以使用 z/OS Job Monitor 视图来监控提交的任务以及查看它的结果(图 14)。
图 14. 用 WebSphere Studio Enterprise Developer 监视任务
- 假设 WBCSCUSD 的编译和链接是成功的,现在您有可执行的加载模块,可以部署到 CICS 上。在更高的层面上,下面这些是您接下来要做的事情:
- 复制该加载模块到一个库中,这个库是一系列用于目的 CICS 系统 的 DFHRPL 的一部分。
- 定义并安装用于 WBCSCUSD 的 PROGRAM 资源。
对于我使用的 DEMOMVS 系统而言,我必须复制 WBCSCUSD 加载模块到名为
USER.LOADLIB 的数据集中,并且为它激活在 CICSA CICS 系统上的 PROGRAM 资源。您将使用的用于您指定安装的步骤可能是多种多样的。当结束该步骤后,用于 CICS 的 SOAP 消息适配器(用于现有的 WBCSCUST 程序)可处理服务请求。在这时,您可以断开 Enterprise Developer 同目的 z/OS 系统的连接。

 |

|
任务 4. 创建 WSDL 来描述基于 CICS 的 Web 服务
在完成了上一个任务以后,您已经成功地部署了名为 WBCSCUSD 的消息适配器,它将同现有的名为 WBCSCUST 的程序相结合。WBCSCUSD 使 WBCSCUST 能更高效的消费和生产 XML 消息。在与用于 CICS 的 SOAP 联合以后,该应用程序可以作为 Web 服务来被访问。接下来我将描述基于 CICS 的 Web 服务,使其可以被发布和发现。为了做到这一点,需要创建 Web Services Description Language(WSDL)文件。图 15 概括了用 Enterprise Developer 创建该 WSDL 文件的步骤。一旦 WSDL 被创建,您就可以用在下一个任务中的 Web Service Explorer 工具来测试它。
图 15. 为基于 CICS 的 Web 服务创建 WSDL
- 在 z/OS Projects 视图中,选择
CICSWS 项目并且按下
Ctrl+N 打开新的向导。在选择向导的面板上,从左面的窗格中选择
Web 服务,并且在右面的窗格中选择
WSDL(参阅图 16)。单击
下一步继续。
图 16.创建新的 WSDL 文件
- 在新的 WSDL 文件面板上,确认 CICSWS 是父目录,并且指定
CustInfo.wsdl 作为文件名。单击
下一步继续。
- 在选项面板上,指定 CustInfo 的定义名,并且选择
soap http://schemas.xmlsoap.org/wsdl/soap 作为包含的附加命名空间(图 17)。WSDL 命名空间包含 WSDL 元素的定义。soap 和 xsd 是标准的命名空间定义,用来指定特定 SOAP 的信息和数据类型。
图 17. 指定 CustInfo.wsdl 的选项
单击
完成来完成创建 WSDL 文件。
- 在创建完 WSDL 文件以后,新 WSDL 文件向导将启动 WSDL 编辑器,您可以完成对 Web 服务的描述。有多个编辑器与 WSDL 文件关联。默认情况下,Enterprise Developer 将 Basic JCA WSDL Editor 定义为 WSDL 文件的默认编辑器。当您进行 JCA(J2EE Connector Architecture)相关的开发时,您可以使用该编辑器。在本教程中,我们将使用名为 WSDL Editor 的编辑器。
要想分辩您正在使用的编辑器,可以查看与其相关的标签数目。Basic JCA WSDL Editor 有六个标签,然而 WSDL Editor 仅仅有两个(参阅图 18 和图 19)。我们将使用 WSDL Editor 的图形视图来编辑 WSDL 文件。如果新 WSDL 文件向导使您位于 Basic JCA WSDL Editor 中,必须关掉它,并且用 WSDL Editor 重新打开 CustInfo.wsdl 文件。
图 18. Basic JCA WSDL Editor
图 19. WSDL Editor
- 确认您在 WSDL Editor 的图形视图下工作(图 19)。现在,我们将开始对 WBCSCUSD Web 服务的描述。首先,我们需要定 portType,它是由多个端点支持的操作的抽象集合。Port 类型可以同一个函数库或者由传统编程语言编写的模块来比较。在图形视图下,将您的光标定位在
Port Types 部分,右键单击并且选择
Add Child => portType,为新的 Port Type 指定名字
CustInfo 并且单击
OK(参阅图 20 和图 21)。
图 20. 添加 Port Type
图 21. CustInfo Port Type
- 在定义了 Port Type以后,我们将定义与其相关的操作。操作是被服务支持的行为的抽象定义。对于本教程,我们将仅仅定义一个操作。在
CustInfo 端口类型上右键单击,然后选择 Add Child => operation;将新的操作命名为
getCustInfo 并且单击
OK(参阅图 22 和图 23)。
图 22. 为 CustInfo 添加操作
图 23. getCustInfo 操作
- 操作通常会与输入和输出消息关联起来。此操作可能是 one-way,它收到消息但是并不返回响应。此操作也可能是 request-response,它收请求并且返回响应。回忆我们的基于 CICS 的 Web 服务,它接收客户号码并且返回关于该客户的信息。因此我们将定义与 getCustInfo 操作相关的输入输出消息。在 getCustInfo 操作上右键单击,然后选择
Add Child -> input (参阅图 24)。
图 24. 将输入与 getCustInfo 关联
重复该过程,并且为 getCustInfo 添加
output。这时,您应该可以看到与图 25 相似的输出。
图 25. 已定义 Port Type 的 CustInfo.wsd
单击
Ctrl+S 来保存您的修改。
- 在已定义 getCustInfo 操作的输入输出以后,接下来,我们将把消息同输入输出相关联。消息是被用来通信的数据的抽象定义。我们将定义一个消息,并将其与到该 Web 服务的输入请求相关联,定义另一个消息,使其与从该 Web 服务出来的输出相应相关联。为了做到这一点,在
getCustInfo 操作的 input 上右键单击,并且选择
Set Message...。在指定消息的面板上,选择
Create a new message 并且接受
getCustInfoRequest 的默认消息名。单击
完成 来指定消息。用图 26 和图 27 来作为指导。
图 26. 定义 Input Message
图 27. getCustInfoRequest Message
对于输出同样重复该过程,并且接受
getCustInfoResponse 的默认消息名。这时您应该看到同图 28 类似的输出。
图 28. 已定义 Message 的 CustInfo.wsdl
按下
Ctrl+S 来保存您的更改。
- 在已定义与 getCustInfo 操作相关联的消息以后,我们将定义组成这些消息的 part。消息可以有一个或者多个 part 组成。对于本教程,getCustInfoRequest 和 getCustInfoResponse 消息将包含各自的 part。右键单击
getCustInfoRequest 消息,并且选择
Add Child => part;将 part 命名为
CustNo 并且单击
OK(参阅图 29 和图 30)。
图 29. 定义 message part
图 30. CustNo Part
重复这个过程来为
getCustInfoResponse 消息来定义 part,并且将其命名为
CustData。这时,您应该看到类似图 31 的输出。
图 31. 已定义 Part 的 CustInfo.wsd
按下
Ctrl+S 来保存您的修改。
- 在定义 part 以后,我们现在必须定义组成这些 part 的元素。此时我们需要使用 XML schemas,XML schemas 是在您执行
任务 2 时由生成 XML 转换器向导生成。在
CustNo part 上右键单击并且选择
Set Element...。在指定元素的面板上,选择
Import element from a file 并单击
Browse... 按钮(参阅图 32 和图33)。
图 32. 为 CustNo 设定元素
图 33. 导入元素
- 在选择文件的面板上,从 CICSWS 中选择
WBCSCUSI.xsd。
WBCSCUSI.xsd 是生成 XML 转换器向导生成的输入 XML schema。单击
OK 选择。回到指定元素的面板上,注意来自
WBCSCUSI.xsd 的 dfhcommarea 元素已被选中。单击
完成来指定 CustNo 的元素(参阅图 34 和图 35)。
图 34. 选择 WBCSCUSI.xsd
图 35. 导入 dfhcommarea
重复此过程来为
CustData part 定义元素,选择
WBCSCUSO.xsd 作为要导入的 XML schema。这时,您应该可以看到与图 36 相似的一些输出。注意现在 CustNo 和 CustData part 都引用了 dfhcommarea。按下
Ctrl+S 来保存您的修改。
图 36. 引用 XML schemas 后的 CustInfo.wsdl
- 迄今为止,我们已经定义了基于 CICS 的 Web 服务的抽象接口。这个任务的其余部分,我们将定义具体的通信协议以及 Web 服务的地址。接下来我们将使用绑定向导来定义该服务的绑定。如果要想启动绑定向导,单击在工作台工具栏中绑定向导按钮
。
- 在指定 Binding Details 面板上,选择
Generate a new binding。使用
CustInfoBinding 作为绑定的名称。选择
tns:CustInfo 作为端口类型(在列表中应仅有一个选择并且已经被选中)。选择
SOAP 作为协议。最后,选择
document literal 作为 SOAP binding 选项;document literal 是与 Microsoft .NET 协同工作时必须的。使用图 37 作为完成这一步的指导。
图 37. WSDL Binding Details
单击
完成来完成绑定的生成。这是您应该看到同图 38 相似的输出。
图 38. 已定义绑定的 CustInfo.wsd
按
Ctrl+S 来保存您的修改。
- 在定义绑定以后,我们最后必须做的事情是定义服务。在这里,我们通过为该绑定指定端口地址来为服务定义通信端点。服务是一个或者多个端点的集合。对于本教程,我们仅有一个端点。在 WSDL Editor 的图形视图下面,定位您的光标到
Services 部分,右键单击并且选择
Add Child => service;将服务命名为
CustInfoService 并且单击
OK 继续(参阅图 33 和图 40)。
图 39.定义服务
图 40. CustInfoService Service
- 右键单击刚定义的
CustInfoService,并且选择
Add Child => port;将该端口命名为
CustInfo(参阅图 41 和图 42)。您可以认为该端口是抽象的端口类型 CustInfo 的具体副本。单击
OK 继续。
图 41. 定义 Service Port
图 42. CustInfo Port
- 在刚定义的
CustInfo 端口上右键单击,选择
Set Binding... (图 43)。
图 43. 设定 Service Binding
在 Specify Binding 面板上,选择
Select an existing binding (这里应该仅仅有
tns:CustInfoBinding 并且是被选中的),然后单击
Finish 来将现有的绑定关联到 CustInfo 端口。
- 我们现在几乎完成了对基于 CICS 的 Web 服务的描述。我们需要做的最后的事情是指定特定的 SOAP 地址,该地址将是 Uniform Resource Identifier(URI)的形式。右键单击
CustInfo 端口并且选择
Add Extensibility Element => soap:address (参阅图 44)。
图 44. 向 CustInfo 端口添加 SOAP address
- soap:address 元素在 CustInfo 端口下被创建。选择
soap:address 来修改位置属性。在本文中,我指定 URI
http://demomvs.demopkg.ibm.com:8080/CICS/CWBA/DFHWSDSH/WBCSCUSD 作为位置的值。您应该用 z/OS 系统的 IP 地址和用于 CICS 的 SOAP 的监听请求的 IP 端口替换
demomvs.demopkg.ibm.com:8080。URI 的其余部分应该保留除非消息适配器外与 WBCSCUSD 不同的名字来部署;在本范例中,用使用的名字替换
WBCSCUSD。参阅图 45 来作为指导。
图 45. 指定 SOAP 地址位置
按下
Ctrl+S 来保存您所做的修改。我们已经完成了对基于 CICS 的 Web 服务,WBCSCUSD 的描述,并且此描述包含在
CustInfo.wsdl WSDL 文件中。您现在可以用该 WSDL 文件来生成开发基于 Java 或者是 Microsoft .NET 的客户端代理。

 |

|
任务 5. 用 Web services Explorer 测试基于 CICS 的 Web 服务
在该任务中,我们将使用 Enterprise Developer 中的 Web Services Explorer 工具来测试基于 CICS 的 Web 服务。
- 在 CICSWS 项目上,右键单击
CustInfo.wsd 并且选择
Web Services => Test with Web Services Explorer。
- Web Services Explorer 在 Web 浏览器视图里面启动。Web Services Explorer 有三个主要的部分:Navigator、Actions 和 Status。注意在 Status 部分中,
CustInfo.wsdl 被成功打开。在 Actions 部分中,您也可以看到 getCustInfo 操作可用。单击链接来执行
getCustInfo 操作(图 46)。
图 46. 用 Web Services Explorer Tool 打开 CustInfo.wsdl
- 请注意,Actions 部分已被 getCustInfo 操作的信息以及其获取的参数代替。它同样列出了同该请求相关的端点。为 CustNo 输入值
8 并且单击
Go 来调用该操作。
- 如果您正确的构造和部署了消息适配器 WBCSCUSD 和现有的 WBCSCUST 程序,并且正确的配置和启动了在 z/OS 系统上的用于 CICS 的 SOAP,您应该在 Status 部分中看到结果,同图 47 是相似的。如果存在许多错误,在 Source 链接上单击查看 SOAP response envelop,检查包含在 SOAP 主题中的任何错误消息。
图 47. 在# 8 客户上执行 getCustInfo 的结果
您可以用
1 到
10 的客户号码来测试。在完成测试后,您可以关闭 Web 浏览器。
任务 6. 使用 Microsoft .NET WSDL 工具为基于 CICS 的 Web 服务生成 C# 代理
迄今为止,您已经为现有的 CICS COBOL 应用程序成功的构造和部署了用于 CICS 的 SOAP 消息适配器,并且有效地将这个应用程序公开为 Web 服务。您也成功地用 WSDL 和 Web Services Explorer 工具描述并测试了该 CICS Web 服务。您在 Enterprise Developer(基于 Java 的开发环境)下面完成了这些行动。本教程中的最后两个任务示范了如何去完成 Web 服务的互操作性。我们将接受在
任务 4 中创建的 WSDL 文件并且在 Microsoft .NET 环境下面使用它。
- Microsoft .NET Framework SDK V1.1 包含 WSDL Tool(
wsdl.exe),它可以为客户端生成代理访问 Web 服务。这个工具接收 WSDL 和 XML schema 文件作为输入,并且可以生成用 C#(CS)、Visual Basic(VB)、JScript(JS)或者 Visual J#(VJS)编写的代理代码。在本文中,我们将使用该工具来生成 C# 代理代码。
由于只安装了 SDK,我将用命令行来示范该操作。在开始前,在磁盘上创建名为
CustInfoClient 的目录。使用 Enterprise Developer 导出
CustInfo.wsdl、
WBCSCUSI.xsd 和
WBCSCUSO.xsd 文件到该目录中。
- 从 CustInfoClient 目录下面执行以下命令(假设 Microsoft .NET SDK bin 和 Framework 运行时目录已经在 PATH 环境变量中定义):
wsdl /nologo CustInfo.wsdl WBCSCUSI.xsd WBCSCUSO.xsd
- CustInfoClient 目录应包含结果文件,
CustInfoService.cs(参阅清单 5 来查看其代码的示例)。这是基于 CICS 的 Web 服务的 C# 代理.
清单 5
using System.Diagnostics;
using System.Xml.Serialization;
using System;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Web.Services;
/// <remarks/>
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="CustInfoBinding", Namespace="http://example.com")]
public class CustInfoService : System.Web.Services.Protocols.SoapHttpClientProtocol {
/// <remarks/>
public CustInfoService() {
this.Url = "http://demomvs.demopkg.ibm.com:8080/CICS/CWBA/DFHWSDSH/WBCSCUSD";
}
/// <remarks/>
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://example.com/getCustInfo",
Use=System.Web.Services.Description.SoapBindingUse.Literal,
ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare)]
[return: System.Xml.Serialization.XmlElementAttribute("dfhcommarea",
Namespace="http://www.WBCSCUSO.com/schemas/WBCSCUSOInterface")]
public DFHCOMMAREA1 getCustInfo([System.Xml.Serialization.XmlElementAttribute
(Namespace="http://www.WBCSCUSI.com/schemas/WBCSCUSIInterface")] DFHCOMMAREA dfhcommarea) {
object[] results = this.Invoke("getCustInfo", new object[] {
dfhcommarea});
return ((DFHCOMMAREA1)(results[0]));
}
|
- 现在我们将生成可以被 C# 客户端引用的库。在 CustInfoClient 目录下面执行下面的命令:
csc /target:library CustInfoService.cs
这个命令调用 Microsoft C# 编译器并且产生
CustInfoService.dll 动态链接库文件。

 |

|
Task 7. 创建、编译并执行简单的 Microsoft .NET 客户端
在该任务中,您将创建、编译并执行用 C# 编写的 Microsoft .NET 客户端。虽然我已经提供简单的 C# 客户端使您快速的入门,但是您仍然可以创建自己的客户端。
- 从构件目录中复制
CustInfoClient.cs 到
CustInfoClient 目录中。
- 编辑
CustInfoClient.cs 文件,并且检查它,以便了解如何调用代理(参阅清单 6)。
清单 6
using System;
// references CustInfoService.dll
// build using: csc.exe CustInfoClient.cs /reference:CustInfoService.dll
public class CustInfoClient {
public static void Main() {
// Instantiate the CustInfo web service proxy
// CustInfoService defined in CustInfoService.dll
CustInfoService proxy = new CustInfoService();
// Instantiate the request document
// DFHCOMMAREA defined in CustInfoService.dll
DFHCOMMAREA request = new DFHCOMMAREA();
// Instantiate the response document
// DFHCOMMAREA1 defined in CustInfoService.dll
DFHCOMMAREA1 response = new DFHCOMMAREA1();
Console.WriteLine("Invoking CICS routine via SOAP over .NET.");
string message = null;
try {
request.CustNo = 8;
response = proxy.getCustInfo(request);
message = response.CustNo.ToString();
message = String.Concat("Details for customer # ", message);
Console.WriteLine(message);
WriteMessage(String.Concat(response.LastName, ", ", response.FirstName));
WriteMessage(response.Address1);
WriteMessage(response.City);
WriteMessage(String.Concat(response.State, ", ", response.Country));
message = response.RetCode.ToString();
message = String.Concat("Return code from request: ", message);
Console.WriteLine(message);
message = "Done invoking CICS COBOL based web service using SOAP.";
WriteMessage(message);
}
catch (Exception e) {Console.WriteLine("Threw general exception: {0}", e);}
}
private static void WriteMessage(string message) {
Console.WriteLine("Server returns: {0}", message);
}
}
|
- 在
CustInfoClient 目录下执行以下命令,它将创建在 Windows 中可执行的文件,
CustInfoClient.exe:
csc CustInfoClient.cs /reference:CustInfoService.dll
- 在
CustInfoClient 目录下执行以下命令运行客户端:
CustInfoClient.exe
您将看到类似图 48 的输出。
图 48. 运行 CustInfoClient - Microsoft .NET Client

 |

|
结束语
本文完整的向您介绍了如何去改编现有的 CICS COBOL 应用程序,使其能成为 Web 服务,且能由 Java 或者是 Microsoft .NET 客户端对其进行访问。通过使用 z/OS V2.2 的 CICS Transaction Server 的 CICS SOAP 特性,您能了解如何使用 WebSphere Studio Enterprise Developer V5.1.1 转换基于 z/OS 的 CICS COBOL 应用程序。这些现有的关键业务应用程序便可以形成您的面向服务体系结构。
下载
参考资料
关于作者  | |  |
Wilbert Kho 是 IBM 的一名软件 IT 咨询认证专家。他的工作主要集中于 WebSphere Studio Enterprise Developer 以及 WebSphere Studio Asset Analyzer 的关于特殊职责的企业转换领域。
|
对本文的评价
|