Java Web 服务: CXF 简介

了解来自 Apache Software Foundation 的另一 Web 服务框架

Apache CXF Web 服务堆栈支持 JAXB 2.x 数据绑定和 JAX-WS 2.x 服务配置。与前面文章所讨论的 Metro Web 服务堆栈相类似,CXF 也使用 XML 文件来扩展 JAX-WS 的配置信息。在本文中,Java Web 服务专栏作者 Dennis Sosnoski 对 CXF 框架的客户和服务器端开发的基础知识进行了介绍。

Dennis Sosnoski, 架构咨询师和培训师, Sosnoski Software Associates Ltd

Dennis Sosnoski 是一名咨询师和培训师,专长是基于 Java 的 XML 和 Web 服务。他有 30 多年的专业软件开发经验,最近 10 年一直致力于服务器端 XML 和 Java 技术方面的工作。Dennis 是开源 JiBX XML Data Binding 框架及相关的 JiBX/WS Web 服务框架的首席开发人员,也是 Apache Axis2 Web 服务框架的提交者。他还是 JAX-WS 2.0 和 JAXB 2.0 规范的专家组成员之一。



2010 年 3 月 29 日

Apache CXF Web 服务堆栈是来自 Apache Software Foundation 的另一替代选择,Axis2 堆栈也来自同一组织。尽管它们来自同一组织,Axis 2 和 CXF 就如何配置和交付 Web 服务采用完全不同的方法。在本文中,您将学习为 CXF Web 服务使用 JAXB 2.x 和 JAX-WS 2.x 的基础,还将比较 CXF 与其他 JAXB/JAX-WS 堆栈 — Axis2 和 Metro — 这两个堆栈在之前的文章中讨论过。

CXF 基础比较

在用户界面方面,CXF 与 Axis2 和 Metro Web 服务堆栈有很多共同之处。三个堆栈都允许要么从已有 Java™ 代码开始构建 Web 服务,要么从 WSDL Web 服务描述开始,生成使用或实现服务的 Java 代码。而且与其他堆栈一样,CXF 将服务操作建模为方法调用,而将服务端口类型建模为接口。

关于本系列

Web 服务构成了 Java 技术在企业计算应用中的关键部分。在本系列文章中,XML 和 Web 服务顾问 Dennis Sosnoski 介绍了对于使用 Web 服务的 Java 开发人员来说比较重要的主要框架和技术。通过跟随本系列的学习,您将了解到该领域的最新进展,并且知道如何使用它们来为您的编程项目提供帮助。

与 Axis2 类似,但是不同于 Metro,CXF 允许选择不同的数据绑定技术。CXF 对 JAXB 2.x 的支持与 Metro 同等而高于 Axis2,因为它允许从 WSDL 生成代码时使用 JAXB 标准(而 Axis2 不允许)。CXF 还允许使用其他数据绑定方法,不过对这些方法的支持不像在 Axis2 中那样成熟 — 特别是,只有在使用 JAXB 或 XMLBeans 数据绑定时才能使用 CXF 从 WSDL 生成代码。

CXF 使用的首选服务配置技术(或在 CXF 术语中称为前端) 是 JAX-WS 2.x 注释,通常附有 XML 配置文件。CXF 中对 JAX-WS 注释的支持与 Metro 同等,因而与 Axis2(在 Axis2 中使用 JAX-WS 时存在一些限制,正如 “Axis2 中的 JAXB 和 JAX-WS” 所述)相比,CXF 更适合使用 JAX-WS。与其他 JAX-WS 实现一样,CXF 需要服务 WSDL 在运行时可用于客户机。

同其他堆栈一样,CXF 使用由可配置组件组成的请求和响应处理流。CXF 调用组件 intercepters,而非 handlers,不过除此以外的其他组件是等效组件。与 Metro 相同的是,CXF 完全支持 WS-Security 和其他扩展技术,将其作为基础下载的一部分。与 Metro 不同的是,CXF JARs 是模块化的 — 即您可以根据正在使用的技术选择 JARs 使其成为应用程序的一部分(CXF 安装目录中的 /lib/WHICH_JARS 文件会告诉您各种常见用例所需的特定 JARs)。该模块化的负面效应是最终会产生应用程序所需的一长列特定 JARs;从有利的一面来说,它允许控制部署的大小。

另一个与 Metro 的相同之处是,CXF 通常需要为 Web 服务构建一个 WAR 文件,而非潜在地部署多个服务到单个服务安装上(这正是 Axis2 所用的方法)。CXF 还以 Jetty 服务器的形式提供一个适合生产使用的集成 HTTP 服务器。与 Axis2 和 Metro 中集成的简单服务器支持相比,这可以提供一个更灵活、强大的替代选择。


