杰瑞科技汇

如何用Java调用WebService?

我会从最基础的概念讲起,然后介绍两种主流的实现方式:传统的 JAX-WS现代的 Spring Boot

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

目录

  1. 第一部分:基础概念

    • 什么是 WebService?
    • WebService 的核心协议:SOAP 和 WSDL
    • 调用 WebService 的两种主要模式
  2. 第二部分:传统方式 - 使用 JAX-WS (Java API for XML-Based Web Services)

    • 客户端调用(最常见)
      • 准备工作:获取 WSDL 文件
      • 使用 wsimport 命令生成客户端代码(传统但经典)
      • 使用 IDE(如 IntelliJ IDEA)自动生成客户端代码(推荐)
      • 完整代码示例
    • 服务端开发

      简单介绍,作为知识补充

  3. 第三部分:现代方式 - 使用 Spring Boot

    如何用Java调用WebService?-图2
    (图片来源网络,侵删)
    • 客户端调用(推荐)
      • 添加依赖
      • 使用 WebClient (Spring WebFlux) 进行调用(现代、异步、高效)
      • 使用 RestTemplate (Spring Web MVC) 进行调用(传统、同步)
      • 完整代码示例
    • 服务端开发
      • 添加依赖
      • 创建服务端接口和实现
      • 发布 WebService
      • 访问 WSDL
  4. 第四部分:总结与对比


第一部分:基础概念

什么是 WebService?

WebService 是一种跨编程语言、跨操作系统的远程调用技术,它允许不同的应用程序通过网络进行交互,它使用开放标准(如 XML, HTTP, SOAP)进行通信,实现了真正的平台独立性。

WebService 的核心协议:SOAP 和 WSDL

  • WSDL (Web Services Description Language):WebService 的“说明书”,它是一个 XML 文件,描述了 WebService 的所有信息,包括:

    • 服务地址 (Endpoint/URL)
    • 可用方法 (Operations)
    • 每个方法的参数 (Input/Output Messages)
    • 参数和返回值的类型 (Data Types)
    • 通信协议 (通常是基于 HTTP 的 SOAP) 调用任何 WebService 的第一步,就是获取它的 WSDL 文件。
  • SOAP (Simple Object Access Protocol):WebService 的“沟通语言”,它是一种基于 XML 的协议,用于在 Web 上交换结构化的信息,SOAP 消息通常是一个 XML 文档,包含了请求或响应的数据,它被包装在 HTTP 请求中发送。

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

调用 WebService 的两种主要模式

  • 契约优先:这是最标准、最健壮的方式,你首先拥有一个由服务提供方定义好的 WSDL 文件,客户端基于这个 WSDL 生成调用代码,服务端也基于它来开发实现,这确保了客户端和服务端的“契约”一致。
  • 代码优先:开发者先在 Java 代码中定义接口和类,然后由框架(如 JAX-WS)自动生成 WSDL 文件,这种方式在开发内部服务时比较方便,但在跨组织协作时不如契约优先清晰。

第二部分:传统方式 - 使用 JAX-WS

JAX-WS 是 Java 标准官方 API,用于创建和调用 WebService,它内置在 JDK 中,无需额外安装框架。

客户端调用

假设我们要调用一个公开的天气查询 WebService,其 WSDL 地址为:http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl

使用 wsimport 命令生成客户端代码

  1. 打开命令行,执行以下命令,这会根据 WSDL 生成一堆 Java 源文件和类文件。

    # -p: 指定生成的包名
    # -keep: 保留生成的源文件
    # -d: 指定 class 文件输出目录
    wsimport -p com.example.weather.client -keep http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl

    执行后,你会得到一堆 .java.class 文件,这些就是客户端的“代理代码”。

  2. 将生成的代码导入项目:将生成的 com 文件夹复制到你的 Java 项目的 src 目录下。

  3. 编写调用代码

    package com.example.weather.client;
    public class WeatherClient {
        public static void main(String[] args) {
            // 1. 创建服务视图 (Service)
            // WeatherWebService 是 wsimport 生成的类,它代表了整个 WebService
            WeatherWebService service = new WeatherWebService();
            // 2. 获取服务端点 (Port)
            // WeatherWebServiceSoap 是 wsimport 生成的接口,它代表了具体的端口(即可调用的方法集合)
            WeatherWebServiceSoap port = service.getWeatherWebServiceSoap();
            // 3. 调用方法并传递参数
            // getWeather 是 WSDL 中定义的一个方法
            String[] result = port.getWeather("北京", "null");
            // 4. 处理结果
            if (result != null) {
                for (String s : result) {
                    System.out.println(s);
                }
            } else {
                System.out.println("获取天气失败");
            }
        }
    }

使用 IDE(如 IntelliJ IDEA)自动生成(推荐)

这个过程和 wsimport 命令完全一样,只是图形化操作,更简单。

  1. 在 IDEA 中,右键项目 -> New -> Web Service Client
  2. 在弹出的窗口中,输入 WSDL 地址,点击 OK
  3. IDE 会自动完成下载、解析、生成代码的全过程,并将生成的代码放在你指定的包下。
  4. 之后,你只需要像上面一样,编写调用代码即可。

