杰瑞科技汇

wsdl2java如何生成客户端代码?

准备工作:安装 Apache CXF

你需要确保你的环境中已经安装了 Apache CXF,最简单的方式是下载它的二进制包。

wsdl2java如何生成客户端代码?-图1
(图片来源网络,侵删)
  1. 下载:访问 Apache CXF 官网下载页面
  2. 选择版本:下载最新的稳定版本(apache-cxf-<version>-bin.zip)。
  3. 解压:将下载的 ZIP 文件解压到一个你方便管理的目录,D:\dev\apache-cxf-3.4.0
  4. 配置环境变量 (推荐)
    • 将解压后的 bin 目录(D:\dev\apache-cxf-3.4.0\bin)添加到系统的 PATH 环境变量中。
    • 这样你就可以在任何地方直接使用 wsdl2java 命令,而无需每次都输入完整路径。

配置完成后,打开一个新的命令行窗口,输入以下命令验证是否安装成功:

wsdl2java -version

如果能看到 CXF 的版本信息,说明安装和配置成功。


wsdl2java 常用参数

wsdl2java 提供了丰富的参数来定制生成的代码,以下是一些最常用的参数:

参数 简写 描述 示例
-d 指定生成代码的输出目录 -d D:/generated-code
-client 生成客户端调用代码(默认包含)。 -client
-server 生成服务端实现代码。 -server
-p 指定生成的 Java 包名,非常重要! -p com.example.client
-wsdlLocation 指定 WSDL 文件的最终位置(在代码中作为常量)。 -wsdlLocation http://example.com/service?wsdl
-frontend 指定前端模式,如 jaxws (默认) 或 jaxb -frontend jaxws
-autoNameResolution 自动解决命名冲突问题(重命名同名类)。 -autoNameResolution
-compile 编译生成的 Java 文件。 -compile
-help 显示帮助信息。 -help

生成客户端代码的步骤

我们通过一个具体的例子来演示,假设你有一个 WSDL 文件,http://www.webservicex.net/globalweather.asmx?wsdl (这是一个公共的天气服务 WSDL)。

wsdl2java如何生成客户端代码?-图2
(图片来源网络,侵删)

获取 WSDL 文件

你可以将 WSDL 文件的 URL 下载到本地,或者直接使用 URL,为了稳定性和离线开发,推荐先下载到本地。

假设我们将 WSDL 文件保存为 GlobalWeather.wsdlD:/wsdl_files/ 目录下。

执行 wsdl2java 命令

打开命令行窗口,进入你想要存放生成代码的目录(D:/),然后执行以下命令:

wsdl2java -p com.example.weather.client -d D:/generated-code -client D:/wsdl_files/GlobalWeather.wsdl

命令解析:

  • wsdl2java: 执行工具。
  • -p com.example.weather.client: 将生成的所有 Java 类放在 com.example.weather.client 这个包下。强烈建议使用这个参数,否则类可能会被放在默认的 org.tempuri 等不规范的包中。
  • -d D:/generated-code: 将所有生成的文件(.java, .class 等)输出到 D:/generated-code 目录。
  • -client: 明确告诉工具我们需要生成客户端代码。
  • D:/wsdl_files/GlobalWeather.wsdl: 指定 WSDL 文件的路径。

执行成功后,你会看到命令行工具开始解析 WSDL,并输出类似 [INFO] ... 的日志信息,最后在 D:/generated-code 目录下生成一套完整的 Java 代码。

查看生成的代码结构

生成的代码目录结构通常如下:

D:/generated-code/
└── com/
    └── example/
        └── weather/
            └── client/
                ├── GlobalWeather.java           // 主要的服务接口 (SEI)
                ├── GlobalWeatherService.java    // 服务工厂类,用于获取接口实例
                ├── ObjectFactory.java          // JAXB 相关的工厂类
                ├── package-info.java
                └── ... (其他一些 JAXB 模型类)

使用生成的代码调用 Web Service

生成的代码中最核心的两个类是:

  1. GlobalWeather.java: 这是服务端点接口,里面定义了 WSDL 中描述的所有操作(方法),你需要像调用普通 Java 接口一样调用它。
  2. GlobalWeatherService.java: 这是一个工厂类,提供了一个 getGlobalWeatherPort() 方法,该方法返回一个 GlobalWeather 接口的实例。

