内容


Apache CXF 简介

开放源代码的服务框架

Comments

开始之前

SOA 目前已经成为了人人皆知的热点,对分析人员来讲,SOA 重点需要加强对业务服务的分析;各种不同的服务是 SOA 的重要基础;ESB 则提供了一个舞台,让各种异构系统的业务服务在这里进行实际业务的展现、集成等。对开发人员来讲,如何更快速地创建出更稳定的业务服务组件是关键;应该更加深入领会使用面向接口的组件化开发方式;开发人员重点是保障服务的生命周期,其它的事情则让业务开发人员来做。

SOA 的重点在于服务的重用,更高一级层次的重用则属于业务层次了。但是对于开发人员来说,重用的层次需要自己掌握与提升,从代码级到组件级、再到业务层次等。

关于本教程

本教程将采取从简单到复杂,知识点和实际代码相结合的方式。先讲述一些简单的概念和代码,使大家先对 CXF 建立起直观的印象,并且能够写出自己的应用程序。然后再介绍 CXF 的类与 Spring 2.0 的简单整合,并且讲述如何使用 Web Services,从而能够在建立好程序的基础之上,增加业务逻辑,组建自己的 Web Services 应用程序。

目标

学完本教程后,您将不仅能够掌握 Apache CXF 的基本知识,可以用 CXF 编写基本的 Web Services,并且能够增加自己的业务逻辑,从而开发满足自己需求的 Web Services 应用,最重要的是学会与 Spring 2.0 框架的无缝整合,快速轻松地实现服务的发布与消费。

先决条件

要学习本教程,您需要有一定的编程经验,并了解面向对象的概念。同时您应该熟悉 Eclipse 开发环境,熟悉 Ant 的基本使用,熟悉基本的 Web 应用程序开发,熟悉基本的 Spring 概念与配置文件的编写。

代码示例和安装要求

您需要一些工具才能试用本教程中的代码。所有这些工具都可以免费下载(参见 参考资源):

  • Java SDK 1.5 或更高版本的 JDK;
  • Apache Ant 1.6.5 或更高版本;
  • Eclipse 3.2 或更高版本;
  • Apache CXF 2.0.2 版本。

CXF 简介

关于 Apache CXF

Apache CXF = Celtix + XFire,Apache CXF 的前身叫 Apache CeltiXfire,现在已经正式更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的支持,并且可以根据实际项目的需要,采用代码优先(Code First)或者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使用。目前它仍只是 Apache 的一个孵化项目。

Apache CXF 是一个开源的 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。

项目目标

下面列出了来自 Apache CXF 官方网站(参见 参考资源)的项目目标。

概要

  • 高性能
  • 可扩展
  • 简单且容易使用

支持多种标准

  • 支持 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;

CXF 安装包

下载及目录结构

CXF 框架目前的最新版本是 2.0.2,可以访问 Apache 站点(链接请见 参考资源)下载 CXF 框架的安装包,下载时请选择“二进制发布包(Binary distribution)”,当然如果您有兴趣也可以下载相应版本的“源代码发布包(Source distribution)”。

下载完成后,将下载的文件解压缩到任意的文件夹中,比如:C:/Java/CXF,在后面的章节中使用 %CXF_HOME% 表示 CXF 框架的存放目录,解压缩后形成的文件目录结构按名称排序如下:

图 1、Apache CXF 发行包的目录结构示意图
图 1、Apache CXF 发行包的目录结构示意图
图 1、Apache CXF 发行包的目录结构示意图

