使用 JAX-WS (wsimport) - 最标准、最推荐的方式
这是 Java 官方标准的方式,通过命令行工具 wsimport 生成客户端代码,然后像调用普通 Java 对象一样调用服务。

适用场景
- .NET WebService 提供了标准的 WSDL 文件。
- 你希望获得类型安全的、强类型的客户端代码。
- 这是企业级应用中最稳定、最常用的方法。
详细步骤
假设我们要调用一个 .NET 提供的 WebService,其地址为:http://www.example.com/Service.asmx?wsdl
步骤 1:获取 WSDL 文件
确保你能访问到 WebService 的 WSDL 地址,通常在 .NET 的 ASMX 服务后面加上 ?wsdl 即可,
http://www.example.com/YourService.asmx?wsdl
步骤 2:使用 wsimport 生成客户端代码

打开你的命令行工具(如 CMD 或 PowerShell),切换到你希望生成代码的目录(D:\java_client),然后执行以下命令:
wsimport -p com.example.client -keep http://www.example.com/YourService.asmx?wsdl
命令参数说明:
-p com.example.client: 指定生成的 Java 包名。-keep: 生成源代码文件,方便查看和调试。-s .: (可选) 指定源代码生成的目录,默认是当前目录。-s .表示在当前目录下生成src文件夹。-d .: (可选) 指定编译后的.class文件存放的目录,默认是当前目录下的build文件夹。http://.../wsdl: WebService 的 WSDL 地址。
执行成功后,你会在指定包下看到一堆生成的 Java 文件,主要包括:
XXX.java: 服务接口,定义了所有可用的 WebService 方法。XXXService.java: 服务工厂类,用于获取XXX接口的实例。XXXSoap.java: 具体的服务端点接口,通常你不需要直接使用它。- 以及一堆
XXX_Type,XXXResponse等数据类型类。
步骤 3:在 Java 项目中调用生成的代码

你可以在你的 Java 项目(例如一个 Maven 项目)中使用这些生成的类了。
-
将生成的代码整合到项目中 你可以将
wsimport生成的.java文件手动添加到你的项目中,或者更好的方式是,使用 Maven 或 Gradle 的插件来自动完成这个过程。Maven 方式 (推荐): 在你的
pom.xml中添加jaxws-maven-plugin插件,它会自动执行wsimport并将生成的代码和依赖添加到项目中。<build> <plugins> <plugin> <groupId>org.jvnet.jax-ws-commons</groupId> <artifactId>jaxws-maven-plugin</artifactId> <version>2.3</version> <executions> <execution> <id>generate-service-client</id> <phase>generate-sources</phase> <goals> <goal>wsimport</goal> </goals> <configuration> <wsdlLocation>http://www.example.com/YourService.asmx?wsdl</wsdlLocation> <sourceDestDir>${project.build.directory}/generated-sources/jaxws</sourceDestDir> <packageName>com.example.client</packageName> </configuration> </execution> </executions> </plugin> </plugins> </build>运行
mvn generate-sources后,生成的代码会出现在target/generated-sources/jaxws目录下,你需要在 IDE 中将此目录标记为源文件夹。 -
编写调用代码
假设生成的服务接口是
YourService,服务工厂类是YourServiceService。package com.example.client; import com.example.client.YourService; // 生成的服务接口 import com.example.client.YourServiceService; // 生成的服务工厂类 import java.net.URL; public class NetWebServiceClient { public static void main(String[] args) { try { // 1. 创建服务工厂实例 // 参数是 wsdl 文件的地址 YourServiceService service = new YourServiceService(new URL("http://www.example.com/YourService.asmx?wsdl")); // 2. 从工厂获取服务端点接口 YourService port = service.getYourServiceSoap(); // 注意这里的后缀通常是 Soap 或 Soap12 // 3. 调用 WebService 方法 // 假设服务有一个名为 HelloWorld 的方法,接收一个字符串参数 String result = port.helloWorld("Java Client"); // 4. 处理结果 System.out.println("调用WebService返回的结果: " + result); } catch (Exception e) { e.printStackTrace(); } } }
常见问题与解决方案
-
问题:
@WebServiceClient注解中找不到wsdlLocation的 URL- 原因:Maven 插件配置的
wsdlLocation是在编译时使用的,如果你手动复制代码,需要确保生成的类中的 URL 是正确的。 - 解决:检查生成的
YourServiceService类,确保其@WebServiceClient注解中的wsdlLocation属性指向了正确的地址。
- 原因:Maven 插件配置的
-
问题:HTTPS 证书错误
- 原因:.NET 服务是 HTTPS 的,并且使用了自签名证书,Java 默认不信任。
- 解决:你需要创建一个自定义的
HttpsURLConnection信任管理器来绕过证书验证,这通常涉及到实现X509TrustManager接口并配置SSLContext。
使用 Apache CXF - 更灵活、功能更强大的框架
Apache CXF 是一个开源的 Services 框架,它支持 JAX-WS 和 JAX-RS (RESTful) 等多种标准,CXF 提供了比标准 JAX-WS 更多的功能和更灵活的配置方式。
适用场景
- 你需要更高级的功能,如拦截器、数据绑定(如 JSON)等。
- 你希望使用 Spring 来管理和配置 WebService 客户端。
- 你想避免手动运行
wsimport,让 CXF 在运行时动态处理。
详细步骤
步骤 1:添加 CXF 依赖
在你的 Maven 项目的 pom.xml 中添加 CXF 的核心依赖。
<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>
</dependencies>
步骤 2:使用 CXF 的 wsdl2java 工具生成客户端代码
CXF 提供了自己的 wsdl2java 工具,功能和 wsimport 类似,但有时能处理一些更复杂的情况。
# 需要先将 cxf-tools 的 bin 目录添加到 PATH 环境变量 # 或者直接执行脚本 wsdl2java -p com.example.cxf.client -keep http://www.example.com/YourService.asmx?wsdl
生成的代码和使用 wsimport 非常相似,你可以直接在项目中使用。
步骤 3:编写 CXF 客户端代码
CXF 的调用方式与标准 JAX-WS 几乎完全一样,因为 CXF 本身就是 JAX-WS 的一个实现。
package com.example.cxf.client;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import com.example.cxf.client.YourService; // 生成的服务接口
public class CxfClient {
public static void main(String[] args) {
// 1. 创建 JaxWsProxyFactoryBean 实例
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
// 2. 设置服务接口
factory.setServiceClass(YourService.class);
// 3. 设置 WebService 的地址
factory.setAddress(" 