下面是一个完整的 Java 调用示例:

package com.example.weather.client;
public class WeatherClient {
    public static void main(String[] args) {
        // 1. 创建服务工厂实例
        GlobalWeatherService service = new GlobalWeatherService();
        // 2. 从工厂获取服务接口的代理对象
        // 方法名 "getGlobalWeatherPort()" 是根据 WSDL 中的 Port 名称生成的
        GlobalWeather port = service.getGlobalWeatherPort();
        // 3. 调用接口方法,传入 WSDL 中定义的参数
        // 注意:根据 WSDL,第一个参数是城市名,第二个是国家名
        String weatherData = port.getWeather("Beijing", "China");
        // 4. 打印返回结果
        System.out.println("北京的天气信息:");
        System.out.println(weatherData);
    }
}

如何运行这个客户端?

  1. GlobalWeather.javaGlobalWeatherService.java 等生成的 .java 文件复制到你的项目中。

  2. 确保你的项目依赖了 Apache CXF 的库,如果你使用 Maven,可以在 pom.xml 中添加:

    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxws</artifactId>
        <version>3.4.0</version> <!-- 使用与你 wsdl2java 工具匹配的版本 -->
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http</artifactId>
        <version>3.4.0</version>
    </dependency>
  3. 编译并运行 WeatherClientmain 方法。


高级用法与最佳实践

使用 -wsdlLocation 参数

在生成的代码中,WSDL 的位置被硬编码为一个常量,WSDL 地址变了,你需要重新生成代码,使用 -wsdlLocation 参数可以更灵活地处理这个问题。

wsdl2java -p com.example.weather.client -d D:/generated-code -wsdlLocation "classpath:GlobalWeather.wsdl" D:/wsdl_files/GlobalWeather.wsdl

这样生成的代码中,WSDL 位置会是 classpath:GlobalWeather.wsdl,你只需要将 GlobalWeather.wsdl 文件放到你项目的 src/main/resources 目录下,运行时会自动从 classpath 中加载。

处理复杂的 WSDL 和命名冲突

对于一些复杂的 WSDL,可能会出现命名冲突(多个不同命名空间下的类型恰好同名)。

  • -autoNameResolution: 这个参数会自动为冲突的类名添加后缀(如 _1, _2),通常能解决大部分问题。
  • 手动重命名: 如果自动重命名不符合你的预期,你可能需要手动编辑 WSDL 文件,或者使用更高级的参数(如 -exsh true)来排除一些 schema,但这需要更深入的理解。

与 Spring 集成

在企业级应用中,通常不会手动创建客户端,而是通过 Spring 框架来管理,CXF 提供了与 Spring 集成的能力。

你可以在 Spring 的配置文件(如 applicationContext.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"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://cxf.apache.org/jaxws
           http://cxf.apache.org/schemas/jaxws.xsd">
    <!-- 定义一个 Web Service 客户端 -->
    <jaxws:client id="globalWeatherClient"
                 serviceClass="com.example.weather.client.GlobalWeather"
                 address="http://www.webservicex.net/globalweather.asmx" />
</beans>

然后在你的 Java 代码中,可以直接通过 Spring 的依赖注入来使用这个客户端:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class WeatherService {
    @Autowired // Spring 会自动注入上面定义的客户端代理
    private GlobalWeather globalWeatherClient;
    public void getWeather() {
        String weatherData = globalWeatherClient.getWeather("Shanghai", "China");
        System.out.println("上海的天气信息: " + weatherData);
    }
}

这种方式更加灵活,便于管理和测试。


使用 wsdl2java 生成 Java 客户端代码是一个非常标准化的流程:

  1. 安装工具:确保 wsdl2javaPATH 中。
  2. 分析 WSDL:了解 WSDL 提供的服务、操作和参数。
  3. 执行命令:使用 -d, -p, -client 等关键参数生成代码。
  4. 使用代码:通过 Service 类获取 Port 接口实例,并调用其方法。
  5. 高级集成:对于复杂项目,考虑使用 -wsdlLocation 和 Spring 框架进行集成。

通过这个流程,你可以快速地将任何符合标准的 Web Service 集成到你的 Java 应用程序中。

分享:
扫描分享到社交APP
上一篇
下一篇