示例应用程序

代码下载 部分提供了本系列之前文章中使用的简单的书库管理服务的一个版本,该版本经过了修改,以演示 CXF 的使用。和之前的版本一样,WSDL 服务定义一共定义 4 个操作:

  • getBook 用于获取 International Standard Book Number (ISBN) 标识的特定图书的详细信息。
  • getBooksByType 用于获取某种类型的所有图书的详细信息。
  • getTypes 用于发现现有的图书类型。
  • addBook 用于将新的图书添加到书库。

在 “Axis2 中的 JAXB 和 JAX-WS” 中,您看到了这个应用程序在 Axis2 中如何工作,然后在 “Metro 简介” 中,您看到了它如何在 Metro 中工作。 这几篇文章中的大部分内容也适用于使用 CXF 的情况。除了服务名称和端点地址不同外,WSDL 是相同的;生成的 JAXB 数据模型是相同的,甚至生成的服务类也是相同的,只是 Java 包和 JAX-WS 注释中使用的服务名称不同。

客户端的使用

与在 Axis2 或 Metro 中使用 JAX-WS 相比,在 CXF 中,示例应用程序的客户端代码是相同的,甚至构建步骤也是类似的:只需代替 JAX-WS 参考实现 wsimport 工具使用 CXF wsdl2java 工具即可。参阅 “Axis2 中的 JAXB 和 JAX-WS” 了解代码和处理的详细信息。

尽管客户端代码相同,不过 CXF 中的客户端行为仍然有一个显著差异。默认情况下,CXF 打印大量令人不悦的日志细节并输出到控制台。CXF 使用 Java 日志记录,因此为避免此输出,您需要设置一个系统属性使其指向一个日志属性文件,设置为仅在有 WARNINGSEVERE 信息时输出日志。示例应用程序所用的 Ant build.xml 使用 JVM 参数行 <jvmarg value="-Djava.util.logging.config.file=${build-dir}/logging.properties"/> 完成这个设置。

服务器端的使用

与在 Axis2 或 Metro 中使用 JAX-WS 相比,在 CXF 中,示例应用程序的客户端代码也是一样的,且构建步骤与 Metro 很相似。使用 Axis2 时,是通过创建一个包含服务和数据模型类的 JAR 文件来准备用于部署的服务,然后通过将该 JAR 拖放到 Axis2 服务器安装目录中的 WEB-INF/servicejars 目录中来部署服务。而当使用 Metro 和 CXF 时,则需要创建一个包含服务和数据模型类、Metro 或 CXF 库 JARs 以及一对配置文件(其中一个文件在这两个堆栈中名称不同)的 WAR 文件。WEB-INF/web.xml 文件配置真正的 servlet 处理。用于示例应用程序的版本如 清单 1 所示:

清单 1. 示例应用程序 web.xml
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee">
  <display-name>CXFLibrary</display-name>
  <description>CXF Library Service</description>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
      classpath:META-INF/cxf/cxf.xml
      classpath:META-INF/cxf/cxf-extension-soap.xml
      classpath:META-INF/cxf/cxf-servlet.xml
     </param-value>
  </context-param>
  <servlet>
    <servlet-name>CXFServlet</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

清单 1 WEB-INF/web.xml 文件正是一个标准 servlet 配置文件,它告诉 Web 应用程序服务器(比如 Tomcat)如何接口到 servlet 应用程序。详情与 Metro 示例中的那些细节一样,不过对于 CXF,<servlet-class> 是 CXF 代码的一部分而 <listener-class> 引用一个 Spring Framework 类 (参阅 参考资料)。与 Metro 示例一样,servlet 被配置为接收所有传入该 Web 应用程序的请求(通过 <url-pattern>/</url-pattern> 条目)。

一个独立文件 WEB-INF/cxf-servlet.xml 用于配置 CXF,使其将 servlet 接收的请求路由到服务实现代码并按需提供服务 WSDL。该文件如 清单 2 所示:

清单 2. 示例应用程序 cxf-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:jaxws="http://cxf.apache.org/jaxws"
      xmlns:soap="http://cxf.apache.org/bindings/soap"
      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">

    <jaxws:endpoint
        id="Processor"
        implementor="com.sosnoski.ws.library.cxf.CXFLibraryImpl"
        wsdlLocation="WEB-INF/wsdl/library.wsdl"
        address="/">
    </jaxws:endpoint>
</beans>