文件目录结构及相关文件的详细说明:

  • bin(目录)

    bin 目录中是 CXF 框架中所提供的代码生成、校验、管理控制台工具:

    • Java to WSDL : java2wsdl
    • CXF Management Console Tool : mc
    • WSDL to Java : wsdl2java
    • WSDL to Service : wsdl2service
    • WSDL to SOAP : wsdl2soap
    • WSDL to XML : wsdl2xml
    • WSDL Validation : wsdlvalidator
    • XSD to WSDL : xsd2wsdl
  • docs(目录)

    CXF 所有类(class)对应的 API 文档,为开发者使用 CXF 完成应用开发提供应有的帮助。

  • etc(目录)

    包含一个基本的 Service 暴露所需要的 web.xml 文件,及其它的配置文件。

  • lib(目录)

    lib 目录中包含 CXF 及其运行时所需要的和可选的第三方支持类包(.jar 文件),可以根据不同项目所需的 CXF 特性选择所需要的支持类包。如果不想一一去区分的话,可以直接在 Web 项目中包含所有的 CXF 及其运行时所需要的第三方支持类包(.jar 文件)即可。

    其中 cxf-2.0.2-incubator.jar 是 CXF 框架的二进制包文件,包含了全部的模块(modules),cxf-manifest-incubator.jar 是列表清单文件 manifest jar 。

    以下的 jar 包是所有 CXF 项目所必需的:

    • cxf.jar
    • commons-logging.jar
    • geronimo-activation.jar (Or the Sun equivalent)
    • geronimo-annotation.jar (Or the Sun equivalent)
    • geronimo-javamail.jar (Or the Sun equivalent)
    • neethi.jar
    • jaxb-api.jar
    • jaxb-impl.jar
    • stax-api.jar
    • XmlSchema.jar
    • wstx-asl.jar
    • xml-resolver.jar

    对于 Java2WSDL 和 WSDL2Java,除了必需的之外,还需要再增加如下 jar 包:

    • jaxb-xjc.jar
    • veliocity.jar
    • velocity-dep.jar

    为了支持 JAX-WS ,除了必需的之外,还需要再增加如下 jar 包:

    • jaxws-api.jar
    • saaj-api.jar
    • saaj-impl.jar
    • asm.jar (可选的,但是可以提升包装类型的性能)

    为了支持 XML 配置,除了必需的之外,还需要再增加如下 jar 包:

    • aopalliance.jar
    • spring-beans.jar
    • spring-context.jar
    • spring-core.jar
    • spring.web.jar

    为了独立的 HTTP 服务支持,除了必需的之外,还需要再增加如下 jar 包:

    • geronimo-servlet.jar
    • jetty.jar
    • jetty-sslengine.jar
    • jetty-util.jar
    • sl4j.jar & sl4j-jdk14.jar (可选的,但是可以提升日志 logging)

    为了支持 Aegis ,除了必需的之外,还需要再增加如下 jar 包:

    • jaxen.jar
    • jdom.jar
    • stax-utils.jar

    为了支持 WS-Security ,除了必需的之外,还需要再增加如下 jar 包:

    • bcprov-jdk14.jar
    • wss4j.jar
    • xalan.jar
    • xmlsec.jar

    为了支持 HTTP Binding ,除了必需的之外,还需要再增加如下 jar 包:

    • jra.jar
    • jettison.jar (仅为 JSON 服务所需的)
  • licenses(目录)

    列表了引用第三方 jar 包的相关许可协议。

  • modules(目录)

    modules 目录中包含了 CXF 框架根据不同特性分开进行编译的二进制包文件。发布基于 CXF 框架的 Web 项目时,可以选择使用该目录下的所有 .jar 文件,也可以选择 lib 目录中的 cxf-2.0.2-incubator.jar 文件。

  • samples(目录)

    samples 目录中包含了所有随 CXF 二进制包发布的示例,包含这些示例的源代码和相关 Web 应用配置文件,可以方便地用 Ant 来编译运行测试这些示例,来了解 CXF 的开发和使用的方法。可以通过 samples 目录和它各个子目录下的 README.txt 的文件来详细了解示例的编译与运行的步骤。

  • DISCLAIMER 由于仍是处于 Apache 孵化状态的项目,这里描述了一些说明。
  • LICENSE 文件中包含了 CXF 框架的授权协议 Apache License Version 2.0 。
  • NOTICE 罗列了 CXF 框架用到的相关第三方组件的授权协议以其它的相关信息。
  • README 文件中包含了 CXF 框架本身的一些简要说明。
  • release_notes.txt 包含了 CXF 发布时的一些信息,包括运行时所需要的环境,修复 BUG 的列表等。

