求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
Web service 与 CICS 事务处理应用的集成
 

作者 :刘 冠军 李 国强,发布于2012-6-21,来源:IBM

 

2008 年 12 月 11 日

CICS(Customer Information Control System),即客户信息控制系统,是为 IBM 和非 IBM 平台上一系列应用提供联机事务处理和事务管理的产品,其主要功能是为商业应用提供一个事务处理环境。该产品拥有近四十年的悠久历史,被广泛应用于银行金融业。但随着当前信息技术的迅猛发展,很多经典的事务处理应用面临着如何被扩展和重用,以求与其他平台应用相集成的问题。CICS 作为 IBM 的重要产品,借鉴了 SOA 的主要思想,采用 Web service 封装已有的应用,实现了 CICS 与其他平台应用的结合与互操作。本文通过一个实际的例子,将一个已有的 CICS 应用程序封装成 Web service 的请求者(requester)请求另一个 Web service,同时又作为服务提供者(provider)接受其它应用的访问。读者不仅能从本文详细了解到如何在 z/OS 上构建 CICS Web service 的详细步骤,同时能够把握 CICS Web service 如何与部署在其他平台上的 Web service 进行互操作,以及与 IBM WSRR(WebSphere Service Registry and Repository) 的结合使用。

概述

主机 (Mainframe) 上的 CICS 服务由于其历史的悠久,存在着很多对于事务处理的经典应用。如何将这些应用重用,并与其他平台的服务进行交互是本文的主要内容。本文模拟了一个非常普遍的应用场景,通过实例介绍 CICS Web service 的封装和具体应用。该实例的总体框架如图 1 所示,主要包括三部分。

1. 实时汇率服务 (Exchange Rate Service, 下文简称为 RateService),是部署在 Windows 操作系统 Websphere Application Server(WAS) 上的一个 Web service,提供汇率值的实时查询服务,由 Java 语言实现。为了使例子简单易懂,这里仅仅提供了人民币对美元的汇率和人民币对欧元的汇率。

2. 转账服务 (TransferService),一个存在于主机 z/OS 环境中的 CICS 事务处理应用程序,它是由 C 语言编写,用于银行帐户不同币种的转账处理。例如某银行客户张三,上月去美国透支了信用卡中 1000 美元用于消费,现在回到中国必须用人民币转账到自己的信用卡美元账户以偿还透支额度。转账过程中必须知道人民币对美元的汇率,因此需要封装成为 Web service 的客户端 (requester) 访问 RateService 提供的实时汇率服务。同时,为了使转账服务能够提供给异构平台上各种语言的客户端调用,还需要将其封装成 Web service 的提供者 (provider)。

3. 网上银行 (Online Trading Platform),模拟的网上交易平台。客户端调用转账服务 (TransferService) 完成客户用人民币偿还信用卡美元帐户等类似转账交易。作者在本文中给出了一个 Struts 框架实现的 Web 应用程序来模拟这一交易平台。

图 1. 实例总体框架

第一步:汇率服务的创建

1. 开发环境

开发平台:Windows 操作系统,IBM Rational Application Developer 7.0.0( 内置 Websphere Application Server 6.1)

开发语言:Java

2.开发步骤

新建一个动态 web 项目。在 IBM RAD7 开发环境中,选择 "File->New->Project", 选择动态 web 项目,命名为 exchange,保留其它选项默认值。

编写要暴露成 Web service 的 Java bean。右键点击 Java Resources:src 目录,选择 "New->Class",填写包名 rate、类名 Rate。Java bean 源代码如清单 1 所示,提供了人民币对美元和人民币对欧元的汇率。

清单 1. Java Bean 源代码

package rate;

public class Rate {

	double RMBtoDollar = 0.1426;

	double RMBtoEuro = 0.09026;

	String errorMsg = "Input is not correct";

	public double getRate(String source, String target) {

		if (source.equalsIgnoreCase("RMB")) {

			if (target.equalsIgnoreCase("Dollar"))
				return RMBtoDollar;

			if (target.equalsIgnoreCase("Euro"))
				return RMBtoEuro;
		}
		// any input error, return 0
		return 0;
	}
}

