首页 > 代码库 > cxf笔记记录

cxf笔记记录

一、Web Service框架介绍:

  1. WebService框架的作用:

     -- WebService只是一种思想,不是一个具体的框架.

     -- 它也是javaEE的规范。

     -- 它可以跨平台(操作平台、应用平台)、跨语言的应用之间的远程调用.

 

 2. WebService框架的应用场景:

   -- 不同公司业务整合

        不同公司业务整合,主要就是业务平台的整合,

         有可能出现运行平台不一样,开发语言不一样.

     

     -- 同一个公司新、旧系统的整合.

       

    

  3. WebService与SOA:

     SOA:Service Oriented Architecture 面向服务架构,

     一个软件由N个服务组件以完全解耦的方式组合在一起,

     组件与组件之间通过ESB(企业服务总线)进行通信。

     它是目前较热门的技术,由ESB与Web Service技术组成。

      Enterprise Service Bus:ESB

 

  4. Web Service与云服务:

     云服务:更多是一种商业模式,

     对于云时代电脑而言,所有的数据计算、存储、程序…都交给网络的“云”完成,

     而“云”则由云服务商提供。

     按照云计算的理念:所有用户应该按需付费(就像用水、用电一样)。

     当云服务商对外提供服务给客户调用时,

     云服务商一定会采用一种跨平台、跨语言的技术来提供“云服务”,

     此时Web Service也是一个极佳的选择。

 

二、Web Service实现商

    Axis  --> Axis2

    XFire + Celtix(ESB) SOA

    CXF 2.6.16

 

三、CXF下载与安装

  -- 它的官方网站: http://cxf.apache.org

    -- apache-cxf-2.6.16.zip

    v2.xx.xx(所有模块分别打成了jar包,有总的jar包)

    v3.xx.xx(所有模块分别打成了jar包,没有总的jar包)

 

    解压:

    -- bin:存放了命令

    -- docs: api文档

    -- lib: 存放了自己的jar与第三方的jar.

    -- modules : 所有模块

    -- samples : 示例

 

    安装:

    -- 把bin目录添加到环境变量

 

四、CXF入门

    1.开发Web Service 服务端来暴露服务组件

    步骤:

    a. 拷贝jar包(7个jar) required文件夹

 

       如果是普通的java项目还需要jetty的jar包

 

    b. 开发WS服务组件

        WS服务组件 = WS服务接口 + WS服务接口实现类

       

         WS服务接口: @WebService()

         WS服务接口实现类: @WebService()

         @WebService(endpointInterface="cn.itcast.ws.AdminService",

                       serviceName="TestService")

 

    c. 暴露Web Service服务组件

        Endpoint.publish("访问地址", "服务组件对象");

 

        http://192.168.26.10:8888/itcast?wsdl (Web Service的xml描述文档)

        

   

    2.开发客户端来调用Web Service服务组件.

      满足条件:必须要有服务端提供的wsdl文档访问地址.

      http://192.168.26.10:8888/itcast?wsdl (外网访问)

 

    步骤:

    a. 生成客户端代码的两种方式:

   

       第一种方式(用CXF框架自带的命令):

 

        -- 用wsdl2java命令生成客户端代码

        -- wsdl2java wsdl访问URL

           wsdl2java http://192.168.26.10:8888/itcast?wsdl

 

        

           第二种方式(用java自带的命令):

         -- 用wsimport命令生成客户端代码

         -- wsimport wsdl访问URL

           wsimport http://192.168.26.10:8888/itcast?wsdl -keep  (保留源代码)

        

    b. 在生成的多个java类中找到Service子类,用它来创建WebService服务工厂.

       调用getXxxxPort()方法获取远程WebService服务组件的代理对象.

       再调用服务组件中的方法即可.

 

 

五、WebService服务组件中的操作的数据类型(方法的形参与返回值)

   

    1. CXF能处理的数据类型

      -- java的8个基本数据类型、包装类、String

       -- javaBean式的复合类

       -- List集合、Set集合、Map集合(客户端调用比较麻烦)

 

 

    2.CXF不能处理的数据类型

      -- 非javaBean式的复合类 (File)

     

      xml与java中的数据类型转换器

      -- @XmlJavaTypeAdapter

      -- 自定义类型转换器需要继承XmlAdapter

          XmlAdapter<ValueType,BoundType>

          ValueType: JAXB它知道处理的类型

           BoundType: JAXB它不知道处理的类型

 

           JAXB : Java Xml Binding 它也是javaEE的规范,

                   它规定了java中的数据类型与xml中数据类型怎样转换

 

         

           注意:在类型转换时,数据不能丢失.

 

      不能处理的数据类型:File

       目标:把file这种数据类型转换成cxf能够处理的数据类型.

       -- 接收客户端调用的参数,转化成服务端能处理类型

       -- 服务端返回给客户端的数据类型,转化成客户端能处理类型

    

       @XmlJavaTypeAdapter指定转来转去的类型适匹器

   

 

