- JAX-WS (Java API for XML Web Services):这是目前最主流、最标准的Java官方技术,用于创建和消费SOAP (Simple Object Access Protocol) 类型的WebService,它通常与WSDL (Web Services Description Language) 文件紧密关联。
- JAX-RS (Java API for RESTful Web Services):这是用于创建和消费RESTful Web Services的Java API,它基于HTTP协议,使用JSON或XML作为数据格式,更轻量、更灵活,是目前Web开发的首选。
- Axis2 / CXF 等框架:这些是功能强大的第三方WebService框架,它们也支持SOAP和REST,提供了比标准JAX-WS/JAX-RS更丰富的功能和更灵活的配置。
下面我将分别详细介绍这三种方式,并提供最常用和最推荐的代码示例。

使用 JAX-WS (消费 SOAP WebService)
这是最经典和标准的方式,适用于企业级的、基于SOAP协议的WebService,消费WebService的核心步骤是:
- 获取WSDL文件:WSDL是WebService的“说明书”,描述了服务提供哪些方法、方法参数、返回值以及如何访问。
- 生成客户端代码:使用
wsimport工具(JDK自带)根据WSDL文件生成Java客户端代码(包括接口、实体类等)。 - 调用服务:在Java代码中像调用本地方法一样,调用生成的接口来远程调用WebService。
详细步骤与示例
假设我们要调用一个提供查询天气信息的SOAP WebService,其WSDL地址为:http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl
第1步:生成客户端代码
打开命令行(CMD),执行以下命令:

# -p: 指定生成的包名 # -d: 指定代码生成的目录 # -keep: 生成后保留源文件 # -verbose: 显示详细过程 wsimport -p com.example.weather.client -d ./src/main/java -keep -verbose http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl
执行成功后,你会在com.example.weather.client包下看到一系列生成的Java文件,其中最重要的是WeatherWSSoap接口(或类似名称,具体取决于WSDL定义)。
第2步:编写Java代码调用服务
生成的代码中会包含一个WeatherWS(或类似名称)的服务工厂类,我们可以用它来获取服务端口(Port),然后调用方法。
import com.example.weather.client.WeatherWS;
import com.example.weather.client.WeatherWSImplService;
import com.example.weather.client.ArrayOfString;
public class JaxWsClientExample {
public static void main(String[] args) {
// 1. 创建服务工厂实例
// WeatherWSImplService 是 wsimport 生成的工厂类
WeatherWSImplService factory = new WeatherWSImplService();
// 2. 获取服务端口
// WeatherWSSoap 是 wsimport 生成的接口,包含了所有可用的方法
WeatherWS weatherWS = factory.getWeatherWSSoap();
// 3. 调用WebService方法
// 假设该方法接收城市名,返回一个字符串数组
String city = "北京";
ArrayOfString result = weatherWS.getWeatherbyCityName(city);
// 4. 处理返回结果
System.out.println("查询城市: " + city);
if (result != null && result.getString() != null) {
for (String info : result.getString()) {
System.out.println(info);
}
} else {
System.out.println("未能获取天气信息。");
}
}
}
关键点:

WeatherWSImplService:这是服务工厂类,用于创建服务的客户端实例。WeatherWS(或WeatherWSSoap):这是核心接口,定义了所有可以远程调用的方法,你只需要像调用普通Java方法一样调用它即可,底层的SOAP请求和响应会由JAX-WS框架自动处理。
使用 JAX-RS (消费 RESTful WebService)
RESTful WebService基于HTTP,通常返回JSON数据,在现代Java开发中,消费REST服务最流行和推荐的方式是使用 Spring Framework 的 RestTemplate (Spring 5之前) 或 WebClient (Spring 5及之后,推荐,响应式编程)。
示例1:使用 Spring RestTemplate (传统同步方式)
假设我们要调用一个公共的REST API获取IP地址的归属地信息:
http://ip-api.com/json/8.8.8.8
第1步:添加Spring Boot依赖
确保你的pom.xml中包含了spring-boot-starter-web,它已经包含了RestTemplate。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
第2步:配置并使用 RestTemplate
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
@Configuration
public class RestTemplateConfig {
// 在Spring Boot应用中,推荐通过这种方式定义Bean
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
}
// 在你的Service或Controller中使用
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class IpLocationService {
@Autowired
private RestTemplate restTemplate;
public String getIpLocation(String ip) {
// 1. 定义API的URL
String url = "http://ip-api.com/json/{ip}";
// 2. 发送GET请求,并直接将响应体映射为String
// RestTemplate会自动处理HTTP连接和JSON转换
String response = restTemplate.getForObject(url, String.class, ip);
// 3. 处理响应
System.out.println("API Response: " + response);
return response;
}
}
// 更高级的用法:将JSON自动映射到Java对象
// 假设API返回的JSON是 {"status":"success","country":"United States","city":"Mountain View"...}
// 我们可以创建一个对应的Java类 IpLocationInfo.java
//
// IpLocationInfo info = restTemplate.getForObject(url, IpLocationInfo.class, ip);
示例2:使用 Spring WebClient (现代异步响应式方式)
WebClient是Spring 5引入的,支持非阻塞、响应式编程,性能更高,是未来的趋势。
第1步:添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
第2步:配置并使用 WebClient
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
@Configuration
public class WebClientConfig {
@Bean
public WebClient webClient(WebClient.Builder builder) {
return builder.baseUrl("http://ip-api.com").build();
}
}
// 在你的Service或Controller中使用
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@Service
public class IpLocationServiceWithWebClient {
@Autowired
private WebClient webClient;
public Mono<String> getIpLocationAsync(String ip) {
return webClient.get()
.uri("/json/{ip}", ip) // 构建URI
.retrieve() // 获取响应
.bodyToMono(String.class); // 将响应体转换为Mono<String>
}
// 在Controller中调用
// public Mono<String> getLocation(@PathVariable String ip) {
// return ipLocationServiceWithWebClient.getIpLocationAsync(ip);
// }
}
使用 Apache CXF (消费 SOAP WebService)
CXF是一个功能强大的开源框架,它也支持SOAP,如果你对JAX-WS生成的代码不满意,或者需要更高级的特性(如WS-Security),可以使用CXF。
CXF消费SOAP服务通常有两种方式:
- 从WSDL生成客户端:和JAX-WS类似,使用CXF提供的
wsdl2java工具。 - 手动创建客户端:不依赖WSDL,手动构建SOAP请求,这种方式更灵活但也更复杂。
示例:使用CXF从WSDL生成客户端并调用
第1步:添加CXF依赖
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.4.5</version> <!-- 使用最新稳定版本 -->
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.4.5</version>
</dependency>
第2步:使用 wsdl2java 生成客户端
CXF也提供了wsdl2java工具,通常在cxf-x.x.x/bin目录下。
# -p: 包名 # -d: 输出目录 # -client: 生成客户端启动类(可选) wsdl2java -p com.example.cxf.client -d ./src/main/java -keep http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl
第3步:编写Java代码调用
生成的代码和使用方式与JAX-WS非常相似,因为CXF本身就是JAX-WS的一个实现。
import com.example.cxf.client.WeatherWS;
import com.example.cxf.client.WeatherWSImplService;
public class CxfClientExample {
public static void main(String[] args) {
// 创建服务工厂
WeatherWSImplService factory = new WeatherWSImplService();
// 获取服务端点
WeatherWS weatherWS = factory.getWeatherWSSoap();
// 调用方法
String city = "上海";
ArrayOfString result = weatherWS.getWeatherbyCityName(city);
// 处理结果
System.out.println("查询城市: " + city);
if (result != null && result.getString() != null) {
result.getString().forEach(System.out::println);
}
}
}
总结与对比
| 特性 | JAX-WS (SOAP) | JAX-RS (REST) | Apache CXF (SOAP) |
|---|---|---|---|
| 协议 | SOAP (XML) | HTTP (JSON/XML) | SOAP (XML) |
| 数据格式 | XML | JSON (主流), XML | XML |
| 核心工具 | wsimport |
RestTemplate, WebClient |
wsdl2java |
| 适用场景 | 企业级应用、金融、电信等对安全、事务要求高的场景 | Web应用、移动后端、微服务,追求高性能和灵活性 | 复杂SOAP服务、需要高级WS-*特性(如安全)的场景 |
| 优点 | 标准化、功能强大(WS-Security, WS-Addressing等)、严格 | 轻量、简单、基于HTTP、易于缓存和扩展 | 功能强大、灵活、支持多种协议和数据绑定 |
| 缺点 | 协议复杂、冗余、性能相对较低 | 无统一标准,功能取决于实现 | 配置相对复杂,学习曲线稍陡 |
如何选择?
- 如果服务是SOAP类型:直接使用 JAX-WS,因为它是Java标准,简单直接,如果需要JAX-WS不支持的复杂特性(如WS-Security),再考虑 CXF。
- 如果服务是RESTful类型:毫无疑问选择 JAX-RS,在Spring生态中,优先使用
WebClient(新项目),RestTemplate(旧项目或简单同步场景)仍然可用。 - 如果不确定:优先考虑 RESTful (JAX-RS),因为它更符合现代Web开发的趋势,更简单高效。