将 Java Bean 封装成 Web service。右键点击项目名称 exchange, 选择 "New->Other->Web Services->Web Service"。设置 Web service 的构建方式,选择 "Bottom Up Java Bean Web Service"——自底向上(由 Java Bean 生成 WSDL 文件)的构建方式。同时指定 Rate 类作为该 Java Bean,如图 2 所示。点击 "Finish",一个 Web service 便构建成功。在 "...\exchange\WebContent\WEB-INF\wsdl" 目录下可以找到刚刚生成的 Rate.wsdl 文件。wsdl 文件描述了该服务的相关信息,该文件可从附件中下载查看。

图 2. 设置 Web service 构建方式

部署 Web service 到应用服务器。启动应用服务器(这里是 Websphere Application Server 6.1),加载该动态项目的 EAR 包 exchangeEAR。

3.测试 Web service

利用内嵌在 Rational Application Developer 开发环境中的 Web service 客户端工具 (Web Services Explorer) 测试 RateService 是否工作正常。

首先在 "...\exchange\WebContent\WEB-INF\wsdl" 目录下找到 Rate.wsdl 文件,右键单击该文件选择 "Web Services->Test with Web Services Explorer",打开客户端测试窗口。

在 "Web Services Explorer" 窗口左侧找到 Rate.wsdl 文件,选中该 Web Service 提供的操作(Operation)——"getRate",窗口右侧出现该服务的详细描述并提供输入界面并显示输出结果。在 source 项中输入 RMB,在 target 项中输入 DOLLAR,得到人民币对美元的汇率 0.1426。这说明 RateService 运行正常,如图 3 所示。

图 3. 使用 Web Services Explorer 测试 Web service

4.发布 RateService 到 WSRR(WebSphere Service Registry and Repository)。

最后需要将描述 RateService 的 wsdl 文件 (Rate.wsdl) 上传到 WSRR->WSDL 管理中心,由 WSRR 统一管理,方便用户查找该服务,如图 4 所示。CICS 在 3.2 版本之后于 2008 年上半年发布了支持 WSRR 的工具包,将在下文详细介绍。

图 4. WSRR 发布 RateService

第二步:转账服务的实现

1. 开发环境

开发平台:CICS 3.2 on z/OS, DB2 v8 on z/OS

开发语言:C 语言

2.CICS Web service 相关概念。CICS 对 Web service 的支持主要通过以下几方面来实现:

CICS 支持 Web service 的相关资源,主要有 PIPELINE、URIMAP、WEBSERVICE、TCPIPSERVICE 等,这些资源能够定义 WebService 的处理过程。

Web Services Assistant 工具,最新的 CICS 3.2 工具包主要由两个程序组成:DFHWS2LS 和 DFHLS2WS。它们在 3.1 的版本上有所增强,提供了更丰富的支持,可支持的语言包括:COBOL、PL/I、C、C++。用户可以通过使用 Web Services Assistant 来快速方便地实现 WebService,也可以通过自己编程完全地控制 CICS 程序和 WebService 接口之间的数据交互。

  • DFHWS2LS: 帮助用户把 WSDL 文件中的数据定义映射为 CICS 程序所使用编程语言的数据结构。
  • DFHLS2WS: 帮助用户把高级语言编写的 CICS 程序所使用的数据结构转换成 WSDL 定义。

支持 WebService 的 CICS API,例如 INQUIRE WEBSERVICE, INVOKE WEBSERVICE 等。

此外 CICS 在推出 3.2 版之后又发布了一个独立的工具包 CICS SupportPac for WSRR,支持 CICS Web service 与 WSRR 的结合使用。这个工具包主要包含两个程序:DFHWS2SR 和 DFHSR2WS。

  • DFHWS2SR: 帮助用户来把已有的 wsdl 文件从主机 USS 系统中发布到 WSRR。
  • DFHSR2WS: 用来帮助用户把发布在 WSRR 上的 wsdl 文件下载到主机 USS 系统中。

3. 背景分析

