Apache Servicemix 教程 – CXFBC

主要介绍下Servicemix最常用的组件之一servicemix cxfbc的使用,官方上有比较详细的文档,英文好的朋友可以直接点击查看

  CXF 同时也是apache的一款webserivce框架.Java开发者可以使用cxf快速的发布webserivce或者作为客户端调用别的webserivce.

  在Java世界里,webserivce本质上就是把java bean对象序列化成xml文本,并包装成SOAP格式的消息传递到服务端,由服务端反序列化xml消息到java bean调用相关服务.

Note:这里的序列化和反序列化,涉及到2个标准,即jax-rpc和jax-ws规范 这2个规范无论是对SOAP的格式还是java-xml间互转都有着本质上的不同.JDK1.5以后,sun已经把jax-rpc移除了jdk中去. JDK1.5开始都采用jax-ws规范. 这里cxf同样只支持jax-ws规范.

  我们先来写一个简单的webservice程序,充当集成的一个系统,我们称这个系统为mock系统. 如何开发一个webserivce不是这里的重点,可以点击此处下载已开发完好的webservice程序,只需把war包扔到Servlet容器内部署即可. 这里我们假设我需要集成一个订单受理系统.

  浏览器内输入 http://localhost:8000/mock/services/order?wsdl   打开如下图,则启动正常

TM截图未命名

好了,我们开始对这个mock系统进行集成,因为是例子,我做的尽量简单,只使用cxfbc一个JBI组件来开发,现实环境中一般还用上xslt作为数据树结构转换,这里我们先不用.

一、编写自定义WSDL,

  CXFBC是一个BC组件,简单来说其实是一个WebService的代理组件,使用这个组件我可以不写任何一行代码,来和一个现有的WebService进行连接,虽然不用写代码,但我们却需要编写一个WSDL文件,这样ESB暴露给别的系统的就是这份WSDL文件,调用后CXFBC组件会把这份WSDL产生的SOAP消息,发往外部系统,这里是我们的mock系统.

大致关系如下:   
Client   — soap –>   ServiceMix(Custom WSDL) – soap – > mock

这里为了演示,我就自己不写WSDL了,直接把mock发布的WDSL拷贝一份即可,但要注意修改几个地方,参考下面WSDL.

 

XML语言: 临时自用代码
<?xml version=”1.0″ ?><wsdl:definitions name=“OrderServerImplService” targetNamespace=“http://www.fengsage.com/order” xmlns:ns1=“http://cxf.apache.org/bindings/xformat” xmlns:soap=“http://schemas.xmlsoap.org/wsdl/soap/” xmlns:tns=“http://www.fengsage.com/order” xmlns:wsdl=“http://schemas.xmlsoap.org/wsdl/” xmlns:xsd=“http://www.w3.org/2001/XMLSchema”>
  <wsdl:types>
<xs:schema attributeFormDefault=“unqualified” elementFormDefault=“unqualified” targetNamespace=“http://www.fengsage.com/order” xmlns=“http://www.fengsage.com/order” xmlns:xs=“http://www.w3.org/2001/XMLSchema”>
<xs:complexType name=“orderDetail”>
<xs:sequence>
<xs:element name=“id” type=“xs:long”></xs:element>
<xs:element minOccurs=“0” name=“name” type=“xs:string”></xs:element>
<xs:element name=“nums” type=“xs:int”></xs:element>
<xs:element minOccurs=“0” name=“remark” type=“xs:string”></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name=“orderResult”>
<xs:sequence>
<xs:element name=“id” type=“xs:long”></xs:element>
<xs:element minOccurs=“0” name=“name” type=“xs:string”></xs:element>
<xs:element minOccurs=“0” name=“status” type=“xs:string”></xs:element>