CXF 框架支撑环境

CXF 框架是一种基于 Servlet 技术的 SOA 应用开发框架,要正常运行基于 CXF 应用框架开发的企业应用,除了 CXF 框架本身之外,还需要 JDK 和 Servlet 容器的支持。

JDK 版本选择、下载和安装

CXF 支持非常多的特性,其中不同的特性对 JDK 版本的要求有所不同,但是 JDK 最低的版本是需要选择 JDK 5 或者以上版本。JDK 各版本均可以在 Sun 公司网站上下载(链接见 参考资源),如何安装 JDK 请参考 SUN 公司的相关技术文档和 JDK 的帮助文档。为了运行 CXF 携带的 samples 目录下的所有示例,还需要 Apache Ant 1.6.5 或以上的版本(下载链接见 参考资源)。为了使用 CXF 的 WS-Security 特性,还需要 Bouncy Castle ,可以从网站下载(下载链接见 参考资源),并增加到 CLASSPATH 中。

Servlet 容器下载和安装

CXF 是一种基于 Servlet 技术的 SOA 应用开发框架,需要 Servlet 容器的支持。CXF 支持在多种 Servlet 容器中运行,包括 WebSphere、WebLogic、Tomcat、Jetty 等。为了说明的简单,我们选择使用 Tomcat 5.5.25 和 Jetty 作为 CXF 的运行容器,所有配置过程和发布步骤的说明也均是针对 Tomcat 和 Jetty,如果读者使用 Tomcat 之外的其它 Servlet 容器或者选择了 Tomcat 的其它版本,下面的配置过程和步骤可能需要做出调整,请读者根据实际 Servlet 容器的帮助文档进行相应调整。

Tomcat 与 Jetty 的各个版本均可以在网上下载(下载链接见 参考资源),如何正确安装 Tomcat 与 Jetty 服务器请参考相关的帮助文档。

CXF 之初体验

下面我们将通过直接运行与简单修改 CXF 自带的例子体验一下服务的发布与消费。

配置与检查环境变量

UNIX 上:

CXF_HOME=/opt/Java/CXF
JAVA_HOME=/opt/JDK/1.5.0
ANT_HOME=/opt/Java/Ant
export PATH=$JAVA_HOME/bin:$ANT_HOME/bin:$CXF_HOME/bin:$PATH
export CLASSPATH=.:$CXF_HOME/lib/cxf-manifest-incubator.jar:./build/classes

Windows 上:

set CXF_HOME=C:\Java\CXF
set JAVA_HOME=C:\JDK\1.5.0
set ANT_HOME=C:\Java\Ant
set PATH=%JAVA_HOME%\bin;%ANT_HOME%\bin;%CXF_HOME%\bin;%PATH%
set CLASSPATH=.;%CXF_HOME%\lib\cxf-manifest-incubator.jar;.\build\classes

为了部署到 Java EE 的容器中进行测试,示例采用 Tomcat 来进行,同样设置 CATALINA_HOME 变量:

UNIX 上:

CATALINA_HOME=/opt/OpenSource/Tomcat-5.5.25
export CATALINA_HOME

Windows 上:

set CATALINA_HOME=C:\OpenSource\Tomcat-5.5.25

如果以上环境变量您没有并没有直接设置到系统的变量中,可以将之另存为一个文件,保存起来,比如存为:%CXF_HOME%/env.sh 或者 %CXF_HOME%/env.bat,这样在运行示例前,先运行它来设置环境变量即可。

通过 Ant 来构建和运行示例

构建与启动 Server

首先,进入到 %CXF_HOME%/java_first_pojo/ 目录下。在 UNIX 或 Windows 下的命令都是一样的,如下:

ant server

最后可以看到如下信息:

build:

server:
 [java] Server ready...

如果看不到这些信息,请检查环境变量设置是否正确。

运行 Client

再打开一个命令窗口,运行:

ant client

最后可以看到如下信息:

