使用 WebSphere ESB 实现协议转换和数据转换_第1页
使用 WebSphere ESB 实现协议转换和数据转换_第2页
使用 WebSphere ESB 实现协议转换和数据转换_第3页
使用 WebSphere ESB 实现协议转换和数据转换_第4页
使用 WebSphere ESB 实现协议转换和数据转换_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

使用WebSphereESB实现协议转换和数据转换简介:

本文主要介绍如何通过WebSphereESB实现协议转换和数据转换功能:通过WebsphereESB实现SOAP/HTTP和JMS之间的协议转换;实现JMSObjectMessage与BusinessObject之间、以及BusinessObject与JavaObject的数据转换;实现客户端与ESB之间request/response的交互方式,客户端向ESB发送带有数据对象的请求,ESB请求Web服务后,将结果以数据对象的形式返回给客户端。引言已有许多文章介绍了如何将xmlmessage传入ESB进行协议转换和数据转换,而在实际的应用环境中,面向对象的设计会显得更实用些。本文主要介绍如何基于JMS和WebSphereESB构建企业服务总线,实现SOAP/HTTP和JMS之间的协议转换;实现JMSObjectMessage,BusinessObject及JavaObject之间的数据转换;以及如何实现通过ESB来实现request/response的交互方式。示例场景

图1:示例场景

图1示例展示了一个典型的端到端的SOA场景:(1)ServiceProvider以SOAP/HTTP方式发布WebService,该WebService输入和返回都是JavaObject;(2)客户端以JMS方式去调用这个WebService,需要经过WehSphereESB进行协议转换,WehSphereESB将客户端的JMS协议转换为服务端需要的SOAP/HTTP协议;(3)客户端将JMSObjectMessage发送给WehSphereESB,WehSphereESB通过SOAP/HTTP方式请求WebService。在服务请求的过程中,WehSphereESB将客户端传入的JMSObjectMessage转换为BusinessObject,又将BusinessObject转换为服务端需要的JavaObject;在服务返回的过程中,WehSphereESB将服务端返回的JavaObject转换为BusinessObject,又将BusinessObject转换为客户端能识别的JMSObjectMessage;(4)客户端向WebSphereESB发送请求和接收返回数据分别在两个队列上进行,客户端只需关注如何将请求的数据转化为JMSObjectMessage并放入WehSphereESB的接收队列,以及如何从WehSphereESB的发送队列里取出JMSObjectMessage并解析所需的结果即可。本示例是基于WID6.0.2和ESB6.0.2实现的,下面来详细介绍如何实现这一示例场景。创建Serviceprovider建立工程BookOrderService,来担任ServiceProvider。该service提供了一个接口方法order(),其输入和输出分别是javaobject:OrderRequest和OrderResponse,将此方法发布成WebService,如下:1.建立一个DynamicWebProject:BookOrderService2.添加对象类、接口和实现类对象类:Address.java包含属性:privateStringstreet;privateStringcity;OrderRequest.java包含属性:privateStringname;privateintcount;privateAddressaddress;OrderResponse.java包含属性:privatedoubletotalPrice;接口类:BookOrderIf.javapublicinterfaceBookOrderIf{publicOrderResponseorder(OrderRequestreq);}实现类:BookOrderImpl.java实现了一个简单的业务逻辑。publicOrderResponseorder(OrderRequestreq){doubletotalPrice=10.0*req.getCount();OrderResponseresp=newOrderResponse();resp.setTotalPrice(totalPrice);System.out.println("ServiceProvider:Thebookis"+req.getName()+",thecityis"+req.getAddress().getCity()+",totalpriceis"+totalPrice);returnresp;}3.将BookOrderImpl发布为SOAP/HTTPWebservice,产生WSDL文件BookOrderImpl.wsdl。创建WebSphereESBWebSphereESB的数据转换和协议转换功能通过MediationModule工程来实现,MediationModule工程包含三个重要组件:MediationFlow、Import和Export组件。MediationFlow组件实现数据转换功能;Import组件负责对ServiceProvider的WebService进行调用;Export组件是外界(JMSClient)访问MediationModule的接口。创建新的MediationModule建立新的MediationModule:SOAPHTTP2JMSBinding。建立MediationModule的同时,会自动创建名称为Mediation1的MediationFlow的组件。MediationModule需要访问刚刚创建的ServiceProvider,就需要导入BookOrderImpl.wsdl文件。从BookOrderServicePorject里找到BookOrderImpl.wsdl,复制到SOAPHTTP2JMSBindingProject。WebSphereESB就是通过BookOrderImpl.wsdl来建立对ServiceProvider调用的。添加Import组件Import组件负责完成对ServiceProvider的WebService进行调用。打开SOAPHTTP2JMSBinding的AssembleDiagram,添加Import,更名为:SOAPHTTPImport。选择SOAPHTTPImport,添加接口“AddInterface”,选择BookOrderImpl,这正是BookOrderImpl.wsdl提供的接口。Import组件有几种方式可以访问MediationModule之外的serviceprovider:MessagingBinding方式,包括JMSBinding、MQBinding和JMSMQBinding;WebServiceBinding方式。因为我们刚才建立的serviceprovider的接口是SOAP/HTTPWebService,所以Import组件需要选用WebServiceBinding方式。为SOAPHTTPImport添加绑定:“GenerateBinding”,选择WebServiceBinding,如图2。

