核心概念:SOAP vs. RESTful
在开始之前,最重要的一步是确定你要调用的 WebService 是什么类型。

| 特性 | SOAP (Simple Object Access Protocol) | RESTful (Representational State Transfer) |
|---|---|---|
| 协议 | 严格基于 XML,通常通过 HTTP/SMTP 协议传输。 | 基于 HTTP 协议本身,没有额外的协议层。 |
| 格式 | 强制使用 XML。 | 灵活,通常使用 JSON、XML、Text 等,JSON 是目前最主流的。 |
| 标准 | 标准化程度高,有 WSDL (Web Services Description Language) 文件来定义服务接口、方法、参数等。 | 无统一标准,依赖 URI 设计和 HTTP 方法。 |
| 架构 | 面向服务和消息,有严格的规范。 | 面向资源和操作,风格更轻量。 |
| 优点 | 安全性高、可靠、可扩展,有严格的契约。 | 简单、轻量、易于使用和缓存,与 Web 天然融合。 |
| 适用场景 | 企业级应用、金融、电信等对安全性和事务性要求高的场景。 | 移动 App、前后端分离项目、公共 API 等。 |
如何判断?
- SOAP: 通常会提供一个
.wsdl文件,调用方式比较“重量级”。 - RESTful: 通常会提供 API 文档(如 Swagger/OpenAPI),使用 HTTP 动词(GET, POST, PUT, DELETE)来操作资源,数据格式多为 JSON。
调用 SOAP WebService
调用 SOAP 服务最经典和强大的方式是使用 JAX-WS (Java API for XML Web Services) 规范,它允许你通过一个 WSDL 文件自动生成客户端代码,然后像调用本地 Java 方法一样调用远程服务。
准备工作
- 获取 WSDL 文件地址:这是调用 SOAP 服务的“地图”。
http://www.example.com/service?wsdl - JDK 环境:确保你的 JDK 中包含了
wsimport工具(通常在bin目录下),这是 JDK 自带的,无需额外安装。
操作步骤
第 1 步:使用 wsimport 生成客户端代码
打开你的命令行(CMD 或 PowerShell),进入你项目的 Java 源代码根目录(src/main/java),然后执行以下命令:
wsimport -p com.example.client -keep -Xnocompile http://www.example.com/service?wsdl
命令参数解释:

-p com.example.client: 指定生成的 Java 包名。-keep: 生成源代码文件(.java),方便查看和理解。-Xnocompile: 只生成源代码,不编译成 .class 文件。http://www.example.com/service?wsdl: 你的 WSDL 文件地址。
执行成功后,会在你指定的包下生成一堆 Java 文件,包括:
- 服务接口:如
YourService.java - 服务端点接口:如
YourServicePortType.java(或YourServiceSoap.java),这里面包含了你在 WSDL 中定义的所有方法。 - 数据模型类:用于封装请求和响应的 XML 数据。
- 工厂类和异常类等。
第 2 步:在 Java 代码中调用服务
你可以像使用普通 Java 对象一样调用服务了。
示例代码:
假设 wsimport 生成的核心接口是 WeatherService 和 WeatherServiceSoap。