转账服务 (TransferService, 下文中两者通用 ) 通常是部署在 CICS 上的一个应用程序,它负责完成各种货币之间的兑换和帐户的转账交易,这是 CICS 应用程序在银行业务中最常见的一种应用。在没有引入 Web service 以前,转账服务必须将有关汇率的处理包含在程序逻辑之内,增加了程序的耦合性。最好的情况也只能封装成 CICS 区域 (region) 上的不同应用程序,通过 CICS 提供的程序之间或区域之间通信的 API 来互相调用。这样一来汇率服务就很难与其他平台和语言编写的程序实现互操作。而 Web service 的引入有效的解决了上述问题,充分实现了服务的可重用性和互操作性。

转账服务的详细处理逻辑:转账服务首先作为 Web service 的服务端 (provider),等待客户端的参数输入。输入包括四个参数:用户名、转账金额、源账户、目标账户。例如:Zhanglin, 100, rmb, dollar 四个参数表示从 zhanglin 的人民币账户中转出 100 元人民币到他的美元账户。转账过程中,需要用到人民币与美元之间的汇率。此时,转账服务转变角色,作为 Web service 的客户端 (requester) 调用 RateService 提供的汇率服务。

4. 开发步骤

下面通过 Web service 封装转账服务的详细步骤,向读者展示 CICS Web service 的应用,并结合实际应用阐述以上有关 CICS Web service 相关的理论和概念。

转账服务作为 RateService 的客户端 (requester),需要知道 RateService 相关描述,所以必须首先通过 DFHSR2WS 从 WSRR 上下载描述 RateService 的 Rate.wsdl 文件。

在主机上通过提交一个 JCL,指定相关参数,便可以调用 DFHSR2WS 程序,将 Rate.wsdl 文件下载到 USS 系统文件夹下。JCL 源码如清单 2 所示:

清单 2. 调用 DFHSR2WS 下载 Rate.wsdl 文件的 JCL 源代码

***************************** Top of Data ******************************
//DSR2WSRT JOB MSGCLASS=H,CLASS=A,NOTIFY=&SYSUID,REGION=0M 
//********************************************************************* 
//* * 
//* DESC : retrieve the wsdl file from WSRR * 
//* * 
//********************************************************************* 
//WSDLREAD JCLLIB ORDER=LIUGUAN.CA1N.JCL 
//EXEC EXEC DFHSR2WS, 
// JAVADIR='java142s/J1.4', 
// WORKDIR='/u/liuguan/install', 
// TMPDIR='/tmp', 
// TMPFILE='SR2WS' 
//INPUT.SYSUT1 DD * 
HOSTPORT=http://cicsrts3.hursley.ibm.com:9080 
LOCATION=/u/liuguan/userdemo/wsdl/ 
LOGFILE=/u/liuguan/userdemo/wsdl/wsdlrate.log 
NAME=Rate.wsdl 
*/ 
**************************** Bottom of Data ****************************
  • Dataset "LIUGUAN.CA1N.JCL" 指定了执行 DFHSR2WS 程序所需要的相关资源
  • HOSTPORT 指定 WSRR 部署的服务器和端口。
  • LOCATION 指定 wsdl 文件存放在 USS 下的具体位置。
  • LOGFILE 指定日志文件,记录程序执行成功或失败的相关信息。
  • NAME 指明在 WSRR 上要下载的 wsdl 文件名。

上述参数是执行 DFHSR2WS 所必须的,其他参数及有关于 DFHSR2WS 更详细的介绍可以在工具包的帮助文档中查到。

Rate.wsdl 文件成功下载后,即可以通过 CICS 3.2 工具包中的 DFHWS2LS 程序,将 wsdl 文件中描述的输入输出转换成具体语言的数据结构,提供给转账服务程序使用。

调用 DFHWS2LS 仍然通过提交一个 JCL,成功执行后会有两个 member 产生,一个描述服务的输入,另一个描述输出。JCL 的源码如清单 3 所示:

清单 3. 调用 DFHWS2LS 实现 XML 到 data 转换的 JCL 源代码

