杰瑞科技汇

Java如何远程调用Webservice?

  1. JAX-WS (Java API for XML Web Services):Java 官方标准,是目前最主流、最推荐的方式,它简化了 WebService 的开发和调用,可以非常方便地通过客户端代理来调用。
  2. Apache CXF:一个功能强大的、开源的 WebService 框架,它既支持 JAX-WS 标准,也支持更灵活的 RESTful 服务(JAX-RS),在需要更多自定义和高级功能时,CXF 是一个绝佳选择。
  3. Axis2 / Axis1:老牌的 WebService 框架,Axis1 已经比较陈旧,Axis2 虽然功能强大,但配置和使用相对复杂,现在新项目已较少使用,除非有特殊需求。

下面我将重点讲解 JAX-WSApache CXF 这两种最常用的方法。

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

准备工作:获取 WebService 的信息

在调用之前,你需要从提供方获取以下关键信息:

  1. WSDL (Web Services Description Language) 地址:这是 WebService 的“说明书”,描述了服务的地址、可用的方法、参数和返回值类型,通常是一个 .wsdl 结尾的 URL。
  2. 目标命名空间 (Target Namespace):一个唯一的 URI,用于标识这个服务。
  3. 服务名 和端口名:在 WSDL 文件中定义。

使用 JAX-WS (Java 标准库)

JAX-WS 是 Java SE 6 和 Java EE 5 及以后版本内置的 API,无需额外添加第三方库,非常方便。

步骤 1:生成客户端代码

你需要使用 JDK 自带的 wsimport 工具,根据 WSDL 文件生成客户端所需的 Java 代码(包括接口、实体类等)。

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

Java如何远程调用Webservice?-图2
(图片来源网络,侵删)
# 基本语法
wsimport -keep -p com.example.client -d . http://example.com/service?wsdl
# 参数解释:
# -keep: 生成源代码文件,方便查看和调试。
# -p com.example.client: 指定生成的包名。
# -d .: 指定编译后的 .class 文件存放目录(这里用当前目录)。
# http://example.com/service?wsdl: WSDL 文件的 URL 地址。

执行成功后,你会在指定的目录下看到一个 com/example/client 包,里面包含了所有生成的 Java 文件。

步骤 2:调用 WebService

在 Java 代码中,通过生成的代理类来调用服务非常简单。

import com.example.client.YourService; // 生成的服务接口名
import com.example.client.YourService_Service; // 生成的服务工厂类名
import com.example.client.YourRequestType; // 生成的请求参数类名
import com.example.client.YourResponseType; // 生成的返回值类名
public class JaxwsClient {
    public static void main(String[] args) {
        // 1. 创建服务工厂实例
        // 类名通常是 "YourService_Service"
        YourService_Service service = new YourService_Service();
        // 2. 获取服务端点接口
        // 类名通常是 "YourService"
        YourService port = service.getYourServicePort(); // 方法名通常是 get + 端口名
        // 3. 准备请求参数 (使用生成的实体类)
        YourRequestType request = new YourRequestType();
        request.setParam1("value1");
        request.setParam2(123);
        try {
            // 4. 调用远程方法
            System.out.println("正在调用远程服务...");
            YourResponseType response = port.yourMethodName(request); // 方法名是 WSDL 中定义的
            // 5. 处理返回结果
            System.out.println("调用成功!");
            System.out.println("返回结果: " + response.getResult());
        } catch (Exception e) {
            // 6. 捕获并处理异常
            System.err.println("调用远程服务失败!");
            e.printStackTrace();
        }
    }
}

优点

  • 无需额外依赖,JDK 自带。
  • 使用简单,API 标准化。
  • 适合快速开发和集成。

使用 Apache CXF (更强大、更灵活)

CXF 是一个功能全面的框架,除了支持 JAX-WS,还支持 RESTful、SOAP 1.1/1.2 等多种协议,并且提供了更丰富的特性,如拦截器、数据绑定等。

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

步骤 1:添加 Maven 依赖

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

<dependencies>
    <!-- CXF 核心依赖 -->
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-core</artifactId>
        <version>3.4.5</version> <!-- 建议使用较新版本 -->
    </dependency>
    <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>
    <!-- CXF 内置了 Jetty 服务器,如果不需要可以不加 -->
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http-jetty</artifactId>
        <version>3.4.5</version>
    </dependency>
</dependencies>

步骤 2:生成客户端代码 (可选)

CXF 也提供了代码生成工具 cxf-xjc-utilswsdl2java,与 wsimport 类似,但功能更强大,如果你只是想调用服务,可以跳过这一步,使用 CXF 的动态客户端。

步骤 3:调用 WebService (静态代理方式)

这种方式与 JAX-WS 类似,但生成的代码和调用方式略有不同。

  1. 使用 CXF 的 wsdl2java 工具生成代码:

    # 需要先下载 CXF 并将 bin 目录加入 PATH
    wsdl2java -p com.example.cxf.client -client -d . http://example.com/service?wsdl
    • -client: 生成一个可直接运行的客户端示例类。
    • -server: 生成一个服务器端骨架。
  2. 调用生成的代码: 生成的代码通常会包含一个客户端示例,你可以参考它来编写自己的调用逻辑。

步骤 4:调用 WebService (动态客户端方式 - 推荐)

动态客户端无需提前生成任何 Java 代码,非常灵活,特别适合 WSDL 地址可能变化或只是临时调用某个服务的场景。

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.jaxws.JaxWsDynamicClientFactory;
public class CxfClient {
    public static void main(String[] args) {
        // --- 方式一:使用 JaxWsProxyFactoryBean (推荐,类型安全) ---
        callWithProxyFactory();
        // --- 方式二:使用 JaxWsDynamicClientFactory (完全动态,不生成代码) ---
        callWithDynamicClient();
    }
    /**
     * 方式一:使用 JaxWsProxyFactoryBean
     * 这种方式会动态创建一个代理对象,但其接口仍然是通过 WSDL 生成的(IDE 可能会报错,但运行正常)。
     * 实际项目中,最好还是先生成接口。
     */
    public static void callWithProxyFactory() {
        // 1. 创建工厂 Bean
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        // 2. 设置 WSDL 地址
        factory.setAddress("http://example.com/service?wsdl");
        // 3. 设置服务接口 (如果提前生成了类,就用生成的类)
        // factory.setServiceClass(com.example.YourService.class);
        // 如果没有生成,这里可以写一个接口,但方法签名必须和 WSDL 中的一致
        // factory.setServiceClass(com.example.cxf.client.YourService.class);
        // 4. 创建客户端代理
        Object service = factory.create();
        // 假设我们知道服务接口有一个方法叫 sayHello
        com.example.cxf.client.YourService port = (com.example.cxf.client.YourService) service;
        try {
            // 5. 调用方法
            String response = port.sayHello("World from CXF");
            System.out.println("--- ProxyFactoryBean 调用结果 ---");
            System.out.println(response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 方式二:使用 JaxWsDynamicClientFactory (
分享:
扫描分享到社交APP
上一篇
下一篇