package com.example.client;
public class SoapWebServiceClient {
public static void main(String[] args) {
try {
// 1. 创建服务对象 (Service)
// WeatherService 是 wsimport 生成的服务接口
WeatherService service = new WeatherService();
// 2. 获取服务端口 (Port)
// WeatherServiceSoap 是 wsimport 生成的包含具体业务方法的接口
WeatherServiceSoap port = service.getWeatherServiceSoap();
// 3. 调用远程方法
// 假设 WSDL 中定义了一个 getCityWeather 方法,接受一个城市名,返回一个天气信息对象
String cityName = "北京";
GetCityWeatherResponse response = port.getCityWeather(cityName);
// 4. 处理响应
// GetCityWeatherResult 是 wsimport 生成的响应对象
if (response != null && response.getGetCityWeatherResult() != null) {
String weatherInfo = response.getGetCityWeatherResult();
System.out.println("城市: " + cityName);
System.out.println("天气信息: " + weatherInfo);
} else {
System.out.println("获取天气信息失败,响应为空。");
}
} catch (Exception e) {
e.printStackTrace();
System.err.println("调用 SOAP 服务时发生错误: " + e.getMessage());
}
}
}
注意事项
- 依赖:
wsimport生成的代码依赖于标准的 Java SE 库,如javax.xml.*和jakarta.xml.*(取决于你的 JDK 版本),所以通常不需要额外添加 Maven/Gradle 依赖。 - 网络代理:如果你的服务需要通过代理服务器访问,可能需要配置 JVM 参数:
-Dhttp.proxyHost=your_proxy_host -Dhttp.proxyPort=your_proxy_port -Dhttps.proxyHost=your_proxy_host -Dhttps.proxyPort=your_proxy_port
- 超时设置:对于长时间运行的服务,可以设置连接和读取超时。
// 在获取 port 之后,设置超时时间(单位:毫秒) ((BindingProvider) port).getRequestContext().put( "javax.xml.ws.client.connectionTimeout", 5000); ((BindingProvider) port).getRequestContext().put( "javax.xml.ws.client.receiveTimeout", 10000);
调用 RESTful WebService
RESTful 服务本质上是 HTTP 服务,调用它就是发送 HTTP 请求并处理响应,在 Java 中,有多种 HTTP 客户端库可以使用。
方案 A:使用 HttpURLConnection (JDK 内置)
这是最基础的方式,无需任何第三方库,但代码比较繁琐。
示例代码:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class JdkHttpURLConnectionClient {
public static void main(String[] args) {
// 目标 API 地址,例如一个获取用户信息的 REST API
String apiUrl = "https://jsonplaceholder.typicode.com/users/1";
try {
// 1. 创建 URL 对象
URL url = new URL(apiUrl);
// 2. 打开连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 3. 设置请求方法
connection.setRequestMethod("GET");
// 4. 设置请求头
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("User-Agent", "MyJavaApp/1.0");
// 5. 获取响应码
int responseCode = connection.getResponseCode();
System.out.println("Response Code: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { // 200
// 6. 读取响应数据
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// 7. 打印结果
System.out.println("API Response: " + response.toString());
} else {
System.out.println("GET request failed.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
方案 B:使用 Apache HttpClient (推荐)
Apache HttpClient 是一个功能强大、稳定且成熟的 HTTP 客户端库,是目前 Java 开发中的事实标准。
添加 Maven 依赖:
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.3.1</version> <!-- 使用最新版本 -->
</dependency>
示例代码:
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.net.URIBuilder;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class ApacheHttpClientExample {
public static void main(String[] args) {
// 1. 创建 HttpClient 实例
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
// 2. 创建 HTTP GET 请求
// 使用 URIBuilder 可以方便地处理 URL 参数
URI uri = new URIBuilder("https://jsonplaceholder.typicode.com/posts")
.addParameter("userId", "1")
.build();
HttpGet request = new HttpGet(uri);
request.addHeader("Accept", "application/json");
request.addHeader("User-Agent", "MyJavaApp/1.0");
// 3. 执行请求并获取响应
try (CloseableHttpResponse response = httpClient.execute(request)) {
// 4. 获取响应实体
HttpEntity entity = response.getEntity();
// 5. 打印响应状态码
System.out.println("Response Code: " + response.getCode());
if (entity != null) {
// 6. 将响应实体内容转换为字符串
String result = EntityUtils.toString(entity, StandardCharsets.UTF_8);
System.out.println("API Response: " + result);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
方案 C:使用 OkHttp (流行)
OkHttp 是另一个非常流行的 HTTP 客户端,以其高效和简洁的 API 而闻名,尤其常用于 Android 开发。
添加 Maven 依赖:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version> <!-- 使用最新版本 -->
</dependency>
示例代码:
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class OkHttpExample {
public static void main(String[] args) {
// 1. 创建 OkHttpClient 实例
OkHttpClient client = new OkHttpClient();
// 2. 创建 Request 对象
Request request = new Request.Builder()
.url("https://jsonplaceholder.typicode.com/users/1")
.addHeader("Accept", "application/json")
.addHeader("User-Agent", "MyJavaApp/1.0")
.build();
// 3. 同步执行请求
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
// 4. 获取并打印响应体
String responseBody = response.body().string();
System.out.println("API Response: " + responseBody);
} catch (IOException e) {
e.printStackTrace();
}
}
}
总结与选择
| 场景 | 推荐方案 | 优点 | 缺点 |
|---|---|---|---|
| 调用 SOAP 服务 | JAX-WS (wsimport) |
标准化、代码生成、类型安全、面向对象 | 依赖 WSDL、相对“重量级” |
| 调用 RESTful 服务 | Apache HttpClient | 功能全面、稳定、高度可配置、社区成熟 | API 相对 OkHttp 稍显复杂 |
| OkHttp | API 简洁、性能高、支持异步、对现代网络友好 | 功能比 HttpClient 略少 | |
| 简单快速调用 (SE) | JDK HttpURLConnection |
无需依赖、轻量 | 代码繁琐、功能有限 |
给你的建议:
- 明确你调用的服务是 SOAP 还是 RESTful。 这是决定你使用哪种技术的第一步。
- 如果是 SOAP,直接使用
wsimport生成客户端,这是最标准、最可靠的方式。 - 如果是 RESTful:
- 在企业级 Java 后端项目中,Apache HttpClient 是一个非常稳妥和强大的选择。
- 如果你希望代码更简洁,或者项目涉及异步调用,OkHttp 是一个极佳的选择。
- 如果只是做一个简单的测试或脚本,且不想引入第三方库,可以考虑使用
HttpURLConnection。
如果你使用的是 Spring Boot 框架,情况会更简单,因为 Spring 提供了 RestTemplate (已不推荐) 和 WebClient (推荐,支持响应式编程) 这两个强大的 HTTP 客户端,它们内部也使用了像 OkHttp 或 Apache HttpClient 这样的库,并对它们进行了优秀的封装。