***************************** Top of Data ******************************
 //TWS2LS JOB 616,LGJ,MSGLEVEL=(1,1),REGION=0M,NOTIFY=&SYSUID 
 //*JUSTIN 
 //*THIS JCL CONVERT WSDL(GET FROM PROVIDER) TO LANGUAGE STRUCTURE 
 //* AND WSBIND FILE 
 //*THIS IS A SAMPLE OF WSCELL 
 //MYPROC JCLLIB ORDER='CTS320.CICS650.SDFHINST' 
 //JAVAPROG EXEC DFHWS2LS,PATHPREF='',USSDIR='cerbsf' 
 //STEPLIB DD DSN=CTS320.CICS650.SDFHINST,DISP=SHR 
 // DD DSN=CNTESTD.CICS.C.SRC,DISP=SHR 
 //INPUT.SYSUT1 DD * 
 LOGFILE=/u/liuguan/userdemo/ws2ls/rate.log 
 PDSLIB=//LIUGUAN.ACICS.WSAT.SOURCE 
 REQMEM=RATEO 
 RESPMEM=RATEI 
 LANG=C 
 STRUCTURE=(ratestq,ratestr) 
 WSBIND=/u/liuguan/userdemo/wsclient/wsbind/rateask.wsbind 
 WSDL=/u/liuguan/userdemo/wsdl/Rate.wsdl 
 /* 
 // 
 **************************** Bottom of Data ****************************
  • Dataset "CTS320.CICS650.SDFHINST" 指定了执行 DFHWS2LS 程序所需要的相关资源。
  • PDSLIB 指定输入输出两个 member 产生的位置。
  • REQMEM 指定转换输入的数据结构。
  • RESPMEM 指定转换输出的数据结构。
  • LANG 指定要转换为哪种语言的数据结构。
  • WSBIND 指定转账服务在作为 Web service 客户端所需要的相关配置信息,它将会在 PIPELINE 安装时用到。通过 wsbind 文件,真正的语言结构 (Language Structure) 和 SOAP 包中 xml 对于数据结构的定义才能相互对应并转换。
  • WSDL 则指定要生成 Language Structure 的 wsdl 文件。

JCL 执行成功后,会在 Dataset "LIUGUAN.ACICS.WSAT.SOURCE" 生成两个 member,RATEO01 和 RATEI01(末尾加上 01 是 DFHWS2LS 的命名规则)。

RATEO01 中存储的是 TransferService 作为 RateService 客户端请求 RateService 时发出的数据结构,源码如清单 4 所示(主机中因为编码的原因 ??( 代表 [,而 ??) 代表 ], 下同):

清单 4. RATEO01 源代码

struct ratestq01 
 { 
    struct 
      { 
          char source??(255??); 
          char target??(255??); 
      } getRate; 
  }; 

RATEI01 则存储的是经过 RateService 处理请求之后返回给 TransferService 的数据结构,源码如下:

清单 5. RATEI01 源代码

struct ratestr01 
 { 
 struct 
 { 
 char getRateReturn??(32??); 
 } getRateResponse; 
 
 }; 

在产生了上述的 wsbind 文件和相应的输入输出数据结构之后,便可以开始 TransferService 代码的编写。TransferService 作为 Web service 的服务端 (provider) 也必须定义输入和输出数据结构两个 member 文件,分别为 TRANSI 和 TRANSO。TRANSI 中的输入结构必须命名为 CMDINPUT,TRANSO 中的输出结构则必须命名为 OUTPUT。根据上文提到的逻辑,输入结构 (CMDINPUT) 中应该有四个值 : 用户名,转账金额,源账户和目标账户,如清单 6 所示。输出结构 (OUTPUT) 中定义账户转账之前和之后的金额两个值,如清单 7 所示。

清单 6. TRANSI 中 CMDINPUT 结构体的定义:

struct CMDINPUT 
 { 
 char user??(32??); 
 char sum??(255??); 
 char source??(255??); 
 char target??(255??); 
 } ;

清单 7. TRANSO 中 OUTPUT 结构体的定义:

struct OUTPUT 
 { 
 char before??(255??); 
 char after??(255??); 
 } ;

完成上述准备工作,焦点转移到 TransferService 程序的逻辑编写,该程序命名为 TRANSFER。TRANSFER 程序中几段核心的源码介绍如下。

清单 8. CICS DB2 应用接口的声明:

EXEC SQL BEGIN DECLARE SECTION;
char dbuser??(11??);
double money = 0;
double rmb_account = 0;
double target_account = 0;

EXEC SQL DECLARE LIUGUAN.USERDEMO TABLE(
 USER_NAME CHAR (10) NOT NULL,
 RMB_ACCOUNT DOUBLE,
 DOLLAR_ACCOUNT DOUBLE,
 POUND_ACCOUNT DOUBLE,
 EURO_ACCOUNT DOUBLE,
 JPY_ACCOUNT DOUBLE,
 HKD_ACCOUNT DOUBLE,
 TWD_ACCOUNT DOUBLE,
 KRW_ACCOUNT DOUBLE
 );
EXEC SQL END DECLARE SECTION;

清单 8 中,"EXEC SQL BEGIN DECLARE SECTION" 和 "EXEC SQL END DECLARE SECTION" 之间声明了程序将会连接的数据库表和相关变量,这是 CICS 操作 DB2 的用法,必须在 main 函数前首先声明。从这个 DECLARE SECTION 中可以看到程序将会操作数据库名为 LIUGUAN 下的 USERDEMO 表。该表的结构如 SECTION 所示,已在主机 DB2 中建好。完成相关的声明,在函数内部才能使用 CICS 操作 DB2 的 API。

清单 9. CICS Web service API 的应用:

//* put data in the container and send the request to get rate value
 EXEC CICS PUT CONTAINER(name_container)
 CHANNEL(channel_name)
 FLENGTH(sizeof(rateout.getRate))
 FROM(rateout.getRate);
 
 //* invoke the web service which provides rate value
 EXEC CICS INVOKE WEBSERVICE(webservice)
 CHANNEL(channel_name)
 OPERATION(operation)
 URI(uri)
 RESP(respcode)
 RESP2(resp2);
 
 //* get the reponse from the container
 EXEC CICS GET CONTAINER(name_container)
 CHANNEL(channel_name)
 INTO(&ratein)
 FLENGTH(ratein_len);
 ratein.getRateResponse.getRateReturn??(32??) = '\0';
 
 //* transfer from char[] to double
 double ratevl = atof(ratein.getRateResponse.getRateReturn);
 double rmbvl = atof(ws_input->sum);
 double destvl = rmbvl * ratevl;

在清单 9 中:

  • "EXEC CICS PUT CONTAINER" API 将要发送的请求 (Request) 数据放入 Container 内存数据区。Container 是 CICS 为处理 Web service 定义的概念,它专用于数据结构的存储。
  • "EXEC CICS INVOKE WEBSERVICE" API 调用 RateService,将 Container 中的请求数据发送给 RateService。
  • RateService 处理完请求并返回 (response) 数据,返回数据仍然存储在先前请求数据所存储的 Container 中。"EXEC CICS GET CONTAINER" API 就是从该 Container 取出返回数据并存入 ratein 变量中。此时 ratein 的值就是相应的汇率值。经过一系列数据类型转换,最后 destvl 变量中存储的就是美元账户中需要新增的数额。

清单 10. CICS DB2 API 的应用:

 EXEC SQL SELECT DOLLAR_ACCOUNT INTO :target_account
 FROM LIUGUAN.USERDEMO 
 WHERE USER_NAME=:dbuser;
 target_account = target_account + destvl;
 EXEC SQL UPDATE LIUGUAN.USERDEMO SET
 DOLLAR_ACCOUNT=:target_account
 WHERE USER_NAME=:dbuser;
 EXEC SQL UPDATE LIUGUAN.USERDEMO SET
 RMB_ACCOUNT=:rmb_account
 WHERE USER_NAME=:dbuser;

在清单 10 中:

首先从 DB2 中查找到该用户的美元账户余额付给变量 target_account 存储起来;destvl 是计算好的转账金额,新的美元账户需要加上这部分金额;最后在 DB2 中更新该用户的美元和人民币账户。CICS DB2 API 中的参数要求用冒号 ":" 加变量名来表示,如 :target_account。

CICS 会把这一系列操作作为事务处理,保证其 ACID 的事务特性,即原子性 (Atomic)、一致性 (Consistent)、隔离性 (Isolated)、永久性 (Durable)。TRANSFER 程序的源码在附件中提供了下载。

通过 JCL 调用 C 程序编译器编译 TRANSFER 程序。

在 JCL 中必须指明程序要绑定的 DB2 PLAN,它与之后定义的 CICS DB2 ENTRY 资源中指定的 PLAN 相同。JCL 执行的最大返回值通常是 4,这说明有警告出现,但可以忽略,视为编译成功。至此,TransferService 相关的程序开发完成。接下来需要在 CICS 区域 (Region) 上定义 TransferService 所需要的所有资源。

5.CICS 上定义 Web service 相关资源 ? 定义 Pipeline:

因为 TransferService 同时充当了 Web service 的 provider 和 requester,所以需要定义两个 PIPELINE 资源。一个作为 requester 处理发送到 RateService 的 soap 包,一个作为 provider 处理客户端发送来的 SOAP 请求。

  • CEDA DEF PIPELINE(PIPERATE) G(CNTEST) 定义作为 requester 时使用的 PIPELINE,名为 PIPERATE,置于 CNTEST 组 (GROUP) 下。需要配置三个选项:Configfile, SHelf 和 Wsdir。Configfile 指明该 PIPELINE 的类别,是作为 requester 使用还是作为 provider 使用;SHelf 指定一个目录存放 PIPELINE 的描述文件;Wsdir 指定 wsbind 文件的位置,如图 5 所示。

图 5. 定义 PIPELINE(PIPERATE)

  • CEDA DEF PIPELINE(PIPETRAN) G(CNTEST) 定义作为 provider 时使用的 PIPELINE,名为 PIPETRAN,仍然置于 CNTEST 组 (GROUP) 下。同样需要配置三个选项:Configfile, SHelf 和 Wsdir。如图 6 所示。

图 6. 定义 PIPELINE(PIPETRAN)

定义 Tcpipservice:

CEDA DEF TCPIPS(TCPTRAN) G(CNTEST) 定义作为 provider 时必须提供的网络服务资源,需要配置两个选项:port 和 portocol。port 指明端口号,protocol 设定协议为 Http。

定义 DB2 Connection:
CEDA DEF DB2C(CONNDBV8) G(CNTEST),定义了名为 CONNDBV8 的 DB2 Connection 并置于组 CNTEST 下。这是任何一个 CICS 程序连接 DB2 数据库,无论是否用到 Web service,都必须指定的。

定义 DB2 Entry:

CEDA DEF DB2E(TEST) G(CNTEST),定义名为 TEST 的 DB2 Entry,同样置于组 CNTEST 下。这也是任何一个 CICS 程序连接 DB2 数据库必须定义的资源。

定义应用程序:

CEDA DEF PROG(TRANSFER) G(CNTEST) 将程序 TRANSFER 定义在 CICS 区域。

通过以上步骤,所有资源的定义完成,最后还需要安装它们。

6. 在 CICS 上安装所有资源:

因为以上定义的资源都置于 CNTEST 组的管理下,因此最简单的安装方式就是直接安装这个组。通过下面这个命令来完成:
CEDA INST GROUP(CNTEST)

至此,部署在 CICS 上的 TransferService 全部完成。

7. 生成 wsdl 文件:

TransferService 部署在 CICS 上,还需要将自己提供的服务以 wsdl 文件的形式发布到 WSRR 上。所以,首先需要利用 CICS 3.2 工具包中的 DFHLS2WS 程序根据 TRANSFER 程序规定的输入输出数据结构生成 wsdl 文件。用 JCL 调用 DFHLS2WS 的源码如清单 11 所示:

清单 11. 调用 DFHLS2WS 生成 wsdl 文件的 JCL 源代码:

***************************** Top of Data *************************
//LS2WS1 JOB (WINMVS,LIUGUAN),MSGCLASS=H, 
// CLASS=A,NOTIFY=&SYSUID,REGION=0M 
//* 
//MYPROC JCLLIB ORDER='CTS320.CICS650.SDFHINST' 
//LS2WS EXEC DFHLS2WS, 
// PATHPREF='',TMPFILE='LIUGUAN', 
// USSDIR='cerbsf' 
//STEPLIB DD DSN=CTS320.CICS650.SDFHINST,DISP=SHR 
// DD DSN=LIUGUAN.ACICS.WSAT.SOURCE,DISP=SHR 
//INPUT.SYSUT1 DD * 
LOGFILE=/u/liuguan/userdemo/wsserver/transfer.log 
PDSLIB=//LIUGUAN.ACICS.WSAT.SOURCE 
REQMEM=TRANSI 
RESPMEM=TRANSO 
LANG=C 
PGMNAME=TRANSFER 
STRUCTURE=(CMDINPUT,OUTPUT) 
URI=transfer 
PGMINT=COMMAREA 
WSBIND=/u/liuguan/userdemo/wsserver/wsbind/transf.wsbind 
WSDL=/u/liuguan/userdemo/wsdl/transfer.wsdl 
/* 
**************************** Bottom of Data ********************** 

PDSLIB 表示输入输出定义的 member 所在的 dataset。

REQMEM 表示输入结构定义的 member。RESPMEM 表示输出结构定义的 member。

LANG 指定编程语言的类型。

PGMNAME 指定提供 Web service 的程序。

URI 指定作为 service provider 端使用的链接标识。

PGMINT 是作为 service provider 端必须指定的参数,表示用什么资源来存储 SOAP 请求中的数据格式转换为编程语言的数据结构。有 COMMAREA 和 CHANNEL 两种方式。

WSBIND 和 WSDL 两个参数的意义同上文 DFHWS2LS。

JCL 执行成功之后,可在主机 USS 的 /u/liuguan/userdemo/wsdl 目录下产生 transfer.wsdl 文件。

8. 发布 TransferService 到 WSRR

最后利用 CICS SupportPac for WSRR 工具包中的 DFHWS2SR 将该文件发布到 WSRR 上,JCL 调用 DFHWS2SR 的源码如清单 12 所示。JCL 执行成功,可在浏览器 WSRR 控制台下看到 transfer.wsdl 文件。客户可以通过该文件获取 TransferService 的相关信息,并调用转账服务完成自己的业务逻辑。

清单 12. 调用 DFHWS2SR 发布 wsdl 文件到 WSRR 的 JCL 源代码:

***************************** Top of Data **********************
//DWS2SR01 JOB (MYSYS,AUSER),MSGCLASS=H, 
// CLASS=A,NOTIFY=&SYSUID,REGION=0M 
//WSDLPUB JCLLIB ORDER=LIUGUAN.CA1N.JCL 
// EXEC DFHWS2SR, 
// JAVADIR='java142s/J1.4', 
// WORKDIR='/u/liuguan/install', 
// TMPDIR='/tmp', 
// TMPFILE='WS2SR' 
//INPUT.SYSUT1 DD * 
HOSTPORT=http://cicsrts3.hursley.ibm.com:9080 
LOGFILE=/u/liuguan/wsrrtest/log/transfer.log 
LOCATION=/u/liuguan/userdemo/wsdl/transfer.wsdl 
NAME=TRANSFER 
*/ 
**************************** Bottom of Data ********************