client:
 [java] Invoke sayHi()....
 [java] Hello user

BUILD SUCCESSFUL

如果看不到这些信息,问题应当是出现在环境变量的设置上,需要再次检查一下您的环境变量设置是否正确。

体验改变

通过上面的构建,运行 Server ,再运行 Client ,我们可以体会到利用 CXF 发布与使用 Web Services 是如此简单。下面我们将开始进行简单地代码修改。

修改 Client 端

打开 %CXF_HOME%/samples/java_first_pojo/src/demo/hw/client 目录下的 Client.java 文件,在最后面修改为:

System.out.println(client.sayHi("World , 利用 Apache CXF 实现 Web Services"));

修改并保存后,再运行:

ant client

现在可以看到您修改后的信息,如下:

client:
 [java] Invoke sayHi()....
 [java] Hello World , 利用 Apache CXF 实现 Web Services

BUILD SUCCESSFUL

修改 Server 端代码

Ctrl + C 直接停止刚才启动的 ant server 启动端,然后打开 %CXF_HOME%/samples/java_first_pojo/src/demo/hw/server 目录下的 HelloWorldImpl.java 文件,修改

return "Hello " + text;

return "Hello " + text + new java.util.Date();

我们在返回信息时增加了一个时间戳上去,然后再次分别运行 ant server 与 ant client ,可以看到返回的信息后面增加了时间,如下:

client:
 [java] Invoke sayHi()....
 [java] Hello World , 利用 Apache CXF 实现 Web ServicesThu Sep 27 21:40:49 CST 2007

BUILD SUCCESSFUL

以上只是一个简单的示例,体验一下利用 CXF 进行发布与使用 Web Services,并尝试修改了 Server 端与 Client 端的代码。下面让我们更进一步,通过查看 Server.java 及 Client.java 的代码,来了解一下 CXF 的运作过程。

代码简单分析

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

 HelloWorldImpl helloworldImpl = new HelloWorldImpl();
 ServerFactoryBean svrFactory = new ServerFactoryBean();
 svrFactory.setServiceClass(HelloWorld.class);
 svrFactory.setAddress("http://localhost:9000/Hello");
 svrFactory.setServiceBean(helloworldImpl);
 svrFactory.create();

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

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

最后,停止 Server,并清除构建过程中产生的一些文件,直接运行 ant clean 即可。

构建和运行在 Servlet 容器里的示例

接下来我们尝试编译打包一个示例,并部署到 Java EE 的容器里进行测试。

构建 Web 应用程序包

停止掉前面运行的 Server ,然后在命令行运行:

ant war

将在 %CXF_HOME%/samples/java_first_pojo/build/war/ 目录下生成 helloworld.war 文件。

部署应用

先运行如下命令,将运行部署到 Tomcat 容器中:

ant deploy -Dtomcat=true

启动 Tomcat

然后在 Windows 下通过 startup.bat 或在 Unix 下通过 startup.sh 来启动 Tomcat,CXF 的应用也就随之启动。通过 Tomcat 管理控制台 http://localhost:8080/manager/html/ 可以看到已经成功部署了 helloworld.war 的应用程序,如下图所示:

图 2. 在 Tomcat 5.5.25 上面成功部署 CXF Web Service 的示意图
图 2. 在 Tomcat 5.5.25 上面成功部署 CXF Web Service 的示意图
图 2. 在 Tomcat 5.5.25 上面成功部署 CXF Web Service 的示意图

校验服务

假设您的 Tomcat 服务端口是 8080 ,那运行以下命令就可以调用部署到 Java EE 容器里的 CXF 所提供的 Web Services 的服务了。

http://localhost:8080/helloworld/services/hello_world?wsdl

查看 wsdl 文件的信息内容如下:

图 3. 在 Tomcat 5.5.25 上面成功部署 CXF Web Service 的示意图
图 3. 在 Tomcat 5.5.25 上面成功部署 CXF Web Service 的示意图
图 3. 在 Tomcat 5.5.25 上面成功部署 CXF Web Service 的示意图

运行 Client

