TIBCO ESB实战系列:使用BW SOAP RequestReply调用SOAP/JMS服务

本文介绍了在SOA环境中,如何使用TIBCO ESB(BusinessWorks)通过SOAP RequestReply调用使用XFire封装的SOAP/JMS服务。文章详细阐述了SOAP和JMS的优缺点,以及XFire和Axis2支持JMS的情况。通过修改配置文件,实现了在TIBCO BW中调用SOAP/JMS服务,并解决了SOAP RequestReply在组装SOAP Message时遇到的问题。

随着SOA (面向服务架构) 的推广,Web Service技术作为SOA最基础最简单的一种实现方式,在各种各样的项目中得到了广泛的应用。Web Service使用SOAP作为消息格式,基于这种通用的技术,各种异构的系统可以很容易地进行整合和交互。这些Web Service接口,也为企业将来的SOA平台提供了良好的基础。

Web Service不仅仅只有SOAP消息,还有它所使用的transportHTTP作为Web Service标准的第一个官方transport,已经得到了广泛的应用,但是http本身有许多局限性。比如:它只支持点对点同步方式;不能保证消息的可靠传输;http受主机端口的限制,扩展性不强;虽然有很多的机制对SOAP/HTTP进行了扩充,但这些机制复杂,难于掌握。

幸运的是,我们还有其他的选择,除了HTTPJMS也是Web Service常用的transport。相对于httpJMS有这样一些优点:JMS有更多的通讯方式,包括同步/异步的点对点和发布/订阅;JMS通过其自身的存储转发机制支持可靠的传输;JMS不受端口限制,有很强的扩展性;因为JMS本身有了上述特性,所以SOAP/JMSSOAP/HTTP要更加简单。当然了,要使用JMS Transport,你需要一个JMS Server

目前广泛使用的Web Service引擎——XFireAxis2都对JMS transport提供了支持。(Axis2的最新版本1.5.1还不支持JMS,据说还没有release)

在这两种Web Service引擎上部署SOAP/JMS的所使用的JAVA代码与SOAP/HTTP完全一样,只是在配置文件上稍有不同。本文中我们使用TIBCO EMS作为JMS服务器。

1.     XFire

l       TIBCO EMSjar文件拷贝到WEB-INF/lib目录下(本文使用XFire 1.2.6)

l       如下修改XFire应用目录下的WEB-INF/classes/META-INF/xfire/services.xml

<!-- START SNIPPET: services -->

<beansxmlns="http://xfire.codehaus.org/config/1.0">

 <xfire>

   <transports>

      <bean id="jmsTransport"

           class="org.codehaus.xfire.transport.jms.JMSTransport"

           xmlns="http://xbean.org/schemas/spring/1.0">

        <constructor-argref="xfire"/>

        <constructor-argref="connectionFactory"/>

      </bean>

   </transports>

 </xfire>

 

  <service>

   <name>TestService</name>

   <namespace>http://xfire.codehaus.org/TestService</namespace>

   <serviceClass>test.TestService</serviceClass>

   <implementationClass>test.TestServiceImpl</implementationClass>

   <bindings>

      <soap11Bindingname="e:TestServiceJMSBinding"transport="urn:xfire:transport:jms">

        <endpoints>

          <endpointname="e:TestServiceJMSEndpoint" url="jms://TestService"/>

        </endpoints>

      </soap11Binding>

   </bindings>   

 </service>

 

 <bean id="connectionFactory"

       class="com.tibco.tibjms.TibjmsQueueConnectionFactory"

        singleton="true"

       xmlns="http://xbean.org/schemas/spring/1.0/">

   <constructor-arg value="tcp://localhost:7222"type="java.lang.String"/>

 </bean>

</beans>

<!-- ENDSNIPPET: services -->

l       红色字体为配置SOAP/JMSSOAP/HTTP不同的地方,部署SOAP/HTTP不需要这些配置;

l       其中<endpoint name="e:TestServiceJMSEndpoint"url="jms://TestService" />jms://后为当前服务使用的Queue或者Topic的,它的名称必须与<name>TestService</name>中的名称相同。

