杰瑞科技汇

Java如何通过WSDL生成客户端代码?

下面我将为你详细介绍几种主流的方法,从最经典到最现代,并提供详细的步骤和示例。

Java如何通过WSDL生成客户端代码?-图1
(图片来源网络,侵删)

核心概念

WSDL 文件是一个 XML 文档,它描述了一个 Web Service 的功能、接口、消息格式、通信协议和地址等信息,Java 客户端代码生成的过程,就是读取这个 WSDL 文件,并根据其中的描述,自动创建一系列 Java 类(如 Service、Port、Stub 等),使得 Java 程序可以像调用本地方法一样方便地调用远程的 Web Service。


使用 JDK 自带的 wsimport 工具 (最经典、最常用)

wsimport 是 Java 开发工具包 (JDK) 自带的一个命令行工具,它基于 JAX-WS (Java API for XML Web Services) 规范,这是官方推荐的标准方法。

准备工作

  • 安装 JDK: 确保你的系统已经安装了 JDK,JAVA_HOME 环境变量配置正确。
  • 获取 WSDL 文件: 你需要目标 Web Service 的 WSDL 文件地址,通常是一个 URL,http://www.example.com/service?wsdl

基本使用步骤

假设我们有一个 WSDL 文件地址:http://localhost:8080/MyService?wsdl

步骤 1: 打开命令行工具

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

打开你的终端 (Windows 的 CMD 或 PowerShell, macOS/Linux 的 Terminal)。

步骤 2: 执行 wsimport 命令

导航到你希望生成代码的目录,然后执行以下命令:

wsimport -keep -p com.example.client http://localhost:8080/MyService?wsdl

命令参数解释:

Java如何通过WSDL生成客户端代码?-图3
(图片来源网络,侵删)
  • wsimport: JDK 提供的工具。
  • -keep: (非常重要) 生成代码后,保留由 WSDL 文件生成的 .java 源文件,如果不加此参数,只会生成 .class 文件,不利于调试和学习。
  • -p com.example.client: 指定生成 Java 类的包名,这有助于组织代码结构。
  • -d .: 指定编译后的 .class 文件输出的目录。 表示当前目录,如果不指定,默认会在 JDK 的某个临时目录下生成。
  • -Xnocompile: (可选) 只生成 .java 文件,不进行编译,当你只想看源码或者用 Maven/Gradle 管理项目时很有用。
  • -extension: (可选) 启用扩展,以支持更多 WSDL 1.1 规范的特性。
  • http://.../MyService?wsdl: 你的 WSDL 文件的 URL 或本地文件路径。

步骤 3: 查看生成的文件

执行成功后,你会在当前目录(或你指定的 -d 目录)下看到一个 com/example/client 文件夹,里面包含了生成的 Java 文件,通常包括:

  • MyService.java: 一个服务接口,用于获取服务端点。
  • MyServiceService.java: 一个服务工厂类,用于创建 MyService 实例。
  • MyServicePort.java (或类似名称): 这是最重要的客户端接口,它定义了你在 WSDL 中声明的所有操作(方法)。
  • 以及一堆用于处理 SOAP 消息的 ObjectFactory.javaXXX.java (用于数据类型) 等。

