目录
- 核心概念:SOAP vs. REST
- 第一部分:调用 SOAP WebService
- 什么是 SOAP WebService?
- 准备工作:获取 WSDL 文件
- 使用 JDK 自带的
wsimport工具(最经典) - 使用 Apache CXF 框架(更灵活、功能更强)
- 使用 Spring Boot + CXF(现代企业级应用)
- 第二部分:调用 RESTful WebService (以 JSON 为例)
- 什么是 RESTful WebService?
- 准备工作:了解 API 的 URL、HTTP 方法、请求/响应格式
- 使用
java.net.HttpURLConnection(原生,无需依赖) - 使用 Apache HttpClient(功能更强大的 HTTP 客户端)
- 使用 Spring Boot
RestTemplate(经典、简洁) - 使用 Spring Boot
WebClient(现代、异步、非阻塞)
- 总结与对比
核心概念:SOAP vs. REST
在开始之前,必须明确你要调用的是哪种类型的 WebService,因为它们的调用方式完全不同。

| 特性 | SOAP (Simple Object Access Protocol) | REST (Representational State Transfer) |
|---|---|---|
| 协议 | 严格基于 XML,是一个协议。 | 一种架构风格,通常基于 HTTP/HTTPS。 |
| 数据格式 | 强制使用 XML。 | 灵活,常用 JSON, XML, HTML, Text。 |
| 标准 | 有严格的规范(WSDL, SOAP, UDDI)。 | 没有官方标准,遵循一组约束(如无状态、统一接口)。 |
| 操作 | 通过 POST 请求,在 SOAP Body 中发送指令。 |
使用标准的 HTTP 方法 (GET, POST, PUT, DELETE)。 |
| 描述文件 | WSDL (Web Services Description Language),定义了服务的所有接口、方法、参数和返回值。 | 通常使用 OpenAPI/Swagger 文档来描述 API。 |
| 适用场景 | 企业级应用、金融、电信等对安全性、事务性要求高的场景。 | 移动应用、Web 前后端分离、微服务架构等。 |
第一部分:调用 SOAP WebService
SOAP WebService 的调用核心是利用 WSDL 文件,WSDL 文件就像是服务的“说明书”,描述了服务提供了哪些方法、每个方法需要什么参数、返回什么类型。
准备工作:获取 WSDL 文件
假设我们要调用一个天气预报服务,它的 WSDL 地址是:
http://ws.webxml.com.cn/WebServices/WeatherWS?wsdl
使用 JDK 自带的 wsimport 工具(最经典)
这是最传统、最直接的方法,无需额外引入第三方库。
步骤 1:根据 WSDL 生成 Java 客户端代码

打开你的命令行(CMD 或 PowerShell),执行以下命令:
# -keep: 生成源代码文件 # -d: 指定编译后的 .class 文件存放目录 # -p: 指定生成的包名 wsimport -keep -d D:\temp -p com.example.weather.client http://ws.webxml.com.cn/WebServices/WeatherWS?wsdl
执行后,会在 D:\temp\com\example\weather\client 目录下生成一堆 .java 和 .class 文件,这些就是客户端代理类。
步骤 2:在项目中使用生成的代码
- 将生成的
.class文件(或整个包)复制到你的 Java 项目的classes目录下,或者打包成 JAR 文件引入项目。 - 编写 Java 代码调用服务。
import com.example.weather.client.WeatherWS;
import com.example.weather.client.WeatherWSSoap;
public class SoapClientTest {
public static void main(String[] args) {
// 1. 创建服务视图对象 (Service)
// 这个类是根据 WSDL 中的 <service> 标签生成的
WeatherWS weatherWS = new WeatherWS();
// 2. 获取服务端点对象 (PortType)
// 这个类是根据 WSDL 中的 <portType> 标签生成的,包含了所有可用的方法
WeatherWSSoap weatherWSSoap = weatherWS.getWeatherWSSoap();
// 3. 调用具体的方法
// 假设 getWeather 方法需要一个城市参数
String result = weatherWSSoap.getWeather("北京", "");
// 4. 处理返回结果
System.out.println("调用 SOAP WebService 返回的结果:");
System.out.println(result);
}
}
使用 Apache CXF 框架(更灵活、功能更强)
CXF 是一个非常流行的开源 WebService 框架,它提供了比 wsimport 更强大的功能和更好的集成能力。

