我会从最基础的概念讲起,然后介绍两种主流的实现方式:传统的 JAX-WS 和 现代的 Spring Boot。

目录
-
第一部分:基础概念
- 什么是 WebService?
- WebService 的核心协议:SOAP 和 WSDL
- 调用 WebService 的两种主要模式
-
第二部分:传统方式 - 使用 JAX-WS (Java API for XML-Based Web Services)
- 客户端调用(最常见)
- 准备工作:获取 WSDL 文件
- 使用
wsimport命令生成客户端代码(传统但经典) - 使用 IDE(如 IntelliJ IDEA)自动生成客户端代码(推荐)
- 完整代码示例
- 服务端开发
简单介绍,作为知识补充
- 客户端调用(最常见)
-
第三部分:现代方式 - 使用 Spring Boot
(图片来源网络,侵删)- 客户端调用(推荐)
- 添加依赖
- 使用
WebClient(Spring WebFlux) 进行调用(现代、异步、高效) - 使用
RestTemplate(Spring Web MVC) 进行调用(传统、同步) - 完整代码示例
- 服务端开发
- 添加依赖
- 创建服务端接口和实现
- 发布 WebService
- 访问 WSDL
- 客户端调用(推荐)
-
第四部分:总结与对比
第一部分:基础概念
什么是 WebService?
WebService 是一种跨编程语言、跨操作系统的远程调用技术,它允许不同的应用程序通过网络进行交互,它使用开放标准(如 XML, HTTP, SOAP)进行通信,实现了真正的平台独立性。
WebService 的核心协议:SOAP 和 WSDL
-
WSDL (Web Services Description Language):WebService 的“说明书”,它是一个 XML 文件,描述了 WebService 的所有信息,包括:
- 服务地址 (Endpoint/URL)
- 可用方法 (Operations)
- 每个方法的参数 (Input/Output Messages)
- 参数和返回值的类型 (Data Types)
- 通信协议 (通常是基于 HTTP 的 SOAP) 调用任何 WebService 的第一步,就是获取它的 WSDL 文件。
-
SOAP (Simple Object Access Protocol):WebService 的“沟通语言”,它是一种基于 XML 的协议,用于在 Web 上交换结构化的信息,SOAP 消息通常是一个 XML 文档,包含了请求或响应的数据,它被包装在 HTTP 请求中发送。
(图片来源网络,侵删)
调用 WebService 的两种主要模式
- 契约优先:这是最标准、最健壮的方式,你首先拥有一个由服务提供方定义好的 WSDL 文件,客户端基于这个 WSDL 生成调用代码,服务端也基于它来开发实现,这确保了客户端和服务端的“契约”一致。
- 代码优先:开发者先在 Java 代码中定义接口和类,然后由框架(如 JAX-WS)自动生成 WSDL 文件,这种方式在开发内部服务时比较方便,但在跨组织协作时不如契约优先清晰。
第二部分:传统方式 - 使用 JAX-WS
JAX-WS 是 Java 标准官方 API,用于创建和调用 WebService,它内置在 JDK 中,无需额外安装框架。
客户端调用
假设我们要调用一个公开的天气查询 WebService,其 WSDL 地址为:http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
使用 wsimport 命令生成客户端代码
-
打开命令行,执行以下命令,这会根据 WSDL 生成一堆 Java 源文件和类文件。
# -p: 指定生成的包名 # -keep: 保留生成的源文件 # -d: 指定 class 文件输出目录 wsimport -p com.example.weather.client -keep http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
执行后,你会得到一堆
.java和.class文件,这些就是客户端的“代理代码”。 -
将生成的代码导入项目:将生成的
com文件夹复制到你的 Java 项目的src目录下。 -
编写调用代码:
package com.example.weather.client; public class WeatherClient { public static void main(String[] args) { // 1. 创建服务视图 (Service) // WeatherWebService 是 wsimport 生成的类,它代表了整个 WebService WeatherWebService service = new WeatherWebService(); // 2. 获取服务端点 (Port) // WeatherWebServiceSoap 是 wsimport 生成的接口,它代表了具体的端口(即可调用的方法集合) WeatherWebServiceSoap port = service.getWeatherWebServiceSoap(); // 3. 调用方法并传递参数 // getWeather 是 WSDL 中定义的一个方法 String[] result = port.getWeather("北京", "null"); // 4. 处理结果 if (result != null) { for (String s : result) { System.out.println(s); } } else { System.out.println("获取天气失败"); } } }
使用 IDE(如 IntelliJ IDEA)自动生成(推荐)
这个过程和 wsimport 命令完全一样,只是图形化操作,更简单。
- 在 IDEA 中,右键项目 ->
New->Web Service Client。 - 在弹出的窗口中,输入 WSDL 地址,点击
OK。 - IDE 会自动完成下载、解析、生成代码的全过程,并将生成的代码放在你指定的包下。
- 之后,你只需要像上面一样,编写调用代码即可。
第三部分:现代方式 - 使用 Spring Boot
Spring Boot 是目前 Java 开发的主流框架,它简化了 WebService 的开发,并且提供了更现代的客户端调用方式。
客户端调用
对于现代 WebService,很多也提供了 RESTful 风格的 API,但如果是传统的 SOAP WebService,Spring Boot 也能很好地支持,这里我们重点介绍调用 RESTful 风格的 WebService,因为它更常见。
添加依赖
在你的 pom.xml 中添加 WebClient 的依赖(Spring WebFlux)。
<dependencies>
<!-- Spring Boot Starter Web (包含 Web, Tomcat, etc.) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 如果需要调用 SOAP WebService,可以添加这个 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
</dependencies>
使用 WebClient 调用(推荐)
WebClient 是 Spring 5 引入的响应式、非阻塞的 HTTP 客户端,性能更高,是未来的趋势。
假设我们要调用一个公开的 JSON API,https://jsonplaceholder.typicode.com/posts/1
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@SpringBootApplication
public class WebServiceClientApplication {
public static void main(String[] args) {
SpringApplication.run(WebServiceClientApplication.class, args);
}
// 可以将 WebClient 定义为 Bean,方便复用
public WebClient webClient() {
return WebClient.create();
}
}
// 在另一个类或主类的内部进行调用
class PostService {
private final WebClient webClient;
public PostService(WebClient webClient) {
this.webClient = webClient;
}
public void fetchPost() {
// 定义请求的 URL
String url = "https://jsonplaceholder.typicode.com/posts/1";
// 发起 GET 请求,并期望返回一个 JSON 字符串
Mono<String> postMono = webClient.get()
.uri(url)
.retrieve() // 执行请求并获取响应
.bodyToMono(String.class); // 将响应体映射为 String
// 订阅并处理结果
postMono.subscribe(postJson -> {
System.out.println("获取到的 Post JSON 数据:");
System.out.println(postJson);
});
}
}
代码解释:
WebClient.create()创建一个WebClient实例。get()指定 HTTP 方法为 GET。uri(url)设置请求的 URL。retrieve()发出请求并获取响应,它会自动处理状态码(如 200, 404, 500)。bodyToMono(String.class)将响应体(body)异步地映射成一个Mono<String>。Mono是 Reactor 中的一个响应式类型,代表 0 到 1 个元素。subscribe()是一个触发点,当数据到达时,会执行传入的 Lambda 表达式。
使用 RestTemplate 调用(传统同步)
RestTemplate 是 Spring 传统的同步 HTTP 客户端,虽然官方不推荐在新项目中作为首选,但仍在广泛使用。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class WebServiceClientApplication {
public static void main(String[] args) {
SpringApplication.run(WebServiceClientApplication.class, args);
RestTemplate restTemplate = new RestTemplate();
String url = "https://jsonplaceholder.typicode.com/posts/1";
String postJson = restTemplate.getForObject(url, String.class);
System.out.println("获取到的 Post JSON 数据:");
System.out.println(postJson);
}
}
RestTemplate 的代码更简洁,但它是阻塞式的,每个请求都会占用一个线程。
第四部分:总结与对比
| 特性 | JAX-WS (传统) | Spring Boot (现代) |
|---|---|---|
| 主要用途 | 调用或开发传统的 SOAP WebService。 | 调用或开发现代的 RESTful API,同时也能支持 SOAP。 |
| 客户端调用方式 | 代码生成模式:必须先通过 WSDL 生成客户端代理类,然后像调用本地方法一样调用。 | HTTP 客户端模式:直接通过 HTTP 请求(GET, POST, PUT, DELETE)与 RESTful 服务交互,无需生成代理代码。 |
| 核心组件 | wsimport 命令,生成的 Service 和 Port 接口。 |
WebClient (异步非阻塞), RestTemplate (同步阻塞)。 |
| 易用性 | 对于 SOAP 服务,流程固定但略显繁琐,对于 RESTful 服务支持不佳。 | 非常简单,直接构造 HTTP 请求,处理 JSON/XML 响应,符合现代开发习惯。 |
| 性能 | 同步阻塞,性能一般。 | WebClient 是异步非阻塞的,在高并发场景下性能优异。RestTemplate 是同步阻塞的。 |
| 学习曲线 | 需要理解 SOAP, WSDL, XML 等概念。 | 主要理解 HTTP 协议和 Spring 框架即可。 |
| 推荐场景 | 必须调用遗留的 SOAP 系统。 项目要求使用标准 Java API。 |
所有新项目,特别是微服务架构。 调用现代的 RESTful API。 |
- 如果你的任务是调用一个传统的、基于 SOAP 协议的 WebService,并且你拿到了 WSDL 文件,那么使用 JAX-WS 是最标准、最可靠的选择。
- 如果你的任务是调用现代的、基于 RESTful 风格的 API,或者你想构建一个现代化的服务,那么使用 Spring Boot 中的
WebClient或RestTemplate是不二之选,尤其是WebClient,代表了未来的方向。
