zoukankan      html  css  js  c++  java
  • Apache CXF 入门详解

    以前没有接触过CXF,项目需要学习,从网上各种找资料加上项目的实践,不断垒字。

    CXF (Celtix + XFire)是一个开源的Services框架。CXF 帮助您利用 Frontend 编程 API 来构建和开发 Services ,像 JAX-WS 。这些 Services 可以支持多种协议,比如:SOAP、XML/HTTP、RESTful HTTP 或者 CORBA ,并且可以在多种传输协议上运行,比如:HTTP、JMS 或者 JBI,CXF 大大简化了 Services 的创建,同时它继承了 XFire 传统,一样可以天然地和 Spring 进行无缝集成。

    功能特性

    CXF 包含了大量的功能特性,但是主要集中在以下几个方面:

    1. 支持 Web Services 标准:CXF 支持多种 Web Services 标准,包含 SOAP、Basic Profile、WS-Addressing、WS-Policy、WS-ReliableMessaging 和 WS-Security。
    2. Frontends:CXF 支持多种“Frontend”编程模型,CXF 实现了 JAX-WS API (遵循 JAX-WS 2.0 TCK 版本),它也包含一个“simple frontend”允许客户端和 EndPoint 的创建,而不需要 Annotation 注解。CXF 既支持 WSDL 优先开发,也支持从 Java 的代码优先开发模式。
    3. 容易使用: CXF 设计得更加直观与容易使用。有大量简单的 API 用来快速地构建代码优先的 Services,各种 Maven 的插件也使集成更加容易,支持 JAX-WS API ,支持 Spring 2.0 更加简化的 XML 配置方式,等等。
    4. 支持二进制和遗留协议:CXF 的设计是一种可插拨的架构,既可以支持 XML ,也可以支持非 XML 的类型绑定,比如:JSON 和 CORBA。

    支持多种标准

    • 支持 JAX-WS、 JAX-WSA、JSR-181 和 SAAJ;
    • 支持 SOAP 1.1、1.2、WS-I BasicProfile、WS-Security、WS-Addressing、WS-RM 和 WS-Policy;
    • 支持 WSDL 1.1 、2.0;
    • 支持 MTOM;

    多种传输方式、Bindings、Data Bindings 和 Format

    • Bindings:SOAP、REST/HTTP;
    • Data Bndings:目前支持 JAXB 2.0、Aegis 两种,默认是 JAXB 2.0。XMLBeans、Castor 和 JiBX 数据绑定方式将在 CXF 2.1 版本中得到支持;
    • 格式(Format):XML、JSON;
    • 传输方式:HTTP、Servlet、JMS 和 Jabber;
    • 可扩展的 API 允许为 CXF 增加其它的 Bindings,以能够支持其它的消息格式,比如:CSV 和固定记录长度。

    灵活部署

    • 轻量级容器:可在 Tomcat 或基于 Spring 的容器中部署 Services;
    • 集成 JBI:可以在如 ServiceMix, OpenESB or Petals 等等的 JBI 容器中将它部署为一个服务引擎;
    • 集成 SCA:可以部署在如 Tuscany 之类的 SCA 容器中;
    • 集成 J2EE:可以在 J2EE 应用服务器中部署 Services,比如:Geronimo、JOnAS、JBoss、WebSphere Application Server 和 WebLogic Application Server,以及 Jetty 和 Tomcat;
    • 独立的 Java 客户端/服务器。

    支持多种编程语言

    • 全面支持 JAX-WS 2.0 客户端/服务器编程模型;
    • 支持 JAX-WS 2.0 synchronous、asynchronous 和 one-way API's;
    • 支持 JAX-WS 2.0 Dynamic Invocation Interface (DII) API;
    • 支持 wrapped and non-wrapped 风格;
    • 支持 XML messaging API;
    • 支持 JavaScript 和 ECMAScript 4 XML (E4X) ,客户端与服务端均支持;
    • 通过 Yoko 支持 CORBA;
    • 通过 Tuscany 支持 SCA;
    • 通过 ServiceMix 支持 JBI ;

    代码生成

    • Java to WSDL;
    • WSDL to Java;
    • XSD to WSDL;
    • WSDL to XML;
    • WSDL to SOAP;
    • WSDL to Service;

     代码简单分析

    通过查看 Server.java 及 Client.java 的代码,来了解一下 CXF 的运作过程。Server.java 中主要的代码片断如下,它利用 ServerFactoryBean 来进行 Web Services 的发布,实例化一个实现类 HelloWorldImpl,设置将要进行发布的地址 address,最后通过 ServerFactoryBean 的 create() 方法就成功地发布了 Web Services,如此简单而已,只有六行代码:

    1 HelloWorldImpl helloworldImpl = new HelloWorldImpl();
    2  ServerFactoryBean svrFactory = new ServerFactoryBean();
    3  svrFactory.setServiceClass(HelloWorld.class);
    4  svrFactory.setAddress("http://localhost:9000/Hello");
    5  svrFactory.setServiceBean(helloworldImpl);
    6  svrFactory.create();

    Client.java 中的主要代码片断如下,通过 ClientProxyFactoryBean 代理工厂类来创建一个服务,绑定到 endPointAddress 地址,就可以 create 并得到服务,并进行服务消费了:

    1  ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
    2  factory.setServiceClass(HelloWorld.class);
    3  factory.setAddress("http://localhost:9000/Hello");
    4  HelloWorld client = (HelloWorld)factory.create();
    5  System.out.println("Invoke sayHi()....");
    6  System.out.println(client.sayHi("user"));

    CXF 应用开发

    下面就将开始我们的 CXF Web Services 的开发之旅!首先,要有一个基于 Eclipse 的开发环境;然后,我们将利用这个开发环境开发一个简单的“调查投票”示例,同时我们将解释一些 CXF 在开发中进行配置的基本方法。

    接口类创建

    在项目的 src 目录中新建一个 ws.cxf 包,并在里面创建接口类 ISurveyService.java,为了简单示示例起见,我们仅创建一个方法 public String vote(String username,int point); 这里要注意的是我们在接口上用 @WebService 注解标明这是一个即将暴露为 Web Service 的接口,并将里面的方法都暴露出去。完整的接口代码清单如下:

    package ws.cxf;
    
    import javax.jws.WebService;
    
    @WebService
    public interface ISurveyService
    {
        /**
         * @param username 名字
         * @param point 分数
         * @return
         */
        public String vote(String username,int point);
    }

    接下来,我们根据接口的定义,来实现它。

    具体类实现

    针对接口的定义,我们创建一个相应的实现类,并将其定义在 sw.cxf.impl 包中,完整的代码清单如下:

    package ws.cxf.impl;
    
    import javax.jws.WebService;
    import ws.cxf.ISurveyService;
    
    @WebService
    public class SurveyService implements ISurveyService
    {
        private String excludeName = "Michael";
        private int leastPonit = 5;
    
        public String vote(String username,int point)
        {
            String result = "";
            if(excludeName.equals(username))
            {
                result = " 您不能重复进行投票!";
            }
            else
            {
                result = " 谢谢您的投票!";
                if(point < leastPonit)
                {
                    result += " 您的投票分数太低!";
                }
                else
                {
                    result += " 您的投票分数通过审核!";
                }
            }
            return result;
        }
    
        // For IoC
        public String getExcludeName()
        {
            return excludeName;
        }
    
        public void setExcludeName(String excludeName)
        {
            this.excludeName = excludeName;
        }
    
        public int getLeastPonit()
        {
            return leastPonit;
        }
    
        public void setLeastPonit(int leastPonit)
        {
            this.leastPonit = leastPonit;
        }
    }

    接口定义与具体的实现就这样简单完成了,接下来就是相关的配置工作了,首先进行 Spring 的 Bean 配置。

    Spring 配置

    在 src 目录中创建 beanRefServer.xml 文件,用来定义 Spring 的 Bean 的配置,CXF 支持 Spring 2.0 Schema 标签配置方式,并且提供快捷暴露 Web Services 的标签。

    首先,我们需要引入 Spring 与 CXF 的命名空间(namespace),如下:

    <beans xmlns="http://www.springframework.org/schema/beans" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:jaxws="http://cxf.apache.org/jaxws"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
            http://cxf.apache.org/jaxws 
            http://cxf.apache.org/schemas/jaxws.xsd">

    这样,我们可以使用 Spring 与 CXF 的标签配置了。接着,我们需要引入我们所需要的 CXF 的 Bean 定义文件,如下:

    <!-- Import Apache CXF Bean Definition -->
        <import resource="classpath:META-INF/cxf/cxf.xml"/>
        <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
        <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>

    接着定义我们具体实现的 Bean ,这个 Bean 的定义与 Spring 普通的 Bean 定义是一样的:

    1 <!-- SurveyService -->
    2     <bean id="surveyService" class="ws.cxf.impl.SurveyService">
    3         <property name="excludeName" value="Michael"/>
    4         <property name="leastPonit" value="10"/>
    5     </bean>

    最后,将定义的 Bean 暴露出去成为 Web Service 服务,通过 CXF 提供的 Schema 标签配置 <jaxws:server> ,这样定义的配置显得更加简洁与方便,定义如下:

     <!-- Expose SurveyWebService -->
        <jaxws:server id="surveyWebService" 
            serviceClass="ws.cxf.ISurveyService" 
            address="/SurveyWebService">
            <jaxws:serviceBean>
                <ref bean="surveyService"/> <!-- 要暴露的 bean 的引用 -->
                </jaxws:serviceBean>
        </jaxws:server>

    在配置中,serviceClass 的值是我们的接口类的名称,address 为将要暴露出去的 Web Service 访问地址。比如:/SurveyWebService,那么客户端消费 Web Service 的地址就会成为 http://host:port/WebAPPName/SurveyWebService ,与之相应的 WSDL 地址则为: http://host:port/WebAPPName/SurveyWebService?wsdl 。

    Web 应用配置

    由于我们的示例是需要通过 Servlet 容器进行服务暴露,因此需要配置相对应的 web.xml 文件,首先是增加 Spring 的配置文件加载 Listener,如下:

     1  <!-- Spring Config Location -->
     2     <context-param>
     3         <param-name>contextConfigLocation</param-name>
     4         <param-value>/WEB-INF/classes/beanRefServer.xml</param-value>
     5     </context-param>
     6     <!-- Spring ContextLoaderListener -->
     7     <listener>
     8         <listener-class>
     9             org.springframework.web.context.ContextLoaderListener
    10         </listener-class>
    11     </listener>

    接下来配置 CXF Servlet 的定义,以及它的映射,如下:

    <!-- Apache CXFServlet -->
        <servlet>
            <servlet-name>CXFServlet</servlet-name>
            <display-name>CXF Servlet</display-name>
            <servlet-class>
                org.apache.cxf.transport.servlet.CXFServlet
            </servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <!-- CXFServlet Mapping -->
        <servlet-mapping>
            <servlet-name>CXFServlet</servlet-name>
            <url-pattern>/*</url-pattern>
        </servlet-mapping>

    我们将之映射为 /* 。这样,服务端的代码与配置就全部完成了,接下来就是将应用程序部署到 Web 容器中去,并验证服务是否正常发布。

     

    服务器端写完接下来就可以利用客户端进行消费了:

    消费服务

    回到 Eclipse 开发平台,开始编写消费服务相关的代码,首先通过 Spring 与 CXF 的配置来定义 Web Service 的客户端 Bean,在 src 目录下创建 beanRefClient.xml 配置文件,同样,我们也需要引入 Spring 与 CXF 命名空间的声明,并引入 CXF 的 Bean 的定义文件,最后通过与服务端配置相对的 CXF 标签 <jaxws:client> 来定义客户端访问服务的声明,完整的定义内容如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:jaxws="http://cxf.apache.org/jaxws"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
            http://cxf.apache.org/jaxws 
            http://cxf.apache.org/schemas/jaxws.xsd">
        <!-- Import Apache CXF Bean Definition -->
        <import resource="classpath:META-INF/cxf/cxf.xml"/>
        <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
        <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
    
        <!-- SurveyWebService Client -->
        <jaxws:client id="surveyServiceClient" 
            serviceClass="ws.cxf.ISurveyService" 
            address="http://localhost:8080/CXF_Spring_Survey/SurveyWebService"/>
    </beans>

    定义说明:id 为 Spring 定义的 id,用来在程序里进行获取它的标识,serviceClass 仍是为服务端定义的接口类,address 为完整的 Web Service 地址,这个与服务端的定义不一样。

    定义完配置文件,接下来我们编写访问的具体代码,在 test 目录下创建 ws.cxf.client 包,然后创建 SurveyServiceClient.java,完整的代码如下:

     1 package ws.cxf.client;
     2 
     3 import org.springframework.context.ApplicationContext;
     4 import org.springframework.context.support.ClassPathXmlApplicationContext;
     5 import ws.cxf.ISurveyService;
     6 
     7 public class SurveyServiceClient
     8 {
     9     public static void main(String[] args)
    10     {
    11         // 加载客户端的配置定义
    12         ApplicationContext context = new 
    13                 ClassPathXmlApplicationContext("beanRefClient.xml");
    14         // 获取定义的 Web Service Bean
    15         ISurveyService surveyService = 
    16             (ISurveyService)context.getBean("surveyServiceClient");
    17         // 1、定义调查投票的变量与内容,用来发送给服务
    18         String username = "Test";
    19         int point = 88;
    20         // 调用方法进行服务消费
    21         String result = surveyService.vote(username,point);
    22         System.out.println("Result:" + result);
    23         // 2、传递不一样的调查投票内容
    24         username = "Michael";
    25         point = 100;
    26         // 再次调用方法进行服务消费,得到不一样的结果
    27         result = surveyService.vote(username,point);
    28         System.out.println("Result:" + result);
    29         // 3、第三次传递与调用
    30         username = "Jordan";
    31         point = 9;
    32         result = surveyService.vote(username,point);
    33         System.out.println("Result:" + result);
    34     }
    35 }

    references:

    https://www.ibm.com/developerworks/cn/education/java/j-cxf/

  • 相关阅读:
    Exchange 2013与 Office Web Apps 整合
    SharePoint2013 以其他用户登录和修改AD域用户密码 功能
    sharepoint 2010 自定义页面布局
    sharepoint 2010 记录管理 对象模型
    SharePoint2010 对象模型 关联列表
    在SharePoint Server 2010中更改“我的网站”
    xenapp 6.5 客户端插件第一次安装总是跳到官网
    如何解决在Windows Server 2008 R2 上安装证书服务重启后出现 CertificationAuthority 91错误事件
    在Win7 Hyper-v虚拟机中挂接真实机的声卡
    win8 中如何删除 共享文件夹 用户名和密码
  • 原文地址:https://www.cnblogs.com/hoojjack/p/6724659.html
Copyright © 2011-2022 走看看