步骤 1:添加 Maven 依赖
在你的 pom.xml 文件中添加 CXF 的依赖:
<dependencies>
<!-- cxf-core -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-core</artifactId>
<version>3.4.5</version>
</dependency>
<!-- cxf-rt-frontend-jaxws -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.4.5</version>
</dependency>
<!-- cxf-rt-transports-http -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.4.5</version>
</dependency>
</dependencies>
步骤 2:使用 CXF 的 JAX-WS 动态客户端
CXF 提供了一种无需预先生成代码的方式,可以直接通过 WSDL 动态调用。
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
public class CxfClientTest {
public static void main(String[] args) {
// 方法一:使用 JaxWsProxyFactoryBean (需要知道服务接口)
// 如果你能从 WSDL 中获取到服务接口的全限定名,这是最简单的方式
/*
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(com.example.weather.client.WeatherWSSoap.class); // 设置服务接口
factory.setAddress("http://ws.webxml.com.cn/WebServices/WeatherWS?wsdl");
WeatherWSSoap weatherService = (WeatherWSSoap) factory.create();
String result1 = weatherService.getWeather("上海", "");
System.out.println("JaxWsProxyFactoryBean 结果: " + result1);
*/
// 方法二:使用 JaxWsDynamicClientFactory (无需任何接口,最灵活)
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://ws.webxml.com.cn/WebServices/WeatherWS?wsdl");
try {
// invoke 方法参数:方法名, 参数1, 参数2, ...
// getWeather 方法需要两个参数,第一个是城市名,第二个是空字符串
Object[] result = client.invoke("getWeather", "广州", "");
System.out.println("JaxWsDynamicClientFactory 结果: " + result[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
}
第二部分:调用 RESTful WebService
RESTful WebService 的调用本质上是发送 HTTP 请求,并处理 HTTP 响应,在现代 Java 开发中,通常使用成熟的 HTTP 客户端库。
假设我们要调用一个公共的 JSONPlaceholder API 来获取一个用户信息:
- URL:
https://jsonplaceholder.typicode.com/users/1 - HTTP Method:
GET - 返回格式: JSON
使用 java.net.HttpURLConnection(原生,无需依赖)
这是 Java 自带的,无需任何额外依赖,但代码较为繁琐。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class NativeHttpClientTest {
public static void main(String[] args) {
String urlString = "https://jsonplaceholder.typicode.com/users/1";
try {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置请求方法
connection.setRequestMethod("GET");
// 设置请求头
connection.setRequestProperty("Accept", "application/json");
int responseCode = connection.getResponseCode();
System.out.println("Response Code: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { // 200
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// 打印返回的 JSON 字符串
System.out.println("Response Body: " + response.toString());
} else {
System.out.println("GET request failed");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用 Apache HttpClient(功能更强大的 HTTP 客户端)
Apache HttpClient 是一个久经考验的 HTTP 客户端库,功能非常全面。
步骤 1:添加 Maven 依赖
<dependencies>
<!-- Apache HttpClient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<!-- 为了方便处理 JSON,添加一个 JSON 库,Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
</dependency>
</dependencies>
步骤 2:编写调用代码
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class ApacheHttpClientTest {
public static void main(String[] args) {
String apiUrl = "https://jsonplaceholder.typicode.com/users/1";
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpGet request = new HttpGet(apiUrl);
request.addHeader("accept", "application/json");
System.out.println("Executing request " + request.getRequestLine());
try (CloseableHttpResponse response = httpClient.execute(request)) {
System.out.println(response.getStatusLine().getStatusCode());
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("Response Body: " + responseBody);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用 Spring Boot RestTemplate(经典、简洁)
如果你的项目是基于 Spring Boot 的,RestTemplate 是调用 RESTful API 的首选方式之一。
步骤 1:配置 RestTemplate
在 Spring Boot 的配置类中声明一个 RestTemplate Bean。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class AppConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
步骤 2:注入并使用 RestTemplate
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class RestTemplateUser implements CommandLineRunner {
@Autowired
private RestTemplate restTemplate;
@Override
public void run(String... args) throws Exception {
String url = "https://jsonplaceholder.typicode.com/users/1";
// 直接获取 JSON 字符串
String jsonString = restTemplate.getForObject(url, String.class);
System.out.println("RestTemplate (String): " + jsonString);
// 将 JSON 自动映射到 Java 对象 (需要定义一个对应的 User 类)
// 假设我们有一个 User 类,其字段名与 JSON 的 key 一致
User user = restTemplate.getForObject(url, User.class);
System.out.println("RestTemplate (Object): " + user.getName() + ", " + user.getEmail());
}
}
// 一个简单的 POJO 类,用于映射 JSON
class User {
private int id;
private String name;
private String username;
private String email;
// ... 其他字段,以及 getter/setter
// 为了简化,省略了 getter/setter,实际项目中需要添加
@Override
public String toString() {
return "User{" + "id=" + id + ", name='" + name + '\'' + ", email='" + email + '\'' + '}';
}
}
使用 Spring Boot WebClient(现代、异步、非阻塞)
WebClient 是 Spring 5 引入的、作为 RestTemplate 替代品的新一代 HTTP 客户端,它基于响应式编程,支持非阻塞 I/O,性能更高,尤其适合微服务架构。
步骤 1:添加依赖
WebClient 在 spring-webflux 中,但它与 Spring Boot Web starter 兼容。
<!-- spring-boot-starter-web 已经包含了 spring-webflux 的依赖 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
步骤 2:注入并使用 WebClient
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@Component
public class WebClientUser implements CommandLineRunner {
@Autowired
private WebClient.Builder webClientBuilder;
@Override
public void run(String... args) throws Exception {
String url = "https://jsonplaceholder.typicode.com/users/1";
Mono<User> userMono = webClientBuilder.build()
.get()
.uri(url)
.retrieve() // 发出请求并获取响应
.bodyToMono(User.class); // 将响应体解析为 User 对象的单个值
// 阻塞式获取结果(在简单的命令行应用中方便)
// 在实际的异步应用中,应该使用 subscribe() 方法
User user = userMono.block();
System.out.println("WebClient Result: " + user.getName() + ", " + user.getEmail());
}
}
总结与对比
| 调用类型 | 推荐方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| SOAP | JDK wsimport |
无需外部依赖,简单直接。 | 生成代码,不够灵活,处理复杂 XML/附件麻烦。 | 快速原型、简单的遗留系统集成。 |
| Apache CXF | 功能强大,支持多种协议,动态调用无需生成代码,易于集成到 Spring。 | 需要引入额外框架。 | 企业级应用、需要高级特性(如 WS-Security)的项目。 | |
| RESTful | 原生 HttpURLConnection |
无依赖,轻量级。 | 代码繁琐,功能有限,需要手动处理连接、流和错误。 | 极简应用、无法引入第三方库的环境。 |
| Apache HttpClient | 功能全面稳定,社区支持好,可定制性强。 | 代码量比 RestTemplate 多,需要手动处理 JSON。 |
需要精细控制 HTTP 请求/响应的复杂应用。 | |
Spring RestTemplate |
集成简单,代码简洁,支持自动 JSON/XML 转换。 | 是同步阻塞模型,性能不如 WebClient。 | 大多数 Spring/Spring Boot 项目的同步调用。 | |
Spring WebClient |
异步非阻塞,性能高,支持响应式编程。 | 学习曲线较陡,基于响应式编程模型。 | 新的 Spring 5+ 项目,微服务,对性能要求高的应用。 |
给你的建议:
- 如果调用 SOAP 服务:如果你的项目不复杂,直接用
wsimport,如果项目是 Spring 体系,或者你需要更强大的功能(如安全、WS-Addressing),直接用 Apache CXF。 - 如果调用 RESTful 服务:
- 如果你的项目是 Spring Boot,首选
RestTemplate(简单同步)或WebClient(高性能异步)。 - 如果不是 Spring 项目,或者你需要一个非常轻量级的解决方案,可以用 原生
HttpURLConnection。 - 如果你需要非常精细的 HTTP 控制,或者项目已经在使用 Apache Commons 生态,Apache HttpClient 是一个可靠的选择。
- 如果你的项目是 Spring Boot,首选
