用于 B2B 集成的 Web 服务和 J2EE 连接器
Web 服务和 J2EE
连接器承诺能够简化不同种类的企业信息系统的集成,并且在因特网上为业务合作伙伴提供共享他们各自应用功能的方式。这篇文章使用了一个保险代理方案来说明
这些性能,它将来自旧的事务的程序化功能融入到 Web 应用程序中。请单击本篇文章的顶部或底部的 讨论,与作者和其他读者在
交流关于这篇文章的观点。
电子商务世界是一个快速变化的环境,如果一个企业要获得具有竞争性的优势,新的功能以及紧跟市场是至关重要的。企业需要集成系统、自动化处理过程,以及以统一、开放的方式为它们的合作伙伴提供对关键数据和服务的访问。
但是,潜在的障碍是许多公司支持不同的计算环境,其中不同的企业信息系统(EIS)使用专有协议来访问数据和进行互相通信。典型的情况是,事务以旧的应用程序的形式存在,这些旧的应用程序是用过程化语言(比如:COBOL 或 C)编写的。
所幸,对于这种专有性难题,结合使用 Web 服务和 J2EE 连接器技术是很好的解决方案。J2EE 连接器为开发者访问旧的事务和数据提供了接口,而 Web 服务为在 Web 上展现应用程序功能提供了统一的、基于标准的技术。
在这篇文章中,我们将使用在线保险代理应用程序作为怎样用 J2EE 连接器和 Web 服务来集成不同种类的 EIS 的示例。
保险代理方案
通
过将由不同保险公司提供的应用程序功能聚集到单一的基于 Web
的接口中,保险代理为客户提供增值服务。使用保险代理应用程序,客户能够快速、容易地得到来自不同保险公司的保险报价和详细的保单信息。通过使用户免于必
须分别填写每一份保险公司的应用表单,保险代理改善了全面的用户体验。此外,客户能够得到个人的保单报价以及信息,然后人工地对它们进行比较。
实际上是 Web 服务和 J2EE 连接器技术使得 B2B 方案成为可能。保险公司将当前的 EIS 事务展现为 Web 服务,而保险代理应用程序以编程方式调用这些 Web 服务为客户提供增值功能,如图 1 图解所示。
为了便于这篇文章中的讨论,我们把提供 Web 服务的保险公司标为 Company B,同时,请求 Web 服务的公司 ― 保险代理 ― 为 Company A。
构建 Web 服务供应商
在
我们的方案中,如图 2 所示,Company B 想要将旧的保险事务展现为 Web 服务操作。旧的事务用 COBOL 编写,并且在 390
大型机运行的 CICS 下执行。这个应用程序服务器主管一个 Java bean 或会话 bean。这个 bean 定义了通过 CICS 的遵循
J2EE 的资源适配器调用 CICS 事务的方法。
服务器端编程模型 ― Company B 的开发者生产和发布服务所需的活动 ― 包括以下的步骤:
- 创建服务描述(即,构建 WSDL 文件)
- 测试新创建的服务
- 将 Web 服务部署到启用 Web 服务的 Web 服务器
- 将 Web 服务发布到 UDDI,使其能被其他人发现和调用
为 EIS 系统专门构建 Web 服务供应商要求有设计来能够访问旧的事务的附加步骤。
- 捕获事务元数据 ― 即,输入和输出记录的定义
- 通过遵循 J2EE 的资源适配器执行旧的事务
- 构建 Java 虚包(Java bean 或 会话 EJB),能够容易地展现为 Web 服务
在下面的章节中,我们将讨论您可以很快完成这些步骤的编程技术以及工具。
使用 J2EE 连接器来访问 EIS 事务
J2EE
平台包括访问非关系 EIS 的“ J2EE
连接器规范”。该规范定义了一系列使允许供应商开发和分发称之为资源适配器的可插入的应用程序服务器组件。能够将遵循 J2EE
的资源适配器部署到任何遵循 J2EE 的应用程序服务器中。在应用程序服务器内运行的组件(比如:Java bean、EJB 以及
servlet)能够通过“公共客户接口”(Common Client
Interface,CCI)对资源适配器进行调用。资源适配器通过本机协议(比如:用于 CICS 的 ECI 或 EPI)将 CCI
调用转换成为对 EIS 的调用。图 3 说明了它们之间的关系。EIS 供应商将典型地提供资源适配器。应用程序开发者使用 CCI
与资源适配器进行交互。
清单 1 中摘录了 CICS 通过遵循 J2EE 的资源适配器使用公共客户接口(CCI)访问 EIS 数据的代码。
清单 1. 使用 CCI 访问 EIS 数据
/* Using CCI to access CICS transactions via ECI. Exception handling omitted for brevity. */ // Class definition imports import com.ibm.connector2.cics.*; // J2EE CICS Connector import javax.naming.Context; import javax.resource.cci.*; // etc... public double getTravelPremium(int numDays, int age, int amount) { // Configure ECIConnectionSpec -- EIS security parameters ECIConnectionSpec cspec = new ECIConnectionSpec("admin", "admin"); // Get a connection to the EIS -- non-managed scenario Context nc = new InitialContext(); ECIConnectionFactory cf = (ECIConnectionFactory)nc.lookup( "java:comp/env/eis/ECIConnectionFactory"); Connection cx = cf.getConnection(cspec); // Prepare for interaction with the EIS -- e.g. CICS via ECI // TRPREM is a legacy CICS transaction which computes travel premium ECIInteractionSpec ispec = new ECIInteractionSpec(); ispec.setFunctionName("TRPREM"); ispec.setInteractionVerb(InteractionSpec.SYNC_SEND_RECEIVE); // Prepare records -- custom records implement javax.resource.cci.Record CustomerInfoRecord custRec = new CustomerInfoRecord(); // Input PremiumInfoRecord premRec = new PremiumInfoRecord(); // Result custRec.setAge(age); custRec.setNumDays(numDays); custRec.setLimit(amount); // Execute the transaction Interaction ix = cx.createInteraction(); ix.execute(ispec, custRec, premRec); // Close the connection cx.close(); // Retrieve results from the result record double premium = premRec.getPremium(); return premium; } |
由于 CCI
提供了基本的交互模型,开发者将特别需要使用工具来帮助捕获旧的事务元数据,生成遵循 J2EE 的记录,以及简化与 CCI
的交互。例如,VisualAge for Java 企业版 4.0,提供了面向事务的称为“企业访问构建器”(Enterprise Access
Builder,EAB)的功能。EAB 定义了能使开发者以面向对象的方式使用旧的事务的编程模型和一系列 bean。按照 EAB
编程模型,开发者:
- 导入定义事务输入和输出的元数据。元数据存储在叫做 RecordTypes 的 Java bean 表单中。
- 将 RecordTypes 转换(包装)成为遵循 J2EE 的记录。这些 bean 变成 J2EE 资源适配器的输入和输出。
- 构造命令。命令是包装与资源适配器进行的交互的 Java bean。
图 4 说明了 EAB 命令 bean。请注意命令 bean 对开发者隐藏了使用资源适配器进行交互的结构。用来构造 bean 的工具生成的输入和结果记录,以及在设计时设置连接和交互规范属性。如果需要,这些可以在运行时重新设置。
现在我们将准备构造虚包,将相应地展现为 Web 服务。
将事务展现为 Web 服务
Web 服务定义包含了能够包括任意量操作的接口描述。目前,可用的工具允许由 Java bean 创建 Web 服务;换句话说,Web 服务本质上是包装了 bean。在 bean 定义的方法成为在 Web 服务接口中定义的操作。
在我们的保险应用程序方案中,我们可以开发带有一系列方法的 bean,每一种方法执行包装了与旧的 CICS 事务进行交互的命令
bean。每一个事务执行要求计算保险费用、提供预算和购买保单的业务逻辑。对于 EIS,我们的 bean
变成便捷的虚包。它聚集了相关的业务逻辑,并且能够容易地展现为 Web 服务。清单 2 展示了一个 bean 方法实现的示例, getTravelPremium() ,来自一个专为假设的 PolicyTransact 公司而构建的虚包。
清单 2. JavaBean 方法实现示例
/* getTravelPremium() method in PolicyTransact bean*/ public double getTravelPremium(int numDays, int age, int amount) { // Command pre-configured for CICS ECI access // ConnectionSpec and InteractionSpec properties already set at design or run-time // Set properties on the input record fPremiumCommand.getInput().setDAYS(numDays); fPremiumCommand.getInput().setAGE(age); fPremiumCommand.getInput().setLIMIT(amount); // Executing the command invokes transaction on EIS fPremiumCommand.execute(); // Exception handling // Retrieve result from output record double premium = fPremiumCommand.getOutput.getPREMIUM(); return premium; } |
既然我们已经构造了我们的虚包,所剩下的就是生成 WSDL 文件。接着我们可以在 UDDI 注册中心(这里叫做 Company B)中创建业务实体并上载 WSDL 文件。
构建 Web 服务请求者
现在 Company A 可以开始构建代理应用程序。但是在 Company A 能够调用由 Company B 提供的 Web 服务之前,它需要发现什么服务可用,然后下载服务定义。
为了访问 Web 服务并将它们运用到应用程序中,开发者需要完成下面的步骤:
- 发现和导入服务描述(WSDL 文件)
- 生成 Java 代理
- 在您的应用程序中调用代理方法
可以通过业务注册中心(比如:“UDDI 业务注册中心”或另一个专用业务注册中心)定位 Web 服务。UDDI 依靠业务及其服务描述(以通用 XML 格式实现)的分布的注册中心管理 Web 服务的发现。
在
我们的方案中,Company B 已经在“IBM UDDI 测试注册中心”中发布了 Web 服务。因此,Company A
的保险代理应用程序开发者只需要搜索“IBM UDDI 测试注册中心”,找到名为 Company B
的业务实体,然后搜索“保险报价”(Insurance Quotation )服务接口。
注册中心包括 Company B 的 Web 服务 WSDL 文档的 URL
引用。该服务 WSDL 文档可以导入它所需要的别的 WSDL 文档,包括绑定 WSDL 文档。服务 WSDL
文档包含服务的位置。绑定文档为由特定的端口类型定义的操作和消息定义了协议和格式。
一旦我们有了 WSDL 文档,我们可以创建 Java 代理 bean(如清单 3 所示),它包含了与在 WSDL 文档中描述的操作相对应的一系列方法。
清单 3. Web 服务 Java 代理
/* PolicyTransactProxy class */ public class PolicyTransactProxy { private Call call = new Call(); private URL url = null; private String SOAPActionURI = ""; private SOAPMappingRegistry smr = call.getSOAPMappingRegistry(); public PolicyTransactProxy() throws MalformedURLException { call.setTargetObjectURI("urn:PolicyTransact"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); this.url = new URL("http://localhost:8080/test/servlet/rpcrouter"); this.SOAPActionURI = "urn:PolicyTransact"; } public synchronized double getTravelPremium(int numDays,int age,int amount) throws Exception { if(url == null) { throw new SOAPException(Constants.FAULT_CODE_CLIENT, "URL must be specified via " + "PolicyTransactProxy.setEndPoint(URL)."); } call.setMethodName("getTravelPremium"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); // set up the parameters ... // invoke the Web service via SOAP Response resp = call.invoke(url, SOAPActionURI); //Check the response. if (resp.generatedFault()) { Fault fault = resp.getFault(); throw new SOAPException(fault.getFaultCode(), fault.getFaultString()); } else { Parameter refValue = resp.getReturnValue(); return ((java.lang.Double)refValue.getValue()).doubleValue(); } } } |
图 5 展示了 Company A
的保险代理应用程序的体系结构。应用程序基于 HTML 的用户界面以 servlet 和 JSP
来实现。应用程序服务器也主管用来实现保险费预算和购买过程的会话 EJB。为了从其它供应商获得保险费估算,会话 EJB 对 Web 服务
Java 代理进行调用。
使用 Java 代理 bean,我们可以容易地从基于 Java 的应用程序调用 Web 服务,如清单 4 中所示。
清单 4. 调用一个 Web 服务
// Create an instance of the Web service Java proxy PolicyTransactProxy policyTransactWebService = new PolicyTransactProxy(); // Invoke the service method double premium = policyTransactWebService.getTravelPremium(numDays, age, amount); |
总结
Web
服务和 J2EE 连接器自然适合于在基于 Web 的 B2B 协作环境集成不同种类的 EIS。Web
服务为展现并访问企业功能性提供了开放、统一、高水平的技术。J2EE
连接器规范为访问旧的事务和数据提供了标准的接口。通过结合这两种技术,应用程序开发者能够在 Web 上容易地展现和访问 EIS 事务。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/374079/viewspace-130748/
,如需转载,请注明出处,否则将追究法律责任。