第三部分:现代方式 - 使用 Spring Boot

Spring Boot 是目前 Java 开发的主流框架,它简化了 WebService 的开发,并且提供了更现代的客户端调用方式。

客户端调用

对于现代 WebService,很多也提供了 RESTful 风格的 API,但如果是传统的 SOAP WebService,Spring Boot 也能很好地支持,这里我们重点介绍调用 RESTful 风格的 WebService,因为它更常见。

添加依赖

在你的 pom.xml 中添加 WebClient 的依赖(Spring WebFlux)。

<dependencies>
    <!-- Spring Boot Starter Web (包含 Web, Tomcat, etc.) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 如果需要调用 SOAP WebService,可以添加这个 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web-services</artifactId>
    </dependency>
</dependencies>

使用 WebClient 调用(推荐)

WebClient 是 Spring 5 引入的响应式、非阻塞的 HTTP 客户端,性能更高,是未来的趋势。

假设我们要调用一个公开的 JSON API,https://jsonplaceholder.typicode.com/posts/1

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@SpringBootApplication
public class WebServiceClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebServiceClientApplication.class, args);
    }
    // 可以将 WebClient 定义为 Bean,方便复用
    public WebClient webClient() {
        return WebClient.create();
    }
}
// 在另一个类或主类的内部进行调用
class PostService {
    private final WebClient webClient;
    public PostService(WebClient webClient) {
        this.webClient = webClient;
    }
    public void fetchPost() {
        // 定义请求的 URL
        String url = "https://jsonplaceholder.typicode.com/posts/1";
        // 发起 GET 请求,并期望返回一个 JSON 字符串
        Mono<String> postMono = webClient.get()
                .uri(url)
                .retrieve() // 执行请求并获取响应
                .bodyToMono(String.class); // 将响应体映射为 String
        // 订阅并处理结果
        postMono.subscribe(postJson -> {
            System.out.println("获取到的 Post JSON 数据:");
            System.out.println(postJson);
        });
    }
}

代码解释

  1. WebClient.create() 创建一个 WebClient 实例。
  2. get() 指定 HTTP 方法为 GET。
  3. uri(url) 设置请求的 URL。
  4. retrieve() 发出请求并获取响应,它会自动处理状态码(如 200, 404, 500)。
  5. bodyToMono(String.class) 将响应体(body)异步地映射成一个 Mono<String>Mono 是 Reactor 中的一个响应式类型,代表 0 到 1 个元素。
  6. subscribe() 是一个触发点,当数据到达时,会执行传入的 Lambda 表达式。

使用 RestTemplate 调用(传统同步)

RestTemplate 是 Spring 传统的同步 HTTP 客户端,虽然官方不推荐在新项目中作为首选,但仍在广泛使用。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class WebServiceClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebServiceClientApplication.class, args);
        RestTemplate restTemplate = new RestTemplate();
        String url = "https://jsonplaceholder.typicode.com/posts/1";
        String postJson = restTemplate.getForObject(url, String.class);
        System.out.println("获取到的 Post JSON 数据:");
        System.out.println(postJson);
    }
}

RestTemplate 的代码更简洁,但它是阻塞式的,每个请求都会占用一个线程。


第四部分:总结与对比

特性 JAX-WS (传统) Spring Boot (现代)
主要用途 调用或开发传统的 SOAP WebService。 调用或开发现代的 RESTful API,同时也能支持 SOAP。
客户端调用方式 代码生成模式:必须先通过 WSDL 生成客户端代理类,然后像调用本地方法一样调用。 HTTP 客户端模式:直接通过 HTTP 请求(GET, POST, PUT, DELETE)与 RESTful 服务交互,无需生成代理代码。
核心组件 wsimport 命令,生成的 ServicePort 接口。 WebClient (异步非阻塞), RestTemplate (同步阻塞)。
易用性 对于 SOAP 服务,流程固定但略显繁琐,对于 RESTful 服务支持不佳。 非常简单,直接构造 HTTP 请求,处理 JSON/XML 响应,符合现代开发习惯。
性能 同步阻塞,性能一般。 WebClient 是异步非阻塞的,在高并发场景下性能优异。RestTemplate 是同步阻塞的。
学习曲线 需要理解 SOAP, WSDL, XML 等概念。 主要理解 HTTP 协议和 Spring 框架即可。
推荐场景 必须调用遗留的 SOAP 系统。
项目要求使用标准 Java API。
所有新项目,特别是微服务架构。
调用现代的 RESTful API。
  • 如果你的任务是调用一个传统的、基于 SOAP 协议的 WebService,并且你拿到了 WSDL 文件,那么使用 JAX-WS 是最标准、最可靠的选择。
  • 如果你的任务是调用现代的、基于 RESTful 风格的 API,或者你想构建一个现代化的服务,那么使用 Spring Boot 中的 WebClientRestTemplate 是不二之选,尤其是 WebClient,代表了未来的方向。
分享:
扫描分享到社交APP
上一篇
下一篇