图2:WebServiceBinding

在接下来的对话框中选择“Useanexistingwebserviceport”,并“Browse”选择serviceports:BookOrderImpl(因为之前已经导入了BookOrderImpl.wsdl文件,该文件提供了访问serviceprovider的webserviceport)。新建BusinessObjectMediationModule要进行数据对象的转换,就需要建立内部的数据对象BusinessObject,来担任数据转换的中间者。为SOAPHTTP2JMSBinding建立新的BusinessObject:OrderBO:添加属性:bookname,count,city和streetRespBO:添加属性:totalPrice新建接口建立新的WebSphereESB接口,为serviceprovider提供新的展现方式,以便向外界提供各种接口方式(各种Binding方式,见“添加Export组件”)。为SOAPHTTP2JMSBinding新建Interface:BookOrderIF添加“RequestResponseOperation”,修改operationname为:order,修改参数,如图3:InputName:orderBOType:OrderBOOutPutName:respBOType:RespBO

图3:NewInterface

添加Export组件为了使外界(JMSClient)访问到MediationModule,需要添加Export组件。添加Export,更名为JMSExport。为JMSExport添加接口,“AddInterface”,选择“BookOrderIF”(注意是新建的接口,不是BookOrderImpl.wsdl提供的接口)。MediationModule可以向外界提供几种方式的接口:MessagingBinding:包括JMSBinding、MQBinding和MQJMSBinding;SCABinding:SCA方式提供给其他MediationModule来访问;WebServiceBinding:提供外界WebService的访问方式。这里,我们提供JMS的访问方式。为JMSExport添加绑定:GenerateBinding,选择“JMSBinding”,如图4。

图4:JMSBinding

弹出对话框,JMSExportBinding需要复杂的资源设置,如图5:

图5:JMSExportBindingConfiguration

因为JMS协议要求访问者(JMSClient和JMSExport都是ESB资源的访问者)通过JNDI来访问队列、队列工厂等ESB资源的,因此需要在ESB上设置各资源的JNDI(参见WAS配置ESB)。在此处需要为JMSExport指定各资源的JNDI。选择“usepre-configuredmessagingproviderresources”,设置激活规范、接收目标和发送目标:JNDInameforactivationspecification:jms/JMSBindingAS4Export这个JNDI是JMSExport访问队列的激活规范(参见WAS配置ESB);JNDInameforreceivedestination:jms/JMSBingQExportRecv这个JNDI指向ESB的接收队列(参见WAS配置ESB);JNDInameforsenddestination:jms/JMSBingQExportSend这个JNDI指向ESB的发送队列(参见WAS配置ESB);选择serializationtype:“SerializedBusinessObjectusingJMSObjectMessage”。因为ESB队列接收和返回的数据都是JMSObjectMessage对象,因此需要选择此项。如果接收到数据是XML,可选择“BusinessObjectXMLusingJMSTextMessage”。为了使WebSphereESB能将数据返回给客户端,还需要设置CallBackDesitination和ManagedConnectionFactory。如图6和图7。