六、WSDL详解

    Web Service三大技术基础:

    -WSDL:Web Service Description Language, Web Service描述语言。

 

    -SOAP:Simple Object Access Protocol简单对象访问协议,Web Service的通信协议。

    -UDDI:Universal Description Discovery and Integration统一描述、

         发现、整合,服务组件注册中心(名存实亡)。

   

 

     WSDL文档分两个部分:

 

a.接口部分

(http://192.168.26.10:8888/itcast?wsdl=AdminService.wsdl)

      

        1. <wsdl:types ../> 类型元素

            -- <xs:schema .../> 它是一份标准的约束文档.

                -- <xs:complexType ../>每一个复杂类型都会生成一个java类

          

       

         2. N个<wsdl:message .../> 对应操作中的输入与输出消息

 

         3. <wsdl:portType .../>

              -- <wsdl:operation name="方法名" ../> 跟ws服务接口的方法一样多

                 操作中子元input与output子素用来定义输入参数与输出值

       

 

 

b.实现类部分

(http://192.168.26.10:8888/itcast?wsdl)

       1. <wsdl:binding .../>

           -- <soap:binding style="document"

                   transport="http://schemas.xmlsoap.org/soap/http"/>

                style: 底层传输风格(xml文档的方式)

                   transport: 底层传输协议

 

       2. <wsdl:service name="TestService"/> name指定生成的服务类名

          <wsdl:port binding="tns:TestServiceSoapBinding"

                   name="AdminServiceImplPort">

                   <soap:address location="http://192.168.26.10:8888/itcast"/>

            </wsdl:port>

           -- soap:address指定访问地址

 

      以login操作为示例

      -- 发送xml片断

         <login>

                   <arg0>admin</arg0>

                   <arg1>123456</arg1>

          </login>

 

      -- 接收xml片断

         <loginResponse>

                   <return>登录成功!</return>

          </loginResponse>

 

 

         一次Web Service调用的完整过程:

         1.客户端将调用参数转换成XML片段。

         2. 客户端将XML片段通过网络发送给服务端。

         3. 服务端接收XML片段。

         4. 服务端解析XML片段,提取其中数据,并转换相应的调用参数。

         5. 服务端执行方法,得到返回值。

         6. 服务端将返回值转换成XML片段。

         7. 服务端将XML片段通过网络发送给客户端。

         8. 客户端接收XML片段。

         9. 客户端解析XML片段,提取其中数据,转换成调用WS的返回值。

          说明:通过上面描述可以发现,一个语言要支持Web Service,只要满足如下2个要求:

          - 支持XML的解析、生成。

          - 支持网络通信

    tomcat: web服务器, apache 它的作者是javaEE web规范的制订者

    jetty: web服务器,codehuas-->eclipse. 它并不比tomcat差,有些方面比tomcat还好

        作为嵌入服务器。

      七、拦截器

     因为用了CXF这个框架,程序员不需要自己封装发出的xml片断,

      也不需要解析接收到的xml片断,如果需要查看xml片断或修改xml片断,

      就需用拦截器.soap包(xml片断)

 

     1. 在服务端添加拦截器查看SOAP包

        操作步骤:

      a. 获取EndpointImpl对象

            EndpointImpl endpointImpl = (EndpointImpl)Endpoint.publish(address, userService);

 

      b. 获取所有的in拦截器集合

            List<Interceptor<?>> inLists = endpointImpl.getInInterceptors();

 

      c. 获取所有的out拦截器集合

            List<Interceptor<?>> outLists = endpointImpl.getOutInterceptors();

 

      d. 添加自己的in拦截器与out拦截器.

            inLists.add(new LoggingInInterceptor());

            outLists.add(new LoggingOutInterceptor());

 

        服务端接收到的soap包:

          <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">

                   <S:Body>

                            <ns2:login xmlns:ns2="http://ws.itcast.cn/">

                                     <arg0>admin</arg0>

                                     <arg1>99999</arg1>

                            </ns2:login>

                   </S:Body>

          </S:Envelope>

 

        

         服务端发送出去的soap包:

         <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">

                   <soap:Body>

                            <ns2:loginResponse xmlns:ns2="http://ws.itcast.cn/">

                                     <return>admin,登录成功!</return>

                            </ns2:loginResponse>

                   </soap:Body>

         </soap:Envelope>

        

        soap包格式:

         <Envelope>

                   <Header> -- 可有可无,程序员自己制订,一般存放鉴权信息

                   </Header>

                   <Body>  -- 必须要有的元素,程序不能修改,因为body部分需要遵守SOAP协议.

                     --交互正常,body子元素部分遵守SOAP协议,由CXF框架自己生成

                       --交互出错, 包含<soap:Fault>子元素,该子元素中有错误代号与错识原因

                   </Body>

         </Envelope>

        

   

    2. 在客户端添加拦截器查看SOAP包(拷贝7个jar包)

        操作步骤:

      a. 获取Client对象

            Client client = ClientProxy.getClient(服务对象);

 

      b. 获取所有的in拦截器集合

            List<Interceptor<?>> inLists = client.getInInterceptors();

 

      c. 获取所有的out拦截器集合

            List<Interceptor<?>> outLists = client.getOutInterceptors();

 

      d. 添加自己的in拦截器与out拦截器.

            inLists.add(new LoggingInInterceptor());

            outLists.add(new LoggingOutInterceptor());

 

       

   3.做权限拦截.

        -- 思路:需要在soap包中添加一个header元素,用来携带鉴权信息.

            header元素中的子元素应该由服务端来约定. 客户端要遵守服务端的约定.

             在发出soap包时需要在header元素中添加服务端约定的子元素.

 

        a.服务端制订heaer头的约定:

             <header>

                   <auth>

                        <auth_id>admin</aut_id>

                        <auth_pwd>888888</auth_pwd>

                   </auth>

             </header>

 

             服务端需要添加In拦截器,拦截收到得soap包信息,解析header头,进行权限验证.

             -- 需要自定义自己In拦截器. 继承AbstactPhareInterceptor

             

        b.客户端在发送soap包之前,添加header头.

          客户端需要添加Out拦截器,拦截将要发送的soap包, 添加header头.

 

八、ssh + cxf 做服务端

1. 拷贝jar包

(spring4、struts2、hibernate5、mysql、jstl、struts2-spring-plugin).

 

 2. Spring4与Struts2整合

       -- web.xml

       -- /WEB-INF/applicationContext.xml (spring)

       -- src/struts.xml (struts2)

 

 3. Spring4与Hibernate5整合

       -- /WEB-INF/applicationContext.xml

          dataSource、SessionFactory、TransactionManager、声明式事务配置、事务切面

  4. 分包 common、cxf、dao、domain、service

  5. Spring4与cxf整合

       步骤:

       -- 拷贝jar (7个jar)

       -- 需要在web.xml文件中配置它的核心CXFServlet. (java_first_spring_support示例)

          <!-- 配置CXF框架核心的CXFServlet -->

          <servlet>

                    <servlet-name>cxf</servlet-name>

                   <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>

                   <load-on-startup>1</load-on-startup>

             </servlet>

             <servlet-mapping>

                   <servlet-name>cxf</servlet-name>

                   <url-pattern>/services/*</url-pattern>

             </servlet-mapping>

 

        -- 提供cxf与Spring4整合的配置文件

            /WEB-INF/applicationContext-cxf.xml

 

         a. 要引用jaxws这个命名空间.

               xmlns:jaxws="http://cxf.apache.org/jaxws"

               xsi:schemaLocation="http://cxf.apache.org/jaxws

                                   http://cxf.apache.org/schemas/jaxws.xsd">

 

    b. 导入cxf整合spring的一份配置文件

                <!-- 导入CXF整合Spring4的配置文件 -->

               <import resource="classpath:META-INF/cxf/cxf.xml"/>

   

       -- 提供Web Service服务

          <!-- 配置提供Web Service服务

          http://localhost:8080/sshcxf_server/services/fkit

          -->

           <jaxws:endpoint implementor="#adminService" address="/fkit">

                   <!-- 配置In拦截器 -->

                   <jaxws:inInterceptors>

                            <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>

                            <bean class="org.fkjava.sshcxf.cxf.interceptor.AuthInterceptor"/>

                   </jaxws:inInterceptors>

                   <!-- 配置Out拦截器 -->

                   <jaxws:outInterceptors>

                            <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>

                   </jaxws:outInterceptors>

           </jaxws:endpoint>

 

 

九、ssh + cxf 做客户端

(调用第三方的Web Service服务)

 

       Spring4与cxf整合

       步骤:

       -- 拷贝jar (7个jar)

  

       -- 提供cxf与Spring4整合的配置文件

            /WEB-INF/applicationContext-cxf.xml

 

        a. 要引用jaxws这个命名空间.

               xmlns:jaxws="http://cxf.apache.org/jaxws"

               xsi:schemaLocation="http://cxf.apache.org/jaxws

                                   http://cxf.apache.org/schemas/jaxws.xsd">

 

           b. 导入cxf整合spring的一份配置文件

                <!-- 导入CXF整合Spring4的配置文件 -->

               <import resource="classpath:META-INF/cxf/cxf.xml"/>

   

       -- 开发调用第三方Web Service服务的客户端:

 

cxf笔记记录