接下来我们来运行 Client 来使用它,运行:

ant client-servlet

如果您的端口不是 8080,可以使用:

ant client-servlet -Dbase.url=http://localhost: 端口号

或者

ant client-servlet -Dhost=localhost -Dport= 端口号

来调用 Web Services ,返回结果如下:

client-servlet:
 [java] Invoke sayHi()....
 [java] Hello World , 利用 Apache CXF 实现 Web ServicesThu Sep 27 21:56:32 CST 2007

BUILD SUCCESSFUL

在 Tomcat 后台可以看到一些 Exception 的信息,这是正常的,是因为 public void pingMe() throws PingMeFault 特意抛出来的,不必理会,没有抛出异常信息才是不正常的,需要重新检查以上各个步骤是否正确执行了。

卸载应用

从 Tomcat 中卸载应用,运行:

ant undeploy -Dtomcat=true

最后,停止 Tomcat,然后清除构建过程中产生的一些文件,直接运行 ant clean 即可。

CXF 应用开发

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

开发环境准备

在开发之前我们通常需要做些准备工作,比如搭建好开发环境。在本教程中,我们将在 Eclipse 3.2 环境中开发,当然如果您是使用 Eclipse Europa(Eclipse 3.3)也是可以的,我们假设您已经下载并且在计算机中安装好了 Eclipse 开发环境(关于如何下载和安装 Eclipse,请参见 参考资源)。

创建项目骨架

启动 Eclipse,创建一个 Java Project,如果是 WTP 的话,可以直接创建一个 J2EE 的 Web 项目,我们取名为 CXF_Spring_Survey,并设置编译的 output 路径为 WEB-INF/classes 目录,方便直接部署应用程序。

目录结构如下图所示:

图 4. 利用 CXF 开发 Web Services 的工程骨架示意图
图 4. 利用 CXF 开发 Web Services 的工程骨架示意图

为了方便起见,我们直接拷贝 %CXF_HOME%/lib 目录下的所有 .jar 文件到 CXF_Spring_Survey 项目的 WEB-INF/lib 目录下,也可以根据前面“CXF 安装包”章节所述的各个 jar 包的作用范围选择仅需要的 .jar 文件。在 Eclipse 里刷新后,可以看到如下结构:

图 5. 利用 CXF 开发 Web Services 的工程引入所有 .jar 文件后的骨架示意图
图 5. 利用 CXF 开发 Web Services 的工程引入所有 .jar 文件后的骨架示意图
图 5. 利用 CXF 开发 Web Services 的工程引入所有 .jar 文件后的骨架示意图

并在 CXF_Spring_Survey 项目属性里将这些 .jar 加到 Java Build Path 当中去,如下图:

图 6. Eclipse 中引入所有 .jar 文件后的示意图
图 6. Eclipse 中引入所有 .jar 文件后的示意图
图 6. Eclipse 中引入所有 .jar 文件后的示意图

这样,项目的基本骨架已经创建完成,接下来开始编写接口与具体实现的代码了。

接口类创建

在项目的 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 定义是一样的:

    <!-- SurveyService -->
    <bean id="surveyService" class="ws.cxf.impl.SurveyService">
        <property name="excludeName" value="Michael"/>
        <property name="leastPonit" value="10"/>
    </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,如下:

    <!-- Spring Config Location -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/classes/beanRefServer.xml</param-value>
    </context-param>
    <!-- Spring ContextLoaderListener -->
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </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 容器中去,并验证服务是否正常发布。

应用部署

我们将应用部署到 Tomcat 5.5.25 当中,在这里,我们采用链接(Link)的部署方式,简单而方便,在 %TOMCAT_HOME%/conf/Catalina/localhost/ 目录下创建与项目名称 CXF_Spring_Survey 一致的 xml 文件:CXF_Spring_Survey.xml,内容为:

<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="F:/JavaProject/WebService/CXF/CXF_Spring_Survey"/>

docBase 里的内容根据您的实际项目所在的目录进行更改,注意使用 / 而不是 \ 即可。

启动服务

