杰瑞科技汇

Java如何调用CXF Webservice?

目录

  1. 核心概念
    • 什么是 CXF?
    • 调用 WebService 的两种主要方式
  2. 准备工作:环境搭建

    添加 CXF 依赖

    Java如何调用CXF Webservice?-图1
    (图片来源网络,侵删)
  3. 使用 WSDL 文件(推荐)
    • 步骤 1:获取 WSDL 文件
    • 步骤 2:使用 wsdl2java 工具生成客户端代码
    • 步骤 3:编写 Java 代码调用服务
    • 完整示例
  4. 动态调用(无需生成客户端代码)
    • 介绍
    • 步骤 1:创建 JaxWsDynamicClientFactory
    • 步骤 2:创建客户端并调用方法
    • 完整示例
  5. 高级配置
    • 添加 SOAP Header(安全认证等)
    • 处理超时问题
  6. 总结与对比

核心概念

什么是 CXF?

Apache CXF 是一个开源的 Services 框架,它支持构建和开发 WebService,它支持多种协议和数据绑定,包括 SOAP、XML/HTTP、RESTful HTTP 以及 CORBA,对于 Java CXF 提供了与 Spring 框架深度集成的能力。

调用 WebService 的两种主要方式

  1. 静态客户端(代码生成方式)

    • 原理:根据 WebService 的 WSDL (Web Services Description Language) 文件,使用 CXF 提供的工具 (wsdl2java) 自动生成一系列 Java 代码(如 Service、PortType、数据模型类等)。
    • 优点
      • 代码类型安全,编译器可以检查错误。
      • 开发体验好,有代码提示,易于调试。
      • 生成的代码封装了所有细节,调用非常简单。
    • 缺点
      • 需要一个额外的代码生成步骤。
      • WSDL 发生变化,需要重新生成代码。
    • 适用场景:WSDL 接口稳定,项目长期维护,推荐使用此方式。
  2. 动态客户端

    • 原理:不生成任何客户端代码,而是在程序运行时通过 WSDL 动态地解析服务接口,并直接调用。
    • 优点
      • 无需代码生成过程,开发快速。
      • 非常灵活,适合处理 WSDL 可能变化或需要动态调用不同服务的场景(如测试工具)。
    • 缺点
      • 代码不够类型安全,所有参数和返回值都是 Object 类型,需要手动强制类型转换。
      • 调试相对困难。
    • 适用场景:快速原型开发、测试工具、脚本化调用。

准备工作:环境搭建

你需要在你的 Java 项目中添加 CXF 的依赖,这里以 Maven 为例。

Java如何调用CXF Webservice?-图2
(图片来源网络,侵删)

在你的 pom.xml 文件中添加以下依赖:

<dependencies>
    <!-- CXF 核心依赖 -->
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxws</artifactId>
        <version>3.4.5</version> <!-- 建议使用较新版本 -->
    </dependency>
    <!-- CXF 的 Jetty 依赖,如果需要内嵌服务器,但这里客户端不需要 -->
    <!-- <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http-jetty</artifactId>
        <version>3.4.5</version>
    </dependency> -->
    <!-- 日志依赖,CXF 依赖 SLF4J -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-jdk14</artifactId>
        <version>1.7.36</version>
    </dependency>
</dependencies>

方式一:使用 WSDL 文件(推荐)

假设我们要调用一个简单的天气查询服务,它的 WSDL 地址是:http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl

步骤 1:获取 WSDL 文件

直接在浏览器中访问上面的 URL,会看到一个 XML 文件,这就是 WSDL,将它保存到本地,weather.wsdl,或者直接使用网络 URL。

步骤 2:使用 wsdl2java 工具生成客户端代码

CXF 提供了一个命令行工具 wsdl2java,它可以根据 WSDL 文件生成客户端代码。

Java如何调用CXF Webservice?-图3
(图片来源网络,侵删)

下载 CXF 压缩包Apache CXF 官网 下载二进制压缩包(apache-cxf-3.4.5.zip),并解压。

设置环境变量 将解压后的 bin 目录添加到系统的 PATH 环境变量中,这样你就可以在任何地方使用 wsdl2java 命令。

运行命令 打开命令行(CMD 或 PowerShell),切换到你的项目根目录(或者一个专门存放生成代码的目录),然后执行以下命令:

wsdl2java -p com.example.weather.client -d src/main/java -client http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl

命令参数解释:

  • -p com.example.weather.client:指定生成的 Java 包名。
  • -d src/main/java:指定代码生成的目标目录(Maven 项目的标准目录)。
  • -client:生成一个可以独立运行的客户端测试类。
  • WSDL 文件的 URL 或本地路径。

执行成功后,你会在 src/main/java/com/example/weather/client 目录下看到一堆生成的 .java 文件,其中最重要的是:

  • WeatherWebService.java:服务接口。
  • WeatherWebServiceService.java:服务工厂类,用于获取服务接口实例。
  • ArrayOfString.java:数据模型类,用于封装请求和响应数据。

步骤 3:编写 Java 代码调用服务

你可以在你的 Java 代码中像调用本地方法一样调用 WebService 了。

package com.example.weather.client;
public class WeatherServiceClient {
    public static void main(String[] args) {
        // 1. 创建服务工厂实例
        // WeatherWebServiceService 是 wsdl2java 生成的工厂类
        WeatherWebServiceService service = new WeatherWebServiceService();
        // 2. 获取服务端点接口
        // WeatherWebService 是 wsdl2java 生成的服务接口
        WeatherWebService weatherWebService = service.getWeatherWebServiceSoap();
        try {
            // 3. 调用 WebService 方法
            // 假设服务有一个 getWeather 方法,需要城市名作为参数
            // 注意:根据实际生成的接口,方法名和参数可能不同
            // 这里我们调用获取支持的城市列表的方法
            String[] cities = weatherWebService.getSupportCity("重庆");
            // 4. 处理返回结果
            System.out.println("支持的城市列表:");
            if (cities != null) {
                for (String city : cities) {
                    System.out.println(city);
                }
            }
            // 调用获取天气信息的方法
            // 参数格式:城市名, 如 "重庆"
            // 返回的是一个复杂对象,需要根据生成的类来解析
            // ArrayOfString weatherInfo = weatherWebService.getWeather("重庆");
            // System.out.println("\n重庆的天气信息:" + weatherInfo.getString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行这个 main 方法,如果一切正常,你就能看到从 WebService 返回的数据。


方式二:动态调用(无需生成客户端代码)

这种方式不需要 wsdl2java 步骤,适合快速测试。

package com.example.weather.dynamic;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.JaxWsDynamicClientFactory;
import org.apache.cxf.endpoint.Client;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.URL;
public class DynamicWeatherClient {
    public static void main(String[] args) {
        // 1. 创建动态客户端工厂
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        // 2. 创建客户端,指定 WSDL 地址
        // 第二个参数是服务的命名空间,可以在 WSDL 的 <definitions> 标签的 targetNamespace 属性找到
        // 第三个参数是服务名
分享:
扫描分享到社交APP
上一篇
下一篇