步骤 4: 在 Java 项目中使用生成的代码

  1. 编译: 将生成的 .java 文件编译成 .class 文件。

    javac com/example/client/*.java
  2. 编写客户端代码: 创建一个新的 Java 类来调用 Web Service。

    import com.example.client.MyService;
    import com.example.client.MyServiceService;
    import com.example.client.MyServicePort; // 注意:这里的 Port 名称可能不同,根据生成的文件名调整
    public class MyServiceClient {
        public static void main(String[] args) {
            // 1. 创建服务工厂实例
            MyServiceService service = new MyServiceService();
            // 2. 通过工厂获取服务端口(即客户端接口)
            // "MyServicePort" 是 WSDL 中定义的端口名称,需要查看生成的 MyServiceService.java 文件确认
            MyServicePort port = service.getMyServicePort();
            // 3. 调用服务端定义的方法
            // 假设 WSDL 中定义了一个名为 "sayHello" 的方法,接收一个 String 参数
            String response = port.sayHello("World");
            // 4. 打印结果
            System.out.println("Response from Web Service: " + response);
        }
    }
  3. 运行: 编译并运行你的客户端代码。

    # 确保当前目录有编译后的 .class 文件
    java MyServiceClient

使用 Maven 或 Gradle (推荐用于现代项目)

在现代 Java 项目中,我们通常使用 Maven 或 Gradle 来管理依赖和构建过程。wsimport 也可以作为 Maven 插件或 Gradle 插件来使用,这样可以更好地集成到项目生命周期中。

这里以 Maven 为例。

pom.xml 中配置插件

在你的 Maven 项目的 pom.xml 文件中,添加 jaxws-maven-plugin 插件配置。

<build>
    <plugins>
        <plugin>
            <groupId>org.jvnet.jax-ws-commons</groupId>
            <artifactId>jaxws-maven-plugin</artifactId>
            <version>2.3</version> <!-- 使用较新版本 -->
            <executions>
                <execution>
                    <id>generate-sources</id>
                    <phase>generate-sources</phase> <!-- 在 generate-sources 阶段执行 -->
                    <goals>
                        <goal>wsimport</goal>
                    </goals>
                    <configuration>
                        <wsdlUrls>
                            <!-- WSDL 文件的 URL 或本地路径 -->
                            <wsdlUrl>http://localhost:8080/MyService?wsdl</wsdlUrl>
                        </wsdlUrls>
                        <sourceDestDir>${project.build.directory}/generated-sources/jaxws</sourceDestDir>
                        <!-- 生成的代码放在哪个包下 -->
                        <packageName>com.example.client</packageName>
                        <!-- 是否保留生成的源文件 -->
                        <keep>true</keep>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

执行 Maven 命令

在项目根目录下打开命令行,执行:

mvn clean generate-sources

Maven 会在 target/generated-sources/jaxws 目录下生成与 wsimport 相同的 Java 代码。

更新项目源码

在 IDE (如 IntelliJ IDEA 或 Eclipse) 中,右键点击项目 -> "Maven" -> "Reload Project",IDE 会自动识别 target/generated-sources/jaxws 目录为源代码目录,你就可以像使用普通代码一样使用这些生成的类了。

编写客户端代码

客户端代码的编写方式与 方法一 中的第 4 步完全相同。


使用 IDE (如 IntelliJ IDEA 或 Eclipse) 的图形化工具

许多 IDE 提供了图形化的界面来执行 wsimport,更加直观和方便。

以 IntelliJ IDEA 为例:

  1. 打开 "Project Structure": File -> Project Structure...
  2. 添加 Web Service 客户端:
    • 在左侧选择 Modules
    • 选择你的模块,然后点击右侧的 Dependencies 选项卡。
    • 点击 号,选择 Web Services Client
  3. 配置 WSDL URL:
    • 在弹出的对话框中,输入你的 WSDL URL (http://...)。
    • 你可以设置生成代码的包名、输出目录等。
    • 点击 OK
  4. 生成代码: IDEA 会自动运行 wsimport 并将生成的代码添加到你的项目中,你可以在 External Libraries 或项目源码目录中找到它们。

常见问题与解决方案

  1. 问题: Error: Could not find or load main class com.sun.tools.internal.ws.wscompile.WsimportTool

    • 原因: JAVA_HOME 没有正确设置,或者 PATH 中没有包含 JDK 的 bin 目录。
    • 解决: 检查并配置好 JAVA_HOMEPATH 环境变量,确保你使用的是 JDK 而不是 JRE。
  2. 问题: javax.xml.ws.WebServiceException: Failed to access the WSDL at: ...

    • 原因: WSDL 地址无法访问(网络问题、服务未启动、地址错误)。
    • 解决: 检查 WSDL URL 是否正确,确保网络连通,且 Web Service 正在运行。
  3. 问题: 生成的类名或方法名不符合预期。

    • 原因: WSDL 文件中的命名空间、端口名称等定义影响了代码生成。
    • 解决: 查看 WSDL 文件,了解其结构,使用 -p 参数可以控制包名,但有时需要更复杂的配置(如 Maven 插件中的额外参数)来精确控制生成的类名。
  4. 问题: Web Service 使用了 WS-Security 等复杂标准。

    • 原因: wsimport 生成的标准客户端可能无法直接处理这些扩展标准。
    • 解决: 你可能需要使用 Apache CXF 或 Spring-WS 等更强大的框架,它们提供了更灵活的方式来处理 WS-Security、SOAP 头部等复杂场景。
方法 优点 缺点 适用场景
wsimport (命令行) - JDK 自带,无需额外安装
- 灵活,可脚本化
- 需要手动处理文件和编译
- 不利于项目集成
快速原型验证、简单的客户端脚本、非 Maven/Gradle 项目
Maven/Gradle 插件 - 与项目构建生命周期无缝集成
- 自动管理依赖和输出目录
- 团队协作友好
- 需要配置 pom.xmlbuild.gradle 强烈推荐,所有现代 Java Web Service 客户端项目。
IDE 图形化工具 - 直观,无需记命令
- IDE 自动集成,方便调试
- IDE 特定,可移植性差 日常开发,喜欢使用 GUI 的开发者。

对于新项目,强烈推荐使用 Maven 或 Gradle 插件 的方式,因为它最规范、最易于维护,对于快速测试或简单脚本,使用 wsimport 命令行工具则非常高效。

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