清单 2 WEB-INF/cxf-servlet.xml 文件只有一个端点定义,其中包括一个实现类、请求的匹配模式以及 WSDL 文档位置。WSDL 文档位置是这个端点定义中惟一的可选项。如果在 cxf-servlet.xml 文件中不指定服务端点的 WSDL 文档,CXF 会在运行时基于 JAX-WS 注释自动生成一个 WSDL 文档。

构建和运行示例代码

捆绑带来的问题

从 Java SE 6 开始,JAXB 2.x 和 JAX-WS 2.x 参考实现运行时(除了供应商扩展)成为标准 Java Runtime Environment (JRE) 库的一部分。其本意是鼓励将这些技术作为 Java 标准使用,但是这也带来一个副作用:为了使用这些技术的更新的版本,可能需要更改 JRE 的安装。

示例应用程序下载文件中使用的 build.xml 将所需的 CXF JAR 文件直接复制到服务 WAR 文件。使用 Java SE 5 构建时,这包括 JAXB 和 JAX-WS JARs;当使用 Java SE 6 构建时,构建依赖于 JVM 安装中 JAXB 和 JAX-WS 的版本。使用 Java SE 6 或更高版本时,如果类装载冲突在 JAXB 或 JAX-WS 代码内产生问题,检查一下您正在使用的 CXF 发行版是否有任何 JVM 兼容性说明。

在运行示例代码之前,首先需要下载并在系统上安装当前版本的 Metro(参阅 参考资料)。示例代码经过 2.2.5 版的测试。另外还需要对解压的示例代码根目录中的 build.properties 文件进行编辑,将 cxf-home 属性的值改为 CXF 安装目录的路径。如果要使用不同的系统或端口上的服务器进行测试,那么需要更改 host-namehost-port

要使用所提供的 Ant build.xml 构建示例应用程序,打开一个控制台,进入下载文件的根目录,输入 ant。这将首先调用 CXF wsdl2java 工具(包括在 CXF 中),然后编译客户端和服务器,最后将服务器代码打包为 WAR。接着可以将生成的 cxf-library.war 文件部署到测试服务器,并在控制台输入 ant run 尝试运行示例客户端。示例客户端运行,经过一系列对服务器的请求,打印出每个请求的简要结果。正如在 客户端的使用 中所提到的,构建过程会配置 CXF 日志记录,以避免运行示例客户端时打印配置细节。


CXF 中的 Spring

注意在 清单 2 cxf-servlet.xml 配置文件中 Spring Framework bean 配置的使用。您可能知道,Spring 是一种开源应用程序框架,它包括许多可用来装配应用程序的组件库。Inversion of Control (IoC) 是 Spring Framework 的原始基础,它允许链接和配置 JavaBean 类型的软件组件,在运行时使用 Java 映像访问 bean 对象的属性。

Spring IoC 容器通常为依赖性信息使用 XML 文件,清单 2 中的 cxf-servlet.xml 文件就是这种 Spring 配置的一个示例。<beans> 元素仅是单个 bean 配置的一个包装器。<jaxws:endpoint> 元素就是这样的一个 bean,CXF 通过特定类型的对象(一个 org.apache.cxf.jaxws.EndpointImpl 实例)与其相关联。

除了这个简单示例中使用的选项之外,还可以指定很多其他选项,包括服务的消息流配置。参阅 CXF 文档中的 JAX-WS 配置信息了解完整细节(Frontends/JAX-WS 目录下)。

除了 JAX-WS 注释之外,Spring 还用于 CXF 堆栈的所有配置,包括 CXF 内部消息流的组织。大部分时候,这些配置细节都通过使用直接包含在 CXF JARs 中的 XML 配置得到自动处理,(参阅 清单 1 web.xml 文件中的 contextConfigLocation 参数值,了解如何引用它们),不过可以使用自己的配置文件覆盖或添加到公共流。本系列文章不直接介绍这方面内容;您可以参阅 CXF 文档了解详细信息。


CXF 展望

本文介绍了 CXF Web 服务堆栈使用 JAXB 2.x 数据绑定和对 JAX-WS 2.x 注释进行配置的基础知识。之前的文章中 Axis2 和 Metro 堆栈使用的 JAXB/JAX-WS 代码在 CXF 中也可以使用,只是构建过程有些许修改且使用的部署配置文件有所不同。这种跨堆栈兼容性是使用 JAXB 和 JAX-WS 的主要优点,因为这便于在不同的堆栈之间切换。

CXF 的功能比这个简单示例显示的要多很多,在后面的文章中您将了解到其他一些特性。下一篇文章将着眼于 WS-Security 的使用,您将看到 CXF 实现与 Axis2 和 Metro 的区别。


下载

描述名字大小
本文源代码j-jws12.zip16KB

参考资料

学习

获得产品和技术

  • CXF:下载 CXF。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


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