图6:CallBackDesitination

在JMSExportProperties的Binding/End-pointconfiguration窗口,设置:JMSDestinations/CallbackDestinationProperties:jms/JMSBindingQ

图7:ManagedConnectionFactoryProperties

在JMSExportProperties的Binding/End-pointconfiguration窗口,设置:ResponseConnection/ManagedConnectionFactoryProperties:jms/JMSBindingQCFCallbackDestination和ManagedConnectionFactory是为JMSExport返回数据而设置的,如果JMS客户端不需要返回数据,则此两项可以不设置。创建JMSExport的自定义实现类为实现JMS客户端的JMSObjectMessage对象与ServiceProvider端的纯Java对象进行数据转换,就需要建立JMSExport的自定义实现类,通过该类先实现JMSObjectMessage和BusinessObject的转换。为SOAPHTTP2JMSBinding新建JMSExport自定义实现类:JMSObjectBindingImpl.java。接口选择com.ibm.websphere.sca.jms.data.JMSObjectBinding。此接口提供了一些数据转换的方法。添加JMSExport自定义实现类的代码:首先新建java类:为SOAPHTTP2JMSBinding新建普通的java数据对象,以承载从JMSExport传入的JMSObjectMessage对象,该类也可以作为JMS客户端的业务对象,客户端在访问ESB队列时,将此业务对象与JMSObjectMessag对象进行转换(详见客户端Servlet和ServiceConsumer的代码):JMSDataObject.java实现接口:java.io.Serializable添加以下属性到该类:privateStringbookname;privateintcount;privateStringcity;privateStringstreet;privatedoubletotalPrice;打开实现类JMSObjectBindingImpl,添加下列代码:publicclassJMSObjectBindingImplimplementsJMSObjectBinding{privateJMSDataObjectjmsdata;privateDataObjectbo;publicvoidsetObject(Objectarg0)throwsDataBindingException{System.out.println("setJMSObject.");jmsdata=(JMSDataObject)arg0;}publicObjectgetObject()throwsDataBindingException{returnjmsdata;}publicbooleanisObjectType(){returnfalse;}publicvoidsetObjectType(booleanarg0){}publicintgetMessageType(){returnJMSObjectDataBinding.OBJECT_MESSAGE;}publicvoidread(Messagearg0)throwsJMSException{System.out.println("readJMSMessage...");jmsdata=(JMSDataObject)((ObjectMessage)arg0).getObject();com.ibm.websphere.sca.ServiceManagerserviceManager=newcom.ibm.websphere.sca.ServiceManager();com.ibm.websphere.bo.BOFactoryfactory=(com.ibm.websphere.bo.BOFactory)serviceManager.locateService("com/ibm/websphere/bo/BOFactory");DataObjectorderBO=factory.create("http://SOAPHTTP2JMSBinding","OrderBO");orderBO.setString("bookname",jmsdata.getBookname());orderBO.setString("city",jmsdata.getCity());orderBO.setString("street",jmsdata.getStreet());orderBO.setInt("count",jmsdata.getCount());try{setDataObject(orderBO);}catch(DataBindingExceptione){thrownewJMSException(e.getLocalizedMessage());}}publicvoidwrite(Messagearg0)throwsJMSException{System.out.println("writeJMSMessage...");try{DataObjectbo=getDataObject();JMSDataObjectjmsobj=newJMSDataObject();jmsobj.setTotalPrice(bo.getDouble("totalPrice"));((ObjectMessage)arg0).setObject(jmsobj);}catch(DataBindingExceptione){thrownewJMSException(e.getLocalizedMessage());}}publicbooleanisBusinessException(){returnfalse;}publicvoidsetBusinessException(booleanarg0){}publicDataObjectgetDataObject()throwsDataBindingException{returnbo;}publicvoidsetDataObject(DataObjectarg0)throwsDataBindingException{System.out.println("setServiceDataObject.");bo=arg0;}该类实现了以下功能:当客户端向JMSExport发出请求时,该类负责将外部传入的JMSObjectMessage转变为内部的BusinessObject,转变过程依次经过以下方法:(1)read(message)(2)getDataObject()当JMSExport向客户端返回数据时,该类负责将内部的BusinessObject转变为外部的JMSObjectMessage,转变过程依次经过以下方法:(1)setDataObject()(2)getMessageType()(3)write(message)设置JMSExport的自定义实现类将JMSExport的MethodBindings设置为自定义的实现类:JMSObjectBindingImpl。返回AssemblyDiagram,选择JMSExport,选择Methodbindings,如图8:

图8:MethodBindings

选择“ShowAdvanced”,设置以下属性,选择刚刚定义的实现类。如图9:Inputdatabindingformat:Serializationtype:UserSuppliedInputdatabindingclassname:order.JMSObjectBindingImplOutputdatabindingformat:Serializationtype:UserSuppliedInputdatabindingclassname:order.JMSObjectBindingImpl

图9:DataBindingFormat

连接Export,Mediation和Import选择JMSExport的AddWire,拖拽到Mediation1;选择Mediation1的AddWire,拖拽到SOAPHTTPImport上。将Export,Mediation和Import连接起来,如图10。

图10:AddWire

配置MediationFlow,做数据对象转换因为ServiceProvider的service有输入对象和返回对象,因此需要作输入对象和返回对象分别做转换:一是BusinessObject到ServiceProvider的输入对象的转换;二是ServiceProvider的返回对象与BusinessObject的转换。从Mediation1的菜单里选择“GenerateImplementation”,进入MediationFlowEditor窗口,连接两个order方法,如图11:

图11:MediationFlow

先为请求的数据对象作mapping:在“Request:order”的窗口里,添加XMLTransformation,命名为XMLTransformation1,并将XMLTransformation1、order:BookOrderIF和order:BookOrderImpl连接起来,如图12:

图12:XMLTransformation

创建Mappingfile。选择XMLTransformation1,选择Properties的Details,如图13:

图13:CreateMappingFile

选择New…,跳过NewXSLTMapping窗口,显示Mapping窗口,展开所有属性,将属性一一做mapping。这样,通过XSLTMapping,就将BusinessObject转换为ServiceProvider的输入对象,如图14:

图14:DataMapping1

同样,为返回的数据对象作Mapping。在“Response:order”窗口,添加XMLTransformation,命名为XMLTransformation2。将ServiceProvider的返回数据对象和BusinessObject属性一一作Mapping。如图15:

图15:DataMapping2

WAS配置ESBMediationModule提供给客户端JMS的访问方式。因此需要在ESB上建立队列以及JMS的JNDI访问对象,以实现客户端和ESB的JMS访问。建立总线目标打开adminconsole,选择服务集成->总线,选择“SCA.SYSTEM.widCell.Bus”。新建队列目标,建立以下三个队列目标:JMSBingQJMSBingQExportRecvJMSBingQExportSend建立JMS队列选择资源->JMS提供程序->缺省消息传递。新建JMS队列,建立下面三个JMS队列:(1)JMSBindingQJNDI名称:jms/JMSBindingQ队列名:JMSBingQ总线名:SCA.SYSTEM.widCell.Bus(2)JMSBingQExportRecvJNDI名称:jms/JMSBingQExportRecv队列名:JMSBingQExportRecv总线名:SCA.SYSTEM.widCell.Bus(3)JMSBingQExportSendJNDI名称:jms/JMSBingQExportSend队列名:JMSBingQExportSend总线名:SCA.SYSTEM.widCell.Bus建立JMS队列连接工厂选择资源->JMS提供程序->缺省消息传递新建JMS队列连接工厂:JMSBindingQCFJNDI名称:jms/JMSBindingQCF总线名:SCA.SYSTEM.widCell.Bus建立激活规范选择资源->JMS提供程序->缺省消息传递新建“JMS激活规范”:JMSBindingAS4ExportJNDI名称:jms/JMSBindingAS4Export目标类型:队列目标JNDI名称:jms/JMSBingQExportRecv总线名:SCA.SYSTEM.widCell.Bus创建ServiceConsumer从BusinessIntegrationPerspective切换到J2EEPerspective。创建客户端的访问程序。创建web工程ServiceConsumerWeb创建新的Web工程ServiceConsumerWeb,EARproject为ServiceConsumerWebEAR。客户端将使用JMSDataObject.java类作为其业务对象类(见“创建JMSExport的自定义实现类”)。因此,需要将SOAPHTTP2JMSBinding工程export成SOAPHTTP2JMSBinding.jar包,并将jar包输出到ServiceConsumerWebEAR\目录下。并且设置ServiceConsumerWeb的属性:将SOAPHTTP2JMSBinding.jar加入到“javaBuildPath/Libraries”;选择javaJARDependencies,选择SOAPHTTP2JMSBinding.jar。创建ServiceConsumer类为ServiceConsumerWeb工程新建java类:ServiceConsumer,实现客户端请求的逻辑。publicclassServiceConsumer{privateStringQCF="jms/JMSBindingQCF";privateStringjndi_recvfrom_esb="jms/JMSBingQExportSend";privateStringjndi_sendto_esb="jms/JMSBingQExportRecv";publicStringsendMes(Objectmes){//throwsISSXException{QueueConnectionFactoryqcf=null;QueueConnectionconnection=null;QueueSessionsession=null;QueueSendersender=null;try{InitialContextic=newInitialContext();qcf=(QueueConnectionFactory)ic.lookup(QCF);//Createaconnectionconnection=qcf.createQueueConnection();connection.start();session=connection.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);QueueoutQueue=(Queue)ic.lookup(jndi_sendto_esb);//CreateaQueueSendersender=session.createSender(outQueue);sender.setTimeToLive(0);Messagemessage=null;if(mesinstanceofObject){System.out.println("Serviceconsumer:sendrequesttoESB.");message=(ObjectMessage)session.createObjectMessage((JMSDataObject)mes);}message.setStringProperty("TargetFunctionName","order");message.setJMSType("order");sender.send(message);//Closetheconnectionsender.close();session.close();connection.close();sender=null;session=null;connection=null;}catch(JMSExceptionje){je.printStackTrace();Exceptionle=je.getLinkedException();if(le!=null){le.printStackTrace();}}catch(Exceptione){e.printStackTrace();}finally{}return"OK";}publicStringreceiveMes(){QueueConnectionFactoryqcf=null;QueueConnectionconnection=null;QueueSessionsession=null;QueueReceiverreceiver=null;Stringret=null;try{InitialContextic=newInitialContext();qcf=(QueueConnectionFactory)ic.lookup(QCF);//Createaconnectionconnection=qcf.createQueueConnection();connection.start();sessio=connection.createQueueSession(true,Session.AUTO_ACKNOWLEDGE);//ObtaintheDestinationobjectfromJNDIQueueinQueue=(Queue)ic.lookup(jndi_recvfrom_esb);//CreateaQueueSenderreceiver=session.createReceiver(inQueue);Messagemessage=receiver.receive(5000);if(messageinstanceofObjectMessage){ObjectMessageomes=(ObjectMessage)message;JMSDataObjectobj=(JMSDataObject)omes.getObject();System.out.println("Serviceconsumer:getresponsefromESB.TotalPrice="+obj.getTotalPrice());}else{System.out.println("Serviceconsumer:receiveothermessage.");}mit();receiver.close();session.close();connection.close();receiver=null;session=null;connection=null;}catch(JMSExceptionje){//Log,save,sendmail,throwexceptionje.printStackTrace();Exceptionle=je.getLinkedException();if(le!=null){le.printStackTrace();}}catch(Exceptione){e.printStackTrace();}finally{}returnret;}}ServiceConsumer类主要实现两个方法:sendMes(Object)方法,将传入的业务数据对象转化为JMSObjectMessage,发送到ESB的接收队列里;receiveMes()方法,将结果从ESB的发送队列里取出,然后将JMSObjectMessage解析为业务数据对象。创建测试的servlet为ServiceConsumerWeb工程创建servlet:TestServletprotectedvoiddoGet(HttpServletRequestarg0,HttpServletResponsearg1)throwsServletException,IOException{ServiceConsumerconsumer=newServiceConsumer();JMSDataObjectdata=newJMSDataObject();data.setBookname("abc");data.setCount(10);data.setCity("beijing");data.setStreet("zhongguancun");consumer.sendMes(data);try{Thread.sleep(5000);}catch(InterruptedExceptione){e.printStackTrace();}consumer

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论