杰瑞科技汇

Java webservice远程调用如何实现高效通信?

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

Java webservice远程调用如何实现高效通信?-图1
(图片来源网络,侵删)

在 Java 生态中,主要有三种主流的方式来调用 WebService:

  1. JAX-WS (Java API for XML Web Services):这是 Java 官方标准,用于创建和调用基于 SOAP 协议的 WebService,它是目前最主流、最成熟的方式。
  2. JAX-RS (Java API for RESTful Web Services):这是用于创建和调用 RESTful 风格 WebService 的标准,虽然严格来说 REST 不属于 WebService 范畴(传统 WebService 指 SOAP),但在实际开发中,我们经常将 REST API 也泛称为 WebService。
  3. 第三方框架(如 Apache Axis2, CXF):这些是功能更强大、更灵活的开源框架,它们实现了 JAX-WS 和 JAX-RS 标准,并提供了更多高级特性。

下面我们重点讲解最常用的 JAX-WSJAX-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

Java webservice远程调用如何实现高效通信?-图2
(图片来源网络,侵删)

步骤 1:获取 WSDL 文件并生成客户端代码

WSDL (Web Services Description Language) 是一个 XML 文件,它描述了 WebService 的所有信息,包括服务地址、可用的方法、参数和返回值类型。

在 Java 中,我们可以使用 JDK 自带的 wsimport 工具来根据 WSDL 文件生成客户端所需的 Java 代码(包括服务接口、实体类等)。

  1. 打开命令行(CMD 或 PowerShell)。

    Java webservice远程调用如何实现高效通信?-图3
    (图片来源网络,侵删)
  2. 执行以下命令:

    # -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 调用流程:

  1. 获取 WSDL:从服务提供方获取 WebService 的 WSDL 地址。
  2. 生成客户端代码:使用 wsimport 工具根据 WSDL 生成 Java 代码。
  3. 创建服务工厂:实例化生成的工厂类(如 WeatherWS)。
  4. 获取服务端点:从工厂类中获取服务接口的实例(如 WeatherWSSoap)。
  5. 调用方法:像调用本地方法一样,调用服务接口上的方法,JAX-WS 框架会自动将其转换为 SOAP 请求发送到服务器,并接收 SOAP 响应,再解析成 Java 对象返回给你。

基于 JAX-RS 的 WebService 调用 (REST)

REST (Representational State Transfer) 是一种更轻量级的架构风格,通常与 JSON 数据格式配合使用,在现代 Web 开发(尤其是移动端和前后端分离项目)中非常流行。

Java 中调用 RESTful 服务,通常使用 javax.ws.rs.client.Clientjavax.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)。

  1. 创建一个与 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;
        // ... 其他字段
    }
  2. 修改调用代码,直接获取 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 调用流程:

  1. 创建 ClientClientBuilder.newClient()
  2. 构建 Targetclient.target(uri) 定义请求的 URL。
  3. 配置请求:通过 request().accept() 等方法设置 HTTP 头。
  4. 发送请求:调用 .get(), .post(), .put() 等方法
分享:
扫描分享到社交APP
上一篇
下一篇