WebService 是一种跨编程语言、跨操作系统平台的远程调用技术,它使用 HTTP 协议传输 XML 或 SOAP(Simple Object Access Protocol)格式的数据,实现了不同系统间的数据交换和通信。

在 Java 生态中,主要有三种主流的方式来调用 WebService:
- JAX-WS (Java API for XML Web Services):这是 Java 官方标准,用于创建和调用基于 SOAP 协议的 WebService,它是目前最主流、最成熟的方式。
- JAX-RS (Java API for RESTful Web Services):这是用于创建和调用 RESTful 风格 WebService 的标准,虽然严格来说 REST 不属于 WebService 范畴(传统 WebService 指 SOAP),但在实际开发中,我们经常将 REST API 也泛称为 WebService。
- 第三方框架(如 Apache Axis2, CXF):这些是功能更强大、更灵活的开源框架,它们实现了 JAX-WS 和 JAX-RS 标准,并提供了更多高级特性。
下面我们重点讲解最常用的 JAX-WS 和 JAX-RS。
基于 JAX-WS 的 WebService 调用 (SOAP)
JAX-WS 是 Java EE 的一部分,在 Java SE 6.0 之后已经内置了其运行时环境,无需额外安装,它允许你通过简单的 API 调用远程的 SOAP WebService。
场景:调用一个公共的天气查询 WebService
假设我们有一个提供 SOAP 服务的地址:http://www.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl

步骤 1:获取 WSDL 文件并生成客户端代码
WSDL (Web Services Description Language) 是一个 XML 文件,它描述了 WebService 的所有信息,包括服务地址、可用的方法、参数和返回值类型。
在 Java 中,我们可以使用 JDK 自带的 wsimport 工具来根据 WSDL 文件生成客户端所需的 Java 代码(包括服务接口、实体类等)。
-
打开命令行(CMD 或 PowerShell)。
(图片来源网络,侵删) -
执行以下命令:
# -keep: 生成源代码文件 # -d: 指定编译后的 .class 文件存放目录 # -p: 指定生成的包名 # wsdlLocation: 指定 wsdl 文件的原始位置,运行时仍会使用它 wsimport -keep -d . -p com.example.weather http://www.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl
执行成功后,会在你指定的目录下生成一堆
.java和.class文件。
步骤 2:使用生成的代码进行远程调用
生成的代码中,最重要的两个类是:
WeatherWSSoap:这是服务接口,包含了所有可调用的方法(如getWeather)。WeatherWS:这是服务工厂类,用于获取WeatherWSSoap接口的实例。
下面是调用代码示例:
import com.example.weather.WeatherWS;
import com.example.weather.WeatherWSSoap;
import com.example.weather.ArrayOfString;
public class JaxWsClient {
public static void main(String[] args) {
// 1. 创建服务工厂实例
WeatherWS weatherWS = new WeatherWS();
// 2. 从工厂中获取服务接口的实例 (port)
// 这个实例就是可以直接调用的代理对象
WeatherWSSoap soap = weatherWS.getWeatherWSSoap();
try {
// 3. 调用远程方法
// getWeather 方法需要城市名称作为参数
ArrayOfString weatherInfo = soap.getWeather("北京");
// 4. 处理返回结果
// 返回结果是一个字符串列表
java.util.List<String> list = weatherInfo.getString();
System.out.println("北京的天气信息:");
for (String info : list) {
System.out.println(info);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
JAX-WS 调用流程:
- 获取 WSDL:从服务提供方获取 WebService 的 WSDL 地址。
- 生成客户端代码:使用
wsimport工具根据 WSDL 生成 Java 代码。 - 创建服务工厂:实例化生成的工厂类(如
WeatherWS)。 - 获取服务端点:从工厂类中获取服务接口的实例(如
WeatherWSSoap)。 - 调用方法:像调用本地方法一样,调用服务接口上的方法,JAX-WS 框架会自动将其转换为 SOAP 请求发送到服务器,并接收 SOAP 响应,再解析成 Java 对象返回给你。
基于 JAX-RS 的 WebService 调用 (REST)
REST (Representational State Transfer) 是一种更轻量级的架构风格,通常与 JSON 数据格式配合使用,在现代 Web 开发(尤其是移动端和前后端分离项目)中非常流行。
Java 中调用 RESTful 服务,通常使用 javax.ws.rs.client.Client 和 javax.ws.rs.client.WebTarget 等类。
场景:调用一个公共的 RESTful API(如 GitHub API)
假设我们要调用 GitHub API 获取用户信息:https://api.github.com/users/dunwu
步骤 1:添加 JAX-RS 实现(如 Jersey)依赖
JAX-RS 只是一个标准,你需要选择一个实现,Jersey 是最流行的实现之一。
如果你使用 Maven,在 pom.xml 中添加 Jersey 核心依赖:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.35</version> <!-- 使用较新稳定版本 -->
</dependency>
步骤 2:编写 Java 代码进行调用
JAX-RS 的调用非常直观,类似于构建一个 URL。
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
public class JaxRsClient {
public static void main(String[] args) {
// 1. 创建一个 Client 实例
Client client = ClientBuilder.newClient();
try {
// 2. 创建 WebTarget,指定目标资源的 URI
WebTarget target = client.target("https://api.github.com/users/dunwu");
// 3. 发送 GET 请求,并指定期望的响应媒体类型为 JSON
// .request(MediaType.APPLICATION_JSON) 设置 Accept 头
// .get() 发送 GET 请求并获取 Response 对象
Response response = target.request(MediaType.APPLICATION_JSON).get();
// 4. 检查响应状态码
if (response.getStatus() == 200) {
// 5. 如果成功,将响应实体(JSON 字符串)读取为 String
String entity = response.readEntity(String.class);
System.out.println("获取到的用户信息 (JSON):");
System.out.println(entity);
} else {
System.err.println("请求失败,状态码: " + response.getStatus());
}
} finally {
// 6. 关闭 Client,释放资源
client.close();
}
}
}
进阶:将 JSON 反序列化为 Java 对象
为了更方便地使用数据,我们通常会将 JSON 字符串反序列化为一个 Java 对象(POJO)。
-
创建一个与 JSON 结构对应的 Java 类(POJO)
// 使用 Lombok 简化代码 import lombok.Data; import com.fasterxml.jackson.annotation.JsonProperty; @Data public class GitHubUser { private int id; private String login; private String name; @JsonProperty("public_repos") // JSON 中的 key 与 Java 属性名不一致时使用 private int publicRepos; // ... 其他字段 } -
修改调用代码,直接获取 POJO 对象
// ... (Client 和 WebTarget 创建部分相同) // 直接调用 .get(GitHubUser.class) 方法,Jersey 会自动完成 JSON 到对象的转换 GitHubUser user = target.request(MediaType.APPLICATION_JSON).get(GitHubUser.class); System.out.println("用户名: " + user.getLogin()); System.out.println("公开仓库数: " + user.getPublicRepos());
JAX-RS 调用流程:
- 创建 Client:
ClientBuilder.newClient()。 - 构建 Target:
client.target(uri)定义请求的 URL。 - 配置请求:通过
request().accept()等方法设置 HTTP 头。 - 发送请求:调用
.get(),.post(),.put()等方法
