杰瑞科技汇

Java如何远程调用WebService?

核心概念

简单理解一下 WebService 的几种主流风格:

Java如何远程调用WebService?-图1
(图片来源网络,侵删)
  1. SOAP (Simple Object Access Protocol): 一种基于 XML 的协议,它格式严格、功能强大、内置安全机制,早期的企业级应用广泛使用,它通常通过 WSDL (Web Services Description Language) 文件来描述其接口(有哪些方法、参数、返回值等)。
  2. REST (Representational State Transfer): 一种更轻量级的架构风格,通常使用 JSON 作为数据格式,通过 HTTP 的 GET、POST、PUT、DELETE 等方法来操作资源,现在更流行,更易于使用和扩展。

下面我们将分别介绍如何调用这两种风格的 WebService。


使用 JAX-WS (调用 SOAP WebService)

JAX-WS (Java API for XML Web Services) 是 Java 官方提供的用于创建和调用 SOAP WebService 的标准 API,对于传统的、有 WSDL 文件的 SOAP 服务,这是最标准、最强大的方式。

步骤 1:获取 WSDL 文件

任何 SOAP 调用的第一步都是获取服务的 WSDL 文件,它就像一个“说明书”,告诉客户端如何与服务通信。

WSDL 文件通常是一个 URL,http://www.webxml.com.cn/webservices/weatherwebservice?wsdl

Java如何远程调用WebService?-图2
(图片来源网络,侵删)

步骤 2:使用 JDK 自带的 wsimport 工具生成客户端代码

wsimport 是 JDK 自带的一个命令行工具,它可以根据 WSDL 文件自动生成一系列 Java 类(客户端存根),这些类封装了所有与服务交互的细节。

打开你的命令行(CMD 或 PowerShell),执行以下命令:

# -p: 指定生成的包名
# -d: 指定生成的 .class 文件存放目录
# -keep: 保留生成的源代码文件
# -s: 指定生成的 .java 文件存放目录
wsimport -p com.example.weather.client -d . -s . http://www.webxml.com.cn/webservices/weatherwebservice?wsdl

执行后,会在你指定的目录下生成一堆 .java.class 文件,最重要的是:

  • WeatherWS.java: 服务接口。
  • WeatherWS_Impl.java: 服务实现。
  • WeatherWSSoap.java: 核心的 SOAP 接口,里面包含了所有可调用的方法(如 getWeather)。
  • 以及其他一些辅助类(如 GetWeatherGetWeatherResponse 等,它们对应 SOAP 请求和响应的 XML 结构)。

步骤 3:在 Java 代码中调用服务

现在你可以在你的 Java 项目中使用这些生成的类来调用远程服务了。

Java如何远程调用WebService?-图3
(图片来源网络,侵删)

示例代码:

import com.example.weather.client.WeatherWS;
import com.example.weather.client.WeatherWS_Impl;
import com.example.weather.client.WeatherWSSoap;
public class JaxwsClient {
    public static void main(String[] args) {
        try {
            // 1. 创建服务实例 (Service)
            WeatherWS weatherWS = new WeatherWS_Impl();
            // 2. 获取服务端点接口 (PortType),这是真正包含方法调用的接口
            WeatherWSSoap port = weatherWS.getWeatherWSSoap();
            // 3. 调用远程方法
            // 假设 WSDL 描述的方法是 getWeather,参数是城市代码
            String cityCode = "北京"; // 注意:实际参数类型和名称需要根据生成的类来定
            // 根据生成的 GetWeather 类,参数通常是一个对象
            com.example.weather.client.GetWeather getWeather = new com.example.weather.client.GetWeather();
            getWeather.setTheCityCode(cityCode);
            com.example.weather.client.GetWeatherResponse response = port.getWeather(getWeather);
            // 4. 处理返回结果
            if (response != null && response.getGetWeatherResult() != null) {
                String result = response.getGetWeatherResult();
                System.out.println("获取到的天气信息:");
                System.out.println(result);
            } else {
                System.out.println("获取天气信息失败。");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

优点:

  • 标准化:Java 官方标准,兼容性好。
  • 类型安全:编译时就能检查类型错误。
  • 功能强大:支持 WS-Security、WS-Addressing 等企业级特性。

缺点:

  • 代码冗余:需要先生成客户端代码,增加了构建步骤。
  • 学习曲线:对于初学者,理解生成的类和调用方式有一定门槛。
  • 性能:基于 XML,解析相对较重。

使用 Apache CXF (更灵活的 SOAP 框架)

Apache CXF 是一个开源的、功能强大的 WebService 框架,它既支持 SOAP,也支持 REST,它比 JAX-WS 更灵活,提供了更多的功能和更好的集成能力。

步骤 1:添加 Maven 依赖

在你的 pom.xml 文件中添加 CXF 的依赖。

<dependencies>
    <!-- CXF 核心依赖 -->
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxws</artifactId>
        <version>3.4.5</version> <!-- 使用最新稳定版 -->
    </dependency>
    <!-- CXF 的 Jetty 服务器依赖(如果需要客户端,可以不加,但加上更完整) -->
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http-jetty</artifactId>
        <version>3.4.5</version>
    </dependency>
</dependencies>

步骤 2:使用 CXF 的 wsdl2java 工具生成客户端

CXF 也提供了自己的代码生成工具,功能和 wsimport 类似,但有时能处理更复杂的 WSDL。

下载 CXF 发行包,将 bin 目录添加到系统 PATH 中,然后执行:

wsdl2java -p com.example.weather.cxf.client -d . -server http://www.webxml.com.cn/webservices/weatherwebservice?wsdl

参数和 wsimport 类似,生成的代码结构也类似。

步骤 3:在 Java 代码中调用服务

CXF 的调用方式比纯 JAX-WS 更简洁一些,它提供了 JaxWsProxyFactoryBean

示例代码:

import com.example.weather.cxf.client.WeatherWSSoap;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
public class CxfClient {
    public static void main(String[] args) {
        // 1. 创建工厂实例
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        // 2. 设置服务接口 (WSDL 中定义的 PortType)
        factory.setServiceClass(WeatherWSSoap.class);
        // 3. 设置 WebService 的地址 (WSDL 的地址,但去掉 ?wsdl 后缀)
        factory.setAddress("http://www.webxml.com.cn/webservices/weatherwebservice.asmx");
        // 4. 创建客户端代理
        WeatherWSSoap weatherWS = factory.create(WeatherWSSoap.class);
        // 5. 调用方法
        com.example.weather.cxf.client.GetWeather getWeather = new com.example.weather.cxf.client.GetWeather();
        getWeather.setTheCityCode("上海");
        com.example.weather.cxf.client.GetWeatherResponse response = weatherWS.getWeather(getWeather);
        // 6. 处理结果
        if (response != null && response.getGetWeatherResult() != null) {
            System.out.println("使用 CXF 获取到的天气信息:");
            System.out.println(response.getGetWeatherResult());
        }
    }
}

优点:

  • 灵活性强:支持多种数据绑定(如 Aegis, JAXB),易于扩展。
  • 功能丰富:内置了大量的特性,如拦截器、数据格式转换等。
  • 优秀的集成:和 Spring 框架集成得非常好。

使用 RestTemplate (调用 RESTful WebService)

对于现代的 RESTful API,我们通常不使用 SOAP 的那一套,Spring 框架提供的 RestTemplate 是调用 REST 服务的经典工具。

步骤 1:添加 Maven 依赖

确保你的项目有 Spring 的核心依赖。

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.7.0</version> <!-- 或其他版本 -->
    </dependency>
</dependencies>

步骤 2:编写 Java 代码调用

假设有一个公开的 REST API,例如

分享:
扫描分享到社交APP
上一篇
下一篇