这时开始启动 Tomcat ,在启动的过程中,可以在启动窗口上看到以链接方式部署的应用在启动中会打印出一些相关信息来,最后显示启动成功。 通过访问 http://localhost:8080/CXF_Spring_Survey/ 可以看到 CXF 暴露的服务链接:

图 7. CXF 暴露的服务链接的内容示意图
图 7. CXF 暴露的服务链接的内容示意图
图 7. CXF 暴露的服务链接的内容示意图

可以直接点击进去,或者手工输入 WSDL 的地址进行访问:http://localhost:8080/CXF_Spring_Survey/SurveyWebService?wsdl ,可以看到如下的 WSDL 内容:

图 8. SurveyWebService 的 WSDL 内容示意图
图 8. SurveyWebService 的 WSDL 内容示意图
图 8. SurveyWebService 的 WSDL 内容示意图

这样,我们可以确定我们的服务真正发布成功了,接下来就可以利用客户端进行消费了。

消费服务

回到 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,完整的代码如下:

package ws.cxf.client;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import ws.cxf.ISurveyService;

public class SurveyServiceClient
{
	public static void main(String[] args)
	{
		// 加载客户端的配置定义
		ApplicationContext context = new 
				ClassPathXmlApplicationContext("beanRefClient.xml");
		// 获取定义的 Web Service Bean
		ISurveyService surveyService = 
			(ISurveyService)context.getBean("surveyServiceClient");
		// 1、定义调查投票的变量与内容,用来发送给服务
		String username = "Test";
		int point = 88;
		// 调用方法进行服务消费
		String result = surveyService.vote(username,point);
		System.out.println("Result:" + result);
		// 2、传递不一样的调查投票内容
		username = "Michael";
		point = 100;
		// 再次调用方法进行服务消费,得到不一样的结果
		result = surveyService.vote(username,point);
		System.out.println("Result:" + result);
		// 3、第三次传递与调用
		username = "Jordan";
		point = 9;
		result = surveyService.vote(username,point);
		System.out.println("Result:" + result);
	}
}

直接运行以上客户端消费程序,一共调用了三次 Web Service,并得到结果如下:

Result: 谢谢您的投票!您的投票分数通过审核!
Result: 您不能重复进行投票!
Result: 谢谢您的投票!您的投票分数太低!

于是服务正常地得到了调用,并且能够正确地返回结果,完整的代码及配置文件可以在本教程的 下载链接 里进行下载。

结束语

本文教程中,我们结合了一个简单的例子,将 CXF 与 Spring 的简单配置与整合完整地演示出来,最后我们完成了对 Web Services 的发布与消费。在各种 Web Services 实现框架共存的开源社区与商业实现中,CXF 整合了 Celtix 与 XFire 的精华,相信凭借它简单的配置,与 Spring 无缝整合,肯定会在 Web Services 领域中占有一席之地。但作为一个新的项目,要被广大开发者所接受并在企业应用开发中使用,仍有一段比较长的路要走,让我们拭目以待吧!


下载资源


相关主题

  • Apache CXF 的官方站点:提供关于 CXF 的最新发布信息,相关版本的软件包下载,相关用户手册及参考文档,感觉兴趣的话还可以从此站点下载源代码回来研究学习。
  • XFire 入门:介绍了如何使用 XFire 轻松的将 Pojo 对象发布成 Web 服务。
  • IBM developerWorks SOA and Web services 专区 提供了大量的文章,以及关于如何开发 Web 服务应用程序的初级、中级和高级教程。
  • 下载 最新版的 Java SDK。
  • 下载 最新版的 Apache Ant。
  • 下载 免费的开源的 Serlvet 容器 Tomcat。
  • 下载 免费的开源的 Serlvet 容器 Jetty。
  • 下载 最新版的 Eclipse IDE。
  • developerWorks Java 技术专区:这里有数百篇关于 Java 编程各个方面的文章。

评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Java technology, SOA and web services, Open source
ArticleID=290840
ArticleTitle=Apache CXF 简介
publish-date=02212008