l       启动部署XFire应用的Application Server,访问该服务的WSDL,会发现相比单纯的SOAP/HTTP,多出了如下信息:

       <wsdl:bindingname="TestServiceJMSBinding"type="tns:TestServicePortType">

              <wsdlsoap:bindingstyle="document" transport="urn:xfire:transport:jms"/>

              <wsdl:operationname="getTests">

                     <wsdlsoap:operationsoapAction=""/>

                     <wsdl:inputname="getTestsRequest">

                            <wsdlsoap:bodyuse="literal"/>

                     </wsdl:input>

                     <wsdl:outputname="getTestsResponse">

                            <wsdlsoap:bodyuse="literal"/>

                     </wsdl:output>

              </wsdl:operation>

              <wsdl:operationname="getResult">

                     <wsdlsoap:operationsoapAction=""/>

                     <wsdl:inputname="getResultRequest">

                            <wsdlsoap:bodyuse="literal"/>

                     </wsdl:input>

                     <wsdl:outputname="getResultResponse">

                            <wsdlsoap:bodyuse="literal"/>

                     </wsdl:output>

              </wsdl:operation>

       </wsdl:binding>

 

       <wsdl:servicename="TestService">

              <wsdl:portname="TestServiceJMSPort"binding="TestServiceJMSBinding">

                     <wsdlsoap:addresslocation="jms://TestService"/>

              </wsdl:port>

              <wsdl:portname="TestServiceHttpPort" binding="tns:TestServiceHttpBinding">

                     <wsdlsoap:addresslocation="http://localhost:8080/xfire/services/TestService"/>

              </wsdl:port>

              <wsdl:portname="TestServiceJMSEndpoint"binding="TestServiceJMSBinding">

                     <wsdlsoap:addresslocation="jms://TestService"/>

              </wsdl:port>

       </wsdl:service>

l        部署在App Server中的XFire应用同时支持SOAP/HTTPSOAP/JMS两种模式。

2.     Axis2

l       TIBCO EMSjar文件拷贝到AXIS2_HOME/lib目录下;

l       修改AXIS2_HOME/conf/axis2.xml,修改与JMS相关的设置,如下:

    <transportReceivername="jms"class="org.apache.axis2.transport.jms.JMSListener">

        <parametername="tibTopicConnectionFactory">

              <parametername="java.naming.factory.initial">com.tibco.tibjms.naming.TibjmsInitialContextFactory</parameter>

              <parametername="java.naming.provider.url">tibjmsnaming://localhost:7222</parameter>

              <parametername="transport.jms.ConnectionFactoryJNDIName">TopicConnectionFactory</parameter>

       </parameter>

 

       <parameter name="tibQueueConnectionFactory">

              <parametername="java.naming.factory.initial">com.tibco.tibjms.naming.TibjmsInitialContextFactory</parameter>

              <parametername="java.naming.provider.url">tibjmsnaming://localhost:7222</parameter>

              <parametername="transport.jms.ConnectionFactoryJNDIName">QueueConnectionFactory</parameter>

       </parameter>

 

       <parameter name="default">

              <parametername="java.naming.factory.initial">com.tibco.tibjms.naming.TibjmsInitialContextFactory</parameter>

              <parametername="java.naming.provider.url">tibjmsnaming://localhost:7222</parameter>

              <parametername="transport.jms.ConnectionFactoryJNDIName">QueueConnectionFactory</parameter>

       </parameter>

</transportReceiver>

 

<transportSendername="jms"                    class="org.apache.axis2.transport.jms.JMSSender"/>

l       AXIS2引擎可以不用部署到App Server就能启动,启动引擎。应用启动后,可在EMS中查到引擎创建的与服务名相同的QueueTopic

l       查询服务的WSDL可以发现新增如下信息:

<wsdl:portname="TestServiceJmsSoap11Endpoint"binding="ns:TestServiceSoap11Binding">

   <soap:addresslocation="jms:/TestService?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&amp;java.naming.provider.url=tibjmsnaming://localhost:7222&amp;java.naming.factory.initial=com.tibco.tibjms.naming.TibjmsInitialContextFactory"/>