</xs:sequence>
</xs:complexType>
<xs:element name=“create” nillable=“true” type=“orderDetail”></xs:element>
<xs:element name=“createResponse” nillable=“true” type=“orderResult”></xs:element>
</xs:schema>
  </wsdl:types>
  <wsdl:message name=“create”>
    <wsdl:part element=“tns:create” name=“create”>
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name=“createResponse”>

    <wsdl:part element=“tns:createResponse” name=“createResponse”>
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name=“OrderMockServer”>
    <wsdl:operation name=“create”>
      <wsdl:input message=“tns:create” name=“create”>
    </wsdl:input>
      <wsdl:output message=“tns:createResponse” name=“createResponse”>
    </wsdl:output>

    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name=“OrderServerImplServiceSoapBinding” type=“tns:OrderMockServer”>
    <soap:binding style=“document” transport=“http://schemas.xmlsoap.org/soap/http”></soap:binding>
    <wsdl:operation name=“create”>
      <soap:operation soapAction=“” style=“document”></soap:operation>
      <wsdl:input name=“create”>
        <soap:body use=“literal”></soap:body>
      </wsdl:input>

      <wsdl:output name=“createResponse”>
        <soap:body use=“literal”></soap:body>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name=“OrderServerImplService”>
    <wsdl:port binding=“tns:OrderServerImplServiceSoapBinding” name=“OrderMockEndPointPort”>
      <soap:address location=“http://localhost:8000/mock/services/order”></soap:address>
    </wsdl:port>

  </wsdl:service>
</wsdl:definitions>

 

注意<wsdl:service name=”OrderServerImplService” 和 <wsdl:port name=”OrderMockEndPointPort” 我们要修改成如下:

XML语言: 临时自用代码
<wsdl:service name=“OrderServerESBService”>
  <wsdl:port binding=“tns:OrderServerImplServiceSoapBinding” name=“OrderESBEndPointPort”>
    <soap:address location=“http://localhost:8000/mock/services/order”></soap:address>
  </wsdl:port>
</wsdl:service>

由于对Servicemix来说,外部系统(mock),也是一个endpoint,所以这里service name和endpoint name不能和外部系统一致,改成不同即可.

二、建立Servicemix工程

  这里使用maven脚本建立.

  1) 创建ROOT目录

C: mvn archetype:create -DarchetypeArtifactId=servicemix-project-root -DarchetypeGroupId=org.apache.servicemix.tooling -DartifactId=Root -DgroupId=com.fengsage.esb

2) 创建CXFBC组件

C:Root>mvn archetype:create -DarchetypeArtifactId=servicemix-cxf-bc-service-unit -DarchetypeGroupId
=org.apache.servicemix.tooling -DartifactId=cxfbc -DgroupId=com.fengsage.esb

3) 把前面自定义的WSDL文件放到srcmainresources 系统classpath 路径下

4) 编辑CXFBC组件的xbean.xml

XML语言: 临时自用代码
<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=“http://www.springframework.org/schema/beans”
       xmlns:cxfbc=“http://servicemix.apache.org/cxfbc/1.0”
       xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
       xmlns:esb=http://www.fengsage.com/order
       xsi:schemaLocation=“http://servicemix.apache.org/cxfbc/1.0 http://servicemix.apache.org/schema/servicemix-cxfbc-3.2.3.xsd
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd”>
  
  <cxfbc:consumer wsdl=“classpath:custom.wsdl”
                service=“esb:OrderServerESBService”
            endpoint=“OrderMockEndPointPort”
                  locationURI=“http://localhost:8193/ESB/1”
            targetService=“esb:OrderServerImplService”
                  targetEndpoint=“OrderMockEndPointPort”/>

  <cxfbc:provider wsdl=“http://localhost:8000/mock/services/order?wsdl”
                service=“esb:OrderServerImplService”
                  endpoint=“OrderMockEndPointPort”/> 
</beans>

5) 创建SA组件,进行打包

C:Root>mvn archetype:create -DarchetypeArtifactId=servicemix-service-assembly -DarchetypeGroupId=or
g.apache.servicemix.tooling -DartifactId=sa -DgroupId=com.fengsage.esb

6) 手动调整SA组件里的POM文件,添加下面几行,通知SA编译时把CXFBC组件打包进去

<dependency>
  <groupId>com.fengsage.esb</groupId>
  <artifactId>cxfbc</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

7) 编译

C:Root>mvn install

8) 发布

  进入SAtarget目录,可以看到有个生成的sa-1.0-SNAPSHOT.jar文件把这个文件放到ApacheService的hotdeploy目录,启动Servicemix即可.或运行下面命令可以直接发布

C:Rootsa>mvn jbi:projectDeploy -o

如无错误,应该有下面提示

INFO  – ServerImpl                     – Setting the server’s publish address to be http://localhost
:8193/ESB/1