第三步:网上银行调用转账服务

1. 开发环境

开发平台:Windows 操作系统,IBM Rational Application Developer 7.0.0( 内置 Websphere Application Server 6.1)

开发语言:Java

2.开发实例

最后给出一个简单的例子,用 Struts 框架实现客户登录网上银行并转账的 web 应用程序。当然,基于 Web service 跨平台、互操作性强的特点,用户可以使用其他任何平台、任何语言来实现网上银行,调用 CICS 提供的转账服务。网上银行有关页面显示和访问主机 DB2 数据库的代码不再赘述,和其他 web 应用程序一样。这里要给出的是在 Action 里完成业务逻辑时,如何调用 CICS 上部署的 TransferService.

首先从 WSRR 上下载 transfer.wsdl 文件,通过该文件在 RAD 集成环境中生成 Web service 客户端框架。生成的代码如图 7 所示:

图 7. TransferService 客户端框架代码结构

然后在 Action 中编写调用 TransferService 的代码如清单 13:

清单 13. 调用 TransferService:

// 创建客户端代理对象,通过该对象调用 TransferService
TRANSFERPortProxy sampleTRANSFERPortProxy = new TRANSFERPortProxy();

// 创建 request 对象,即 TransferService 的输入
Cmdinput cmdinput = new Cmdinput();