</wsdl:port>

<wsdl:portname="TestServiceJmsSoap12Endpoint"binding="ns:TestServiceSoap12Binding">

   <soap12:addresslocation="jms:/TestService?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&amp;java.naming.provider.url=tibjmsnaming://localhost:7222&amp;java.naming.factory.initial=com.tibco.tibjms.naming.TibjmsInitialContextFactory"/>

 

</wsdl:port>

l       在我这几天做的测试中,发现AXIS2 1.3AXIS2 1.4.1上部署的服务都有问题;同样的aar包部署在AXIS2 1.5.1可以正常运行,但是它还不支持JMS transport,需要等待更新的版本,所以在后面的测试中,我也没有再使用BW去调用AXIS2SOAP/JMS服务。

3.     使用BW SOAP RequestReply调用SOAP/JMS服务

TIBCO BusinessWorks (简称BW) 是一款非常优秀的集成平台产品,它通过图形化方式创建集成应用,并且能够与市面上几乎所有的技术接口进行交互,这里面当然不会少了Web ServiceBW本身也可以进行SOAP应用的封装和调用,在本节中,我们将要介绍如何用BW调用使用XFire封装的SOAP/JMS服务。(因为AXIS2本身的缺陷和不完善,暂不做讨论)

使用BW调用SOAP/JMS服务有两种方式,可以使用topic或者queuerequestor调用同步服务,或者用Topic Publisher或者Queue Sender来调用One Way的异步服务,因为SOAP/JMS本质上就是使用JMS发送SOAP格式的报文。另一种方式就是更加正规的,使用SOAP RequestReply来进行调用。

l       XFire服务的WSDL导入BW工程,与SOAP RequestReply关联,我们会发现Transport Detail是空的;

l       如下修改XFire服务的WSDL

n       wsdl:definitions中增加如下两个Name Space

xmlns:jms ="http://www.tibco.com/namespaces/ws/2004/soap/binding/JMS"

xmlns:jndi = http://www.tibco.com/namespaces/ws/2004/soap/apis/jndi

n       wsdl:service中增加如下的红色字体

       <wsdl:service name ="TestService">

              <wsdl:portbinding = "TestServiceJMSBinding" name = "TestServiceJMSPort">

                     <wsdlsoap:addresslocation = "jms://TestService"/>

                     <jms:connectionFactory>QueueConnectionFactory</jms:connectionFactory>

                     <jms:targetAddress destination ="queue">TestService</jms:targetAddress>

              </wsdl:port>

              <wsdl:portbinding = "tns:TestServiceHttpBinding" name ="TestServiceHttpPort">

                     <wsdlsoap:addresslocation = "http://localhost:8080/xfire/services/TestService"/>

              </wsdl:port>

              <wsdl:portbinding = "TestServiceJMSBinding" name ="TestServiceJMSEndpoint">

                     <wsdlsoap:address location= "jms://sample"/>

                     <jms:connectionFactory>QueueConnectionFactory</jms:connectionFactory>

                     <jms:targetAddress destination ="queue">TestService</jms:targetAddress>

              </wsdl:port>

       </wsdl:service>

                     增加的内容为使用的jndi connection factorydestination的类型和名称。

n       如上修改后,用户就可以在Transport Detail中进行Transport的设置

l       启动Process 进行测试,SOAP RequestReply会抛出异常:SoapMessage::initRequestMessage。看样子是SOAP RequestReply在组装SOAP Message的时候就有问题,没法把消息发送到EMS服务器上;通过检查WSDL,发现问题在于:

<wsdlsoap:binding style="document"transport="urn:xfire:transport:jms"/>

              SOAP RequestReply不能识别这个transport,如下进行修改:

<wsdlsoap:binding style = "document" transport = "http://www.tibco.com/namespaces/ws/2004/soap/binding/JMS"/>

l       重新启动Process,调用成功。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值