使用 JDK 自带的 wsimport (最经典、最常用)
这是 Java 标准的、基于 SOAP WebService 的方法,它通过 WSDL (Web Services Description Language) 文件,自动生成客户端所需的 Java 代码(存根),然后你就可以像调用本地方法一样调用远程的 WebService。

适用场景:标准的 SOAP WebService。
步骤:
-
获取 WSDL 文件:这是 WebService 的“说明书”,描述了服务的地址、可用方法、参数和返回值类型,通常是一个 URL,
http://www.webxml.com.cn/webservices/WeatherWebService.asmx?wsdl。 -
生成客户端代码:使用 JDK 自带的
wsimport工具,打开命令行(CMD 或 PowerShell),执行以下命令:
(图片来源网络,侵删)wsimport -keep -p com.example.client http://path/to/your/service?wsdl
-keep: 生成源代码文件,方便查看和调试。-p com.example.client: 指定生成的 Java 包名。http://path/to/your/service?wsdl: WSDL 文件的 URL。
执行成功后,会在你指定的包目录下生成一堆
.java文件(如WeatherWebService.java,WeatherWebServiceSoap.java等)和一个.class文件。 -
在 Java 项目中使用生成的代码:
- 将生成的
.java文件编译到你的项目中,或者直接将生成的.class文件以及依赖的 JAR 文件添加到项目的 classpath 中。 - 在你的 Java 代码中,创建服务对象,然后调用其方法。
- 将生成的
完整示例:调用天气查询 WebService
假设我们要调用 WebXML 提供的天气查询服务。
生成客户端代码

# 创建一个项目目录,WeatherClient # 在目录下执行 wsimport 命令 wsimport -keep -p com.example.weather http://www.webxml.com.cn/webservices/WeatherWebService.asmx?wsdl
生成的关键代码结构
执行后,com/example/weather 目录下会生成类似这样的文件:
WeatherWebService.java: 服务接口。WeatherWebServiceService.java: 服务工厂类,用于获取服务实例。WeatherWebServiceSoap.java: 包含了所有可调用的方法(如getWeather)。- 以及各种用于传递参数和接收返回值的
XXX.java和XXXResponse.java类。
编写 Java 调用代码
创建一个 Main.java 文件:
package com.example.weather;
public class Main {
public static void main(String[] args) {
try {
// 1. 创建服务工厂对象
WeatherWebServiceService service = new WeatherWebServiceService();
// 2. 获取服务的 Port (端口),即实际提供服务的对象
// "WeatherWebServiceSoap" 是 wsdl 中定义的端口名称
WeatherWebServiceSoap weatherWebServiceSoap = service.getWeatherWebServiceSoap();
// 3. 调用 WebService 方法
// getWeather 方法需要城市名作为参数,返回一个字符串数组
String[] result = weatherWebServiceSoap.getWeather("北京", "");
// 4. 处理返回结果
System.out.println("===== 查询结果 =====");
if (result != null) {
for (String str : result) {
System.out.println(str);
}
} else {
System.out.println("查询失败,返回结果为空。");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行
编译并运行 Main.java,你将看到从远程 WebService 返回的北京天气信息。
使用 Apache CXF (功能强大、灵活)
Apache CXF 是一个开源的、功能齐全的 WebService 框架,它不仅支持 SOAP,也支持 RESTful 服务,它提供了比 wsimport 更多的功能和更好的扩展性。
适用场景:需要高级功能(如 WS-Security、REST 支持、更好的集成)的项目。
步骤:
-
添加依赖:如果你使用 Maven,在
pom.xml中添加 CXF 依赖。<dependencies> <!-- CXF 核心依赖 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.5.5</version> <!-- 使用最新稳定版 --> </dependency> <!-- CXF 运行时依赖 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>3.5.5</version> </dependency> </dependencies> -
生成客户端代码 (可选):CXF 也提供了代码生成工具
cxf-xjc-utils或wsdl2java(与wsimport类似),但也可以直接使用 JDK 生成的代码。 -
编写调用代码:CXF 的调用方式与
wsimport生成的代码几乎完全相同,因为它也遵循 JAX-WS (Java API for XML Web Services) 标准。// 代码与方法一中的第3步完全一样 package com.example.weather; public class CxfClientMain { public static void main(String[] args) { try { // 创建服务工厂对象 WeatherWebServiceService service = new WeatherWebServiceService(); // 获取服务的 Port WeatherWebServiceSoap weatherWebServiceSoap = service.getWeatherWebServiceSoap(); // 调用方法 String[] result = weatherWebServiceSoap.getWeather("上海", ""); // 处理结果 System.out.println("===== CXF 查询结果 ====="); if (result != null) { for (String str : result) { System.out.println(str); } } } catch (Exception e) { e.printStackTrace(); } } }
CXF 的优势:
- 无需手动生成代码:CXF 的 JAX-WS 实现可以动态代理,有时可以省去
wsimport步骤(但对于复杂服务,生成代码更稳定)。 - 强大的拦截器:可以方便地添加日志、安全、压缩等横切关注点。
- 更好的集成:与 Spring 框架无缝集成。
- 支持 SOAP 1.1/1.2, REST, CORBA 等多种协议。
调用 RESTful WebService (JSON 格式)
现代 WebService 更多地采用 RESTful 风格,通常通过 HTTP 协议,数据交换格式为 JSON,这不能使用 wsimport,而是需要发送 HTTP 请求并解析 JSON。
适用场景:调用 REST API。
工具选择:
- 传统方式:
java.net.HttpURLConnection(JDK 自带,但代码繁琐)。 - 推荐方式:
Apache HttpClient(功能强大,业界标准)。 - 现代方式:
OkHttp(轻量级,性能好)。 - 简化方式:
Spring RestTemplate(如果项目已使用 Spring,这是最简单的方式)。
示例:使用 RestTemplate (Spring 环境)
假设我们要调用一个公共的 IP 地址查询 API:http://ip-api.com/json/8.8.8.8,它会返回一个 JSON 对象。
添加 Spring 依赖
确保你的项目有 Spring Web 依赖。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
编写调用代码
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.ObjectMapper; // 用于将JSON字符串转为对象
public class RestTemplateClient {
public static void main(String[] args) {
// 1. 创建 RestTemplate 实例
RestTemplate restTemplate = new RestTemplate();
// 2. 定义 API 的 URL
String url = "http://ip-api.com/json/8.8.8.8";
// 3. 发送 GET 请求,并直接将响应体映射为 Map
// RestTemplate 会自动将 JSON 解析为 Map
@SuppressWarnings("unchecked")
Map<String, Object> response = restTemplate.getForObject(url, Map.class);
// 4. 处理返回结果
System.out.println("===== IP 查询结果 =====");
System.out.println("Country: " + response.get("country"));
System.out.println("City: 