// 从页面获取用户对象
String user = (String) request.getSession().getAttribute("user");
tform.setUser(user);

// 将用户页面输入的信息封装进 request 对象
cmdinput.setUser(tform.getUser());
cmdinput.setSum(tform.getAmount());
cmdinput.setSource(tform.getSource());
cmdinput.setTarget(tform.getTarget());

// 创建 response 对象,即 TransferService 的输出
Output output = new Output();

// 通过客户端代理对象调用 TransferService 提供的服务操作 TransferOperation,将 request 对象作为参数传入
output = sampleTRANSFERPortProxy.TRANSFEROperation(cmdinput);

程序部署在 WAS6.1 上。成功启动服务器后,通过浏览器访问此 web 应用程序,可以看到模拟的网上银行页面,如图 8 所示,网上银行创建成功。

图 8. 网上银行登录页面

3.网上银行运行效果演示

输入用户名和密码,进入网上银行转账页面,该页面显示了用户当前各币种账户的余额。如图 9 所示:

图 9. 网上银行转账页面

在页面上选定源账户 (Source)、目标账户 (Target),输入转账金额 (Amount),并提交便可完成转账业务。转账信息如图 10 所示:

图 10. 网上银行转账结果显示

图 10 所示页面表示用户转账操作成功,也同时意味着网上银行成功调用 CICS 提供的 TransferService。至此,CICS 应用程序作为 Web service 的 requester 和 provider 都成功编写。

