什么是 WebService?
WebService 是一种基于 Web 的、跨平台的、跨语言的远程服务调用技术,它使用 XML 来传输数据,并通过 HTTP 协议进行通信,最核心的标准是 SOAP (Simple Object Access Protocol) 和 WSDL (Web Services Description Language)。

- WSDL (Web Services Description Language): 一个 XML 文件,它描述了 WebService 的所有信息,比如服务地址、可用的方法、每个方法的参数类型和返回值类型等,调用方通过 WSDL 文件来了解如何调用服务。
- SOAP (Simple Object Access Protocol): 一种协议,规定了消息的格式,SOAP 消息是一个 XML 文档,包含了调用的方法名、参数和返回结果。
调用 WebService 的几种主要方式
JDK 自带的 javax.xml.ws (原生 API) - 最传统
这是 Java 标准库自带的方式,无需引入第三方依赖,适合简单的调用,核心是使用 wsimport 工具生成客户端代码。
步骤:
-
使用
wsimport生成客户端代码wsimport是 JDK 自带的命令行工具,它会根据 WSDL 文件生成一系列 Java 类(如Service、PortType、Data Type等)。- 打开命令行,执行以下命令:
# -p: 指定生成的包名 # -d: 指定生成代码的存放目录 # -keep: 生成后保留 .java 文件,方便查看 wsimport -p com.example.client -d ./src/main/java -keep http://www.example.com/service?wsdl
- 执行成功后,你的项目目录下就会多出
com/example/client包,里面包含了调用服务所需的所有类。
-
在 Java 代码中调用
(图片来源网络,侵删)- 生成的代码中通常会有一个
XXXService类(MyWebServiceService),这是服务的入口。 - 通过这个
Service类可以获取到XXX端口(MyWebService),这个端口对象就是你实际用来调用的服务代理。
- 生成的代码中通常会有一个
示例代码:
假设 wsimport 生成了 MyWebServiceService 和 MyWebService 这两个类。
import com.example.client.MyWebService; // 生成的服务接口
import com.example.client.MyWebServiceService; // 生成的服务工厂类
public class JdkWebServiceClient {
public static void main(String[] args) {
try {
// 1. 创建服务工厂对象
// 参数是 wsdl 文件中的 service name
MyWebServiceService service = new MyWebServiceService();
// 2. 从工厂获取服务端口 (Port)
// 参数是 wsdl 文件中的 port name
MyWebService webService = service.getMyWebServicePort();
// 3. 调用 WebService 的方法
// 假设 WSDL 中定义了一个名为 sayHello 的方法,参数为 String name
String result = webService.sayHello("Java Client");
// 4. 处理结果
System.out.println("WebService 返回结果: " + result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
优点:
- 无需额外依赖,JDK 自带。
- 官方支持,稳定可靠。
缺点:

- 需要预先通过
wsimport生成代码,开发流程稍显繁琐。 - 生成的代码可能很多,增加项目体积。
- 处理复杂的数据类型(如 Map、List)时可能不太方便。
Apache CXF - 业界主流框架
Apache CXF 是一个非常强大和流行的开源框架,用于构建和开发 WebService,它既支持作为服务器端框架,也支持作为客户端框架,CXF 可以使用原生 API 方式,也可以使用更简单的动态客户端。
使用原生 API (类似 JDK 方式)
这种方式和 JDK 的 javax.xml.ws 类似,CXF 也提供了自己的注解和 API,但如果你习惯 JDK 的方式,CXF 完全兼容。
动态客户端 (更简单,推荐)
动态客户端不需要预先生成任何代码,而是直接在运行时通过 WSDL 地址来调用服务,非常灵活。
步骤:
-
添加 Maven 依赖
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>3.4.5</version> <!-- 使用合适的版本 --> </dependency>注意:即使你不用 Spring Boot,也可以使用
cxf-rt-frontend-jaxws和cxf-rt-transports-http等核心依赖。 -
编写 Java 代码调用
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
public class CxfDynamicClient {
public static void main(String[] args) {
// 1. 创建 JaxWsProxyFactoryBean 实例
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
// 2. 设置 WebService 的 WSDL 地址
factory.setAddress("http://www.example.com/service?wsdl");
// 3. 设置服务接口 (这个接口需要你根据 WSDL 手动定义,或者用 CXF 的 wsdl2java 工具生成)
// 为了演示,我们假设有一个接口 MyWebService
factory.setServiceClass(MyWebService.class);
// 4. 创建服务代理对象
MyWebService webService = factory.create(MyWebService.class);
// 5. 调用方法
String result = webService.sayHello("CXF Dynamic Client");
// 6. 处理结果
System.out.println("WebService 返回结果: " + result);
}
}
优点:
- 功能强大,支持 SOAP 1.1/1.2, RESTful 等多种协议。
- 动态客户端非常灵活,无需生成代码。
- 社区活跃,文档丰富。
- 与 Spring/Spring Boot 集成非常方便。
缺点:
- 引入了第三方框架,会增加项目依赖。
Spring Boot 整合 CXF - 现代企业级首选
这是目前企业开发中最常见的方式,它将 CXF 客户端无缝集成到 Spring Boot 应用中,可以方便地使用 Spring 的特性(如依赖注入)。
步骤:
-
添加 Maven 依赖 (同 CXF 方式)
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>3.4.5</version> </dependency> -
定义服务接口 (根据 WSDL 手动创建或生成)
// com/example/service/MyWebService.java import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; @WebService(name = "MyWebService", targetNamespace = "http://www.example.com/") public interface MyWebService { @WebMethod String sayHello(@WebParam(name = "name") String name); } -
创建客户端配置类
使用
@Bean将 CXF 的客户端工厂声明为 Spring Bean。// com/example/config/WebServiceClientConfig.java import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class WebServiceClientConfig { @Bean public MyWebService myWebServiceClient() { JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.setAddress("http://www.example.com/service?wsdl"); factory.setServiceClass(MyWebService.class); return (MyWebService) factory.create(); } } -
在 Service 中注入并调用
// com/example/service/MyAppService.java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MyAppService { @Autowired private MyWebService myWebService; // 注入客户端 Bean public void callWebService() { String result = myWebService.sayHello("Spring Boot Client"); System.out.println("WebService 返回结果: " + result); } }
优点:
- 集成度高,符合 Spring Boot 的开发习惯。
- 客户端管理清晰,通过 Spring IoC 容器管理。
- 代码结构清晰,易于维护和测试。
Spring Boot 整合 WebClient - 调用 RESTful WebService
如果你的 WebService 是 RESTful 风格(基于 HTTP/HTTPS,通常返回 JSON/XML,而不是 SOAP),那么使用 Spring 5+ 引入的 WebClient 是最佳选择,它是一个响应式的、非阻塞的 HTTP 客户端。
步骤:
-
添加 Maven 依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> -
编写调用代码
假设有一个 RESTful 服务,地址是
http://www.example.com/api/users/123,返回 JSON 数据。import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; @Service public class RestWebServiceClient { private final WebClient webClient; // 通过构造器注入 WebClient.Builder public RestWebServiceClient(WebClient.Builder webClientBuilder) { this.webClient = webClientBuilder.baseUrl("http://www.example.com").build(); } public String getUserInfo(String userId) { // 定义返回的数据结构 class User { public String id; public String name; public String email; } // 发起 GET 请求并异步获取响应 Mono<User> userMono = this.webClient.get() .uri("/api/users/{id}", userId) .retrieve() .bodyToMono(User.class); // 阻塞并获取结果 (在同步方法中) User user = userMono.block(); return "User: " + user.name + ", Email: " + user.email; } }
优点:
- 现代、异步、高性能。
- 专门用于调用 RESTful API,非常直观。
- 是 Spring 生态系统的标准 HTTP 客户端。
缺点:
- 只适用于 RESTful 服务,不适用于传统的 SOAP WebService。
总结与对比
| 方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
JDK javax.xml.ws |
简单、快速调用,不想引入第三方库。 | 无需依赖,JDK 自带。 | 需要预生成代码,处理复杂数据麻烦。 |
| Apache CXF (动态) | 需要灵活调用,不想维护生成的代码。 | 无需生成代码,功能强大,支持多种协议。 | 引入框架依赖,需要手动定义接口。 |
| Spring Boot + CXF | 企业级 Spring Boot 项目,需要整合 Spring 生态。 | 集成度高,代码清晰,易于管理。 | 引入框架依赖,配置稍显复杂。 |
Spring Boot + WebClient |
调用 RESTful 风格的 WebService 或 API。 | 现代、异步、高性能,与 Spring 生态完美结合。 | 不适用于 SOAP。 |
如何选择?
-
如果你的服务是 SOAP 协议:
- 小型项目/快速验证:使用 JDK 原生 API。
- 需要灵活性:使用 CXF 动态客户端。
- 企业级 Spring Boot 项目:使用 Spring Boot + CXF,这是最佳实践。
-
如果你的服务是 RESTful 协议:
- 直接使用 Spring Boot +
WebClient,这是目前最现代和推荐的方式。
- 直接使用 Spring Boot +
希望这个详细的指南能帮助你理解如何在 Java 中调用 WebService!