10) 打开http://localhost:8193/ESB/1?wsdl 进行浏览,可以看到这个就是我们在ESB发布的WebService了

11) 测试

  我们使用一款免费的WebService测试工具, SOAP UI , 官方地址

<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:ord=”http://www.fengsage.com/order”>
   <soapenv:Header/>
   <soapenv:Body>
      <ord:create>
         <id>?</id>
         <!–Optional:–>
         <name>?</name>
         <nums>?</nums>
         <!–Optional:–>
         <remark>?</remark>
      </ord:create>
   </soapenv:Body>
</soapenv:Envelope>

14 条评论。

  1. mvn archetype:create -DarchetypeArtifactId=servicemix-cxf-bc-service-unit -DarchetypeGroupId

    =org.apache.servicemix.tooling -DartifactId=cxfbc -DgroupId=com.fengsage.esb

    这类的指令是在哪里看到全的呢?这个是创建BC的,如果创建SE怎么写

    有没有啥资料,我没查到……

  2. 你好,仔细看了你这篇教程,在进行到第六步的时候,那几行代码放在

    Apache ServiceMix :: Service Assembly

    后面对吗?

    为什么我编译成功之后,部署到servicemix的时候,总是提示

    Artifact cxfbc-1.0-SNAPSHOT.zip not found for service unit cxfbc

    不能成功部署呢

    我之前按照别的教程编译出来的jar也是相同的情况,是不是我哪一部错了?

    另外,你访问你的war是,地址http://localhost:8000/mock/services/order?wsdl,必须要改成8080才能访问

  3. 感谢楼主的大力支持,终于成功,另外有几个问题期待楼主解答,已经发送邮件!

  4. 已经发送,非常感谢

  5. 详细情况,你可以把未编译的工程发我邮箱me(AT)fengsage.com

    下面你访问什么端口,是根据你Servlet容器决定的,我设置的是8000. tomcat默认是8080

  6. @gogo 我看了下,你用maven编译的时候,后面不要加-o 试试看,我这边加是因为本地已经有相关库了,告诉maven不要重检查库而直接进行编译.

    mvn clean install

    cd *sa

    mvn jbi:projectDeploy

  7. 部署完成,测试失败,详细信息已经发送邮件,期待你的解答

  8. 张宴老师,您好!按照上面的例子,我在最后一步:
    6) 手动调整SA组件里的POM文件,添加下面几行,通知SA编译时把CXFBC组件打包进去


    com.fengsage.esb
    cxfbc
    1.0-SNAPSHOT

    中如实添加了,但生成的sa-1.0-SNAPSHOT.jar没有包含su,到底是怎么回事呢?
    我整个sa的pom.xml内容如下:

    4.0.0 Root
    com.fengsage.esb
    1.0-SNAPSHOT
    com.fengsage.esb
    sa
    1.0-SNAPSHOT jbi-service-assembly Apache ServiceMix :: Service Assembly


    com.fengsage.esb
    cxfbc
    1.0-SNAPSHOT


    org.apache.servicemix.tooling
    jbi-maven-plugin
    4.3
    true

    service-assembly

    静候回复,O(∩_∩)O谢谢

  9. fred:你好!在上面例子中的第六步,即:
    6) 手动调整SA组件里的POM文件,添加下面几行,通知SA编译时把CXFBC组件打包进去


    com.fengsage.esb
    cxfbc
    1.0-SNAPSHOT

    能否把整个pom文件贴出来,O(∩_∩)O谢谢

  10. serviceMix有支持socket的BC吗?如何自己创建BC安装到serviceMix中

  11. @Terry没有这个BC。需要自己实现BC。不过不太建议sock走smx。

  12. @fred
    为什么不建议,smx不是有Ftp的吗,Ftp不是走socket协议。
    最后请问有办法或是如何自己写BC并安装到smx中,谢谢

  13. @Terry抱歉,这几天有点忙。

    如何创建BC:http://servicemix.apache.org/hello-world-bc.html
    如何创建SE:http://servicemix.apache.org/hello-world-se.html

    不建议走SOCK的。ESB的大多协议都是比较高级的传输协议。SOCK没有什么统一的标准这类的。

    http://servicemix.apache.org/components-list.html

    这里有SMX所有支持的组建,上面完成的和正在开发的协议。你可以了解下。就明白为什么没有直接TCP的东东了。