结束语

通过引入 SOA 架构的思想,将 CICS 上原本耦合性很强的转账服务拆分成汇率服务和转账服务。通过 Web service 实现了这些服务的封装及其互操作以及与其他任意平台任意语言的应用程序进行互操作,极大的提高了程序的扩展性与可重用性。本文通过模拟客户转账的经典应用,介绍了 CICS Web service 的相关概念和具体用法。相信通过本文,有一定主机和 Web service 经验的初级用户也可以自己开发出 CICS 上的 Web service 程序。


相关文章

企业架构、TOGAF与ArchiMate概览
架构师之路-如何做好业务建模?
大型网站电商网站架构案例和技术架构的示例
完整的Archimate视点指南(包括示例)
相关文档

数据中台技术架构方法论与实践
适用ArchiMate、EA 和 iSpace进行企业架构建模
Zachman企业架构框架简介
企业架构让SOA落地
相关课程

云平台与微服务架构设计
中台战略、中台建设与数字商业
亿级用户高并发、高可用系统架构
高可用分布式架构设计与实践

 
分享到
 
 
     


基于SOA的工作流(WF)整合
SOA 100问 - 问与答
SOAP 应用模式:处理与性能
ESB架构之企业实施案例
基于SOA架构的企业集成系统
基于SOA的体系架构设计
更多...   


面向应用的架构设计实践
单元测试+重构+设计模式
软件架构师—高级实践
软件架构设计方法、案例与实践
嵌入式软件架构设计—高级实践
SOA体系结构实践


某第三方电子支付企业 SOA架构设计
某电子企业 SOA应用
中国移动 SOA培训
北京大学 SOA架构设计实践
友邦保险 SOA架构设计
上海 SOA架构实践
山东移动通信 SOA体系结构实践
更多...