WebSphere JCA Adapter 开发入门
来源:互联网 发布:如何做好一个淘宝客 编辑:程序博客网 时间:2024/05/16 18:38
IBM WebSphere JCA Adapter 是沟通 WebSphere Process Server 和 EIS 之间的桥梁,本文通过一个简单实例介绍了开发 WebSphere JCA Adapter 的基本步骤。
JCA (Java 2 Enterprise Edition (J2EE) Connector Architecture)是J2EE规范中重要的一环,为J2EE应用程序和其它企业信息系统(EIS)之间的交互制定了标准。IBM WebSphere Process Server(WPS)是构筑在J2EE之上的企业应用集成服务器,IBM WebSphere JCA Adapter就是配合WPS使用的,既符合JCA规范又支持WPS优秀集成特性的产品家族。目前最新的是6.0.2版,主要包括如下Adapter:
- IBM WebSphere Adapter for JDBC
- IBM WebSphere Adapter for Flat Files
- IBM WebSphere Adapter for PeopleSoft Enterprise
- IBM WebSphere Adapter for SAP Software
- IBM WebSphere Adapter for Siebel Business Applications
- IBM WebSphere Adapter for Email
- IBM WebSphere Adapter for FTP
- IBM WebSphere Adapter for JD Edwards EnterpriseOne
- IBM WebSphere Adapter for Oracle E-Business Suite
IBM WebSphere JCA Adapter 架构
所需知识背景本文假定读者熟悉J2EE,并对JCA规范有所了解。如果不熟悉JCA,最好先读一下JCA 1.5规范的以下章节:概述,包括1,2,3章;Outbound 相关,包括6,15章。
WebSphere Adapter使用Service Data Object(SDO)规范来表示数据,如果读者有SDO相关知识,将有助于理解相关内容。
IBM WebSphere JCA Adapter完全符合JCA 1.5规范。JCA Adapter规范规定了连接和操作EIS的协议,但是对所交换的数据规范没有指定。在WPS中,核心的数据规范是Business Object,简称BO。BO从技术实现的角度讲是Service Data Object(SDO),一种标准化的数据接口。WebSphere JCA Adapter使用SDO与WPS来交换数据。
连接不同的EIS的Adapters有很多共性,对每个Adapter都完全从实现JCA接口开始白手起家显然是没有必要的。因此,IBM开发了Adapter Foundation Classes作为WebSphere JCA Adapter的开发框架。它提供了JCA 接口的抽象实现,以及在Adapter之间可以重用的基本功能,并提供了Assured Event Delivery等QoS服务,而将与EIS密切相关的功能留给具体的Adapter来实现,从而大大简化了Adapter的开发工作。
下图表明WebSphere Adapter的基本架构:
图 1. Adapter的基本架构
从上图可以看出,Adapter Foundation Classes提供了JCA 1.5规范的框架实现,Adapter特有部分扩展并细化这一框架,实现对EIS的操作,并通过SDO规范与WPS交换数据。有了Adapter Foundation Classes,开发Adapter的工作量大为减少,只要实现上图中的蓝色部分,开发主要关注点为对不同EIS的操作。
古人云:绝知此事要躬行,以下本文将以一个连接虚拟的EIS(Mock EIS)的MockAdapter为例简要描述了如何基于WebSphere Adapter Foundation Classes 6.0.2 版,一步步开始开发符合WebSphere 框架的JCA Adapter。以此来更好的了解Adapter的工作原理。MockAdapter将只支持由J2EE应用程序发起的对EIS的操作(在JCA规范中称为Outbound操作)。
开发工具和Adapter Foundation Classes库文件
和WPS配套的开发工具是WebSphere Integration Developer(WID),它是基于Eclipse技术的企业应用集成开发环境。我们需要使用WID这个工具来开发WebSphere JCA Adapter。在WID 6.0.2的安装目录下,可以找到Resource Adapters目录,其中包括了所有可用的JCA Adapter。将某个Adapter,如FlatFile的RAR文件导入WID中,你会在connectModule目录下发现CWYBS_AdapterFoundation.jar,这就是Adapter Foundation Classes。
回页首
Mock EIS
为了简化,本文不使用任何现实的EIS,而是用一个Mock EIS 类来模拟一个EIS,这样的好处是你无需了解任何EIS API的调用,通常那是很复杂的。Mock EIS是一个二元计算服务,可以计算加减乘除。
使用Mock EIS的程序,首先要用setOperation()
设置运算符,然后调用calculate()
计算得出结果。
代码清单 1.MockEIS.java
package com.ibm.eis.mock; public class MockEIS { String operation = "+"; public MockEIS(){ } /** * @param operation The operation to set. */ public void setOperation(String operation) { this.operation = operation; } /** * Calculate the result. * @param x * @param y * @return */ public float calculate(float x, float y){ float result = Float.NaN; if(operation.equals("+")){ result = x + y; }else if(operation.equals("-")){ result = x - y; }else if(operation.equals("*")){ result = x * y; }else if(operation.equals("/")){ result = x / y; } return result; }}
回页首
先期准备:创建Business Object定义
由于SDO是一种需要预先定义数据格式的规范,并且使用XML Schema文件来描述数据格式,在WPS/WID中称为Business Object 定义。我们首先要确定EIS所需要处理的数据格式,并将它映射到一个适当的Business Object 定义。在Mock EIS中需要处理的数据包括运算数和结果,可以作为属性封装在一个BO中。
我们是用WID的BO编辑器来创建BO。首先创建一个新Business Object,命名为MockBO,为它添加X,Y,Result三个属性,然后为它生成一个Business Graph(BG),BG是SDO规范中规定的BO的包装器,用来纪录BO的变化和某些附加信息,可以看作是一种特殊的BO。在WebSphere Adapter中,接受和发送的数据对象都是以BG包装的BO。
创建完成的BO如下图所示:
图 2. MockBO 定义
BO的定义会保存为XML Schema文件,切换到资源透视图,可以在模块工程目录下找到MockBO.xsd和MockBOBG.xsd两个文件。
回页首
第一步:创建Connector Project
在WID中切换到J2EE perspective,创建一个Connector Project。注意要选择WebSphere Process Server 6.0作为该Project的server,然后,把Foundation Classes的Jar文件CWYBS_AdatperFoundation.jar导入到该project的connectorModule 目录下,并添加到build path中。接下来,将刚才创建的BO定义文件,即MockBO.xsd和MockBOBG.xsd复制到connectorModule,以便将来BO定义随Adapter一同部署。
回页首
第二步:创建Resource Adapter主类
用文本方式打开ra.xml文件,目前只有对MockAdapter的简单描述,将各项描述添全。
<display-name>IBM Mock Adapter for QA</display-name> <vendor-name>IBM CSDL AIA</vendor-name> <eis-type>Mock EIS</eis-type> <resourceadapter-version>1.0.0</resourceadapter-version>
接着创建Mock Adapter的ResourceAdapter类,类名为com.ibm.j2ca.mock.MockAdapter,将此添加到ra.xml中。
<resourceadapter> <resourceadapter-class>com.ibm.j2ca.mock.MockAdapter</resourceadapter-class> ...... </resourceadapter>
通过继承WBIResourceAdapter类创建MockAdapter类。WBIResourceAdapter类在com.ibm.j2ca.base包中(大部分Adapter需要继承的基类都在这个包中,如不特别指出,以下文中提到的需要继承的类都属于这个包)。唯一必须实现的方法是getResourceAdapterMetadata,返回描述该Adapter的WBIResourceAdapterMetadata实例。注意,该类需要符合Java Bean规范,即必须有public无参数的缺省构造函数。
代码清单 2.MockAdapter.java
package com.ibm.j2ca.mock;import javax.resource.ResourceException;import com.ibm.j2ca.base.WBIResourceAdapter;import com.ibm.j2ca.base.WBIResourceAdapterMetadata;public class MockAdapter extends WBIResourceAdapter { public MockAdapter() super(); } public WBIResourceAdapterMetadata getResourceAdapterMetadata() throws ResourceException { return new WBIResourceAdapterMetadata( "IBM Mock Adapter", "IBM CSDL ", "1.0.0", false); }}
回页首
第三步:实现对EIS的连接管理逻辑
WebSphere Adapter要连接EIS,必须实现JCA规范中的Connection管理逻辑。包括四个主要接口:Connection,ManagedConnection,ManagedConnectionFactory,ConnectionFactory。
首先要确定的是连接特定的EIS需要的属性值,必需的属性要加在实现ManagedConnectionFactory接口的类里,如hostname,port,username,password之类。Mock EIS唯一需要设置的就是操作符Operation。因此Mock Adapter只需要一个ManagedConnectionFactory属性:Operation
。
各个接口的实现类以及ManagedConnectionFactory的属性需要在ra.xml里加以描述。在ra.xml <resourceadapter>标签下加上如下信息,来描述Adapter的outbound功能,指明各个接口的实现类名。
<outbound-resourceadapter> <connection-definition> <managedconnectionfactory-class> com.ibm.j2ca.mock.MockManagedConnectionFactory </managedconnectionfactory-class> <config-property> <config-property-name>Operation</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value></config-property-value> </config-property> <connectionfactory-interface> javax.resource.cci.ConnectionFactory </connectionfactory-interface> <connectionfactory-impl-class> com.ibm.j2ca.mock.MockConnectionFactory </connectionfactory-impl-class> <connection-interface>javax.resource.cci.Connection</connection-interface> <connection-impl-class>com.ibm.j2ca.mock.MockConnection</connection-impl-class> </connection-definition> <transaction-support>NoTransaction</transaction-support> <reauthentication-support>false</reauthentication-support></outbound-resourceadapter>
接着分别实现这四个接口:
Connection:Foudation Classes提供了Connection接口的抽象实现WBIConnection,MockConnection继承并该类。唯一必须实现的方法是createInteraction,提供outbound操作需要的Interaction接口的实现MockInteraction(将在下一步中描述)。
代码清单 3.MockConnection.java
package com.ibm.j2ca.mock; import javax.resource.ResourceException;import javax.resource.cci.Interaction;import com.ibm.j2ca.base.WBIConnection;import com.ibm.j2ca.base.WBIManagedConnection;public class MockConnection extends WBIConnection { public MockConnection(WBIManagedConnection mc) throws ResourceException { super(mc); } public Interaction createInteraction() throws ResourceException { return new MockInteraction(this); }}
ManagedConnection:对EIS真正的连接通过实现ManagedConnection接口完成。Foundation Classe提供了抽象实现WBIManagedConnection。Mock Adapter要继承WBIManagedConnection并完成对EIS连接的操作,如创建和关闭连接。MockManagedConnection所要做的是创建一个MockEIS对象来代表一个连接。需要实现的方法有:
- getMetaData方法返回关于EIS的一些信息。
- getWBIConnection方法,进行认证并返回一个对应的JCA Connection对象,这里将是MockConnection。
- destory方法,释放对EIS的连接。
- getMockEIS方法,使得Adapter其他部分可以访问EIS。
代码清单 4.MockManagedConnection.java
package com.ibm.j2ca.mock;import javax.resource.ResourceException;import javax.resource.spi.ManagedConnectionMetaData;import javax.resource.spi.security.PasswordCredential;import javax.security.auth.Subject;import com.ibm.eis.mock.MockEIS;import com.ibm.j2ca.base.WBIConnectionRequestInfo;import com.ibm.j2ca.base.WBIManagedConnection;import com.ibm.j2ca.base.WBIManagedConnectionFactory;import com.ibm.j2ca.base.WBIManagedConnectionMetaData;/** * @author Donny * */public class MockManagedConnection extends WBIManagedConnection { private MockEIS mockEIS ; public MockManagedConnection(WBIManagedConnectionFactory factory, Subject sub, WBIConnectionRequestInfo request,MockEIS eis) throws ResourceException { super(factory, sub, request); mockEIS = eis; } public ManagedConnectionMetaData getMetaData() throws ResourceException { return new WBIManagedConnectionMetaData("Mock EIS", "1.0.0",10,super.getPasswordCredential().getUserName()); } public Object getWBIConnection(PasswordCredential arg0, boolean arg1) throws ResourceException { return new MockConnection(this); } public void destroy() throws ResourceException { } public MockEIS getMockEIS() { return mockEIS; } }
ManagedConnectionFactory:J2EE容器通过ManagedConnectionFactory来创建ManagedConnection。AFC提供了ManagedConnectionFactory的抽象实现WBIManangedConnectionFactory。MockManagedConnectionFactory只需要继承这个类,实现特定的属性,在这里就是Operation。同时要实现方法createConnectionFactory供J2EE服务器取得ConnectionFactory的实例,这里将是MockConnectionFactory对象;最重要的是要实现createManagedConnection返回MangedConnection对象。还必须实现在前面确定并在ra.xml文件里制定的属性所对应的get和set方法,这里即getOperation和setOperation。MockManagedConnectionFactory根据Operation属性值构造一个MockEIS实例,并由此实例构造出MockMangedConnection的一个实例。
MockManagedConnectionFactory实现如下,注意必须提供缺省构造函数使其满足Java Bean规范要求:
代码清单 5.MockManagedConnectionFactory.java
package com.ibm.j2ca.mock;import javax.resource.ResourceException;import javax.resource.spi.ConnectionManager;import javax.resource.spi.ConnectionRequestInfo;import javax.resource.spi.ManagedConnection;import javax.security.auth.Subject;import com.ibm.j2ca.base.WBIConnectionRequestInfo;import com.ibm.j2ca.base.WBIManagedConnectionFactory;public class MockManagedConnectionFactory extends WBIManagedConnectionFactory { private String operation = "+"; public MockManagedConnectionFactory() { super(); } public ManagedConnection createManagedConnection(Subject sub, ConnectionRequestInfo info) throws ResourceException { //“连接” Mock EIS,创建对MockManagedConnection MockEIS eis = new MockEIS(); eis.setOperation(this.operation); return new MockManagedConnection(this, sub, (WBIConnectionRequestInfo) info,eis); } public Object createConnectionFactory(ConnectionManager arg0) throws ResourceException { return new MockConnectionFactory(arg0,this); } public String getOperation(){ return operation; } public void setOperation(String operation){ this.operation = operation; }}
MockConnectionFactory:MockConnectionFactory需继承WBIConnectionFactory,该类已经实现了基本逻辑,子类只要实现构造函数即可。
代码清单 6.MockConnectionFactory.java
package com.ibm.j2ca.mock;import javax.resource.spi.ConnectionManager;import com.ibm.j2ca.base.WBIConnectionFactory;import com.ibm.j2ca.base.WBIManagedConnectionFactory;public class MockConnectionFactory extends WBIConnectionFactory { public MockConnectionFactory(ConnectionManager cm, WBIManagedConnectionFactory factory){ super(cm, factory); }}
到这里,连接管理的逻辑已经全部实现。
回页首
第四步:实现Interaction接口以支持outbound操作
为支持outbound操作,必须实现Interaction接口,如上一步所示,Interaction对象由MockConnection创建。Foundation Classes提供了抽象实现WBIInteraction。继承该类需要实现的唯一方法是execute,在其中根据传入的参数实现对EIS的操作。
为符合Websphere Adapter的标准,Record execute(InteractionSpec ixSpec,Record in) 函数的传入参数有相应的限制,ixSpec应当是 WBIInteractionSpec的实例,in应该是DataObjectRecord的实例。DataObjectRecord包含了一个SDO规范所定义的DataObject,即BO。
MockAdatper非常简单的实现了execute方法,分析输入的BO,取出操作数,交给MockEIS进行计算后返回一份BO副本。
如何操作BOWPS提供了BO操作的各种服务,比如创建,复制等等。Foundation Classes将这些服务封装在com.ibm.j2ca.base.AdapterBOUtil工具类中以方便调用。
代码清单 7.MockInteraction.java
package com.ibm.j2ca.mock;import javax.resource.ResourceException;import javax.resource.cci.InteractionSpec;import javax.resource.cci.Record;import com.ibm.eis.mock.MockEIS;import com.ibm.j2ca.base.AdapterBOUtil;import com.ibm.j2ca.base.DataObjectRecord;import com.ibm.j2ca.base.WBIConnection;import com.ibm.j2ca.base.WBIInteraction;import com.ibm.j2ca.base.WBIInteractionSpec;import commonj.sdo.DataObject;public class MockInteraction extends WBIInteraction { public MockInteraction(WBIConnection arg0) { super(arg0); } public Record execute(InteractionSpec ixSpec, Record record) throws ResourceException { if(!(ixSpec instanceof WBIInteractionSpec)){ throw new ResourceException("Unknown InteractionSpec type!"); } if(!(record instanceof DataObjectRecord)){ throw new ResourceException("Invalid Record type!"); } //1. 分析输入的BO,得到运算数 DataObject bg = ((DataObjectRecord)record).getDataObject(); DataObject mockBO = bg.getDataObject("MockBO"); float x = mockBO.getFloat("X"); float y = mockBO.getFloat("Y"); //2. 通过相应的连接,得到Mock EIS服务,并计算结果 MockManagedConnection mcon = (MockManagedConnection)( (WBIConnection)this.getConnection()).getManagedConnection(); MockEIS eis = mcon.getMockEIS(); float result = eis.calculate(x,y); //3. 创建输出Record DataObject outputBG = AdapterBOUtil.copyBusinessObject(bg); outputBG.getDataObject("MockBO").setFloat("Result",result); DataObjectRecord outputRecord = new DataObjectRecord(); outputRecord.setDataObject(outputBG); outputRecord.setRecordName(record.getRecordName()); return outputRecord; }}
到这里,Adapter对Outbound的支持已经完全实现,可以部署运行了。
回页首
测试:CCI 方式调用Adapter
为了在WPS上部署运行Adapter,需要将Adapter打包。首先,用wid的export功能,将Adapter所有类文件打包成为一个jar文件,比如MockAdapter.jar,并将该文件保存在工程的connectorModule目录下,这样可以在WID的集成测试环境中成功部署。
必须要有应用程序来调用Adapter,可以是jsp,ejb等。这里我们创建一个动态Web工程,使用jsp来做测试。根据J2EE的规范,还需要创建EAR工程,将Adapter工程和Web工程都包括进去。
调用Adapter很简单,首先通过JNDI查找获取ConnectionFactory实例以创建连接;然后调用Interaction的execute方法执行操作;最后关闭连接即可。
代码清单 8.MockTest.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><HTML><HEAD><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ page import="com.ibm.j2ca.base.*"%> <%@ page import="commonj.sdo.*"%> <%@ page import="javax.resource.cci.*"%><META http-equiv="Content-Type" content="text/html; charset=UTF-8"><META name="GENERATOR" content="IBM Software Development Platform"><TITLE>MockTest.jsp</TITLE></HEAD><BODY><% try{ //Step 1: 获取连接 // 1.1: 通过JNDI查找ConnetionFactory javax.naming.InitialContext initCx = new javax.naming.InitialContext(); String jndi = "Mock/Mock_Multi"; ConnectionFactory cxf = (ConnectionFactory) initCx.lookup(jndi); // 1.2: 创建连接 Connection connection = null ; connection = cxf.getConnection(); //Step 2: 执行操作 // 2.1: 创建Interaction Interaction interaction = null; interaction = connection.createInteraction(); // 2.2: 准备InteractionSpec WBIInteractionSpec interactionSpec = new WBIInteractionSpec(); // 2.3: 准备BO,必须以BG为包装器 DataObject inputObject = null; inputObject = AdapterBOUtil .createDataObject( "http://MockTest", "MockBOBG"); DataObject bo = inputObject.createDataObject("MockBO"); bo.set("X", "1.01"); bo.set("Y", "3.21"); // 2.4: 准备Record DataObjectRecord inputRecord = new DataObjectRecord(); inputRecord.setDataObject(inputObject); // 2.5: 调用执行方法 Record outputRecord = interaction.execute(interactionSpec, inputRecord); // 2.6: 获取返回值并输出 DataObject outputObject = ((DataObjectRecord) outputRecord) .getDataObject(); out.println(AdapterBOUtil.serializeDataObject(outputObject)); //Step 3: 关闭连接 connection.close(); } catch (Exception e) { e.printStackTrace(); }%></BODY></HTML>
以上代码中,第一步引用了JNDI名字Mock/Mock_Multi,需要在ear部署后手工创建。首先启动WID的集成测试服务器,将ear工程添加到服务器上。接着通过WPS的管理控制台,找到相应的企业应用程序,为其建立J2C连接工厂,将其JNDI设为Mock/Mock_Multi,并且定制其属性opertaion为“*”(即乘法)。
图 3. 定义J2C连接工厂
然后可以通过浏览器来执行index.jsp。如果完全按照如上设置,将得到以下输出:
图 4. 输出结果
回页首
总结及展望
以上我们实现了MockAdapter的连接管理和Outbound操作功能。WebSphere JCA Adapter还有很多其它需要考虑的特性,比如事务的管理,Inbound通讯等。Foundation Classes也有很多其他功能,如Command管理框架,统一的日志功能等。这些本文都没有触及。实际可用的Adapter无疑要复杂的多,但是基本的实现步骤是大体相同的。
参考资料
学习- Sun的JCA官方网站可以获得JCA 1.5规范
- IBM WebSphere Adapters 文档中心
- 参考 SDO规范 学习更多SDO的知识
获得产品和技术
- 参考 IBM WebSphere Adapter 产品主页
- 参考 IBM WebSphere Integration Developer 产品主页
关于作者
刘冬清是中国软件实验室(CSDL BJ)的工程师,加入IBM以来一直从事Websphere Business Integration相关软件的开发和测试工作。可以通过电子邮件:liudongq@cn.ibm.com来联系他。
- WebSphere JCA Adapter 开发入门
- JCA入门(上)
- JCA入门(下)
- WebSphere MQ 开发快速入门
- 用WID 开发JCA
- J2EE入门-jca(1)-简介
- Websphere 入门基础 第三课 WebSphere Studio应用开发
- WebSphere Adapter Development Redbooks
- JCA
- WebSphere Portlet Factory开发的入门
- WebSphere Portlet Factory 快速开发入门
- Websphere 入门基础 第九课 IBM WebSphere Studio实验以及应用开发实验的设置指导
- Websphere 入门基础 第十一课 IBM WebSphere应用开发实验指导
- Linux上的WebSphere MQ开发快速入门
- adapter入门
- WebSphere Studio 新功能入门
- WebSphere快速入门
- WebSphere快速入门
- 局域网实现原理与Windows下的局域网共享
- AXIS实现Web服务深入篇
- 关于Iris网络流量分析监测工具对本地TCP无法抓包的问题
- 数据服务笔记
- C/C++ Programming interview questions and answers (ZZ)
- WebSphere JCA Adapter 开发入门
- 用 Apache 和 Subversion 搭建安全的版本控制环境
- web application 中的buildpath与jvm
- 局域网文件共享访问设置
- 一些网站
- Android学习笔记(11)-开始做一个数独游戏[下]
- 鉴别音箱的方法
- 面向对象编程思想的错误
- 局域网互联文件共享详细设置