杰瑞科技汇

Java如何调用WebServer?

核心概念:SOAP vs. RESTful

在开始之前,最重要的一步是确定你要调用的 WebService 是什么类型。

Java如何调用WebServer?-图1
(图片来源网络,侵删)
特性 SOAP (Simple Object Access Protocol) RESTful (Representational State Transfer)
协议 严格基于 XML,通常通过 HTTP/SMTP 协议传输。 基于 HTTP 协议本身,没有额外的协议层。
格式 强制使用 XML。 灵活,通常使用 JSON、XML、Text 等,JSON 是目前最主流的。
标准 标准化程度高,有 WSDL (Web Services Description Language) 文件来定义服务接口、方法、参数等。 无统一标准,依赖 URI 设计和 HTTP 方法。
架构 面向服务和消息,有严格的规范。 面向资源和操作,风格更轻量。
优点 安全性高、可靠、可扩展,有严格的契约。 简单、轻量、易于使用和缓存,与 Web 天然融合。
适用场景 企业级应用、金融、电信等对安全性和事务性要求高的场景。 移动 App、前后端分离项目、公共 API 等。

如何判断?

  • SOAP: 通常会提供一个 .wsdl 文件,调用方式比较“重量级”。
  • RESTful: 通常会提供 API 文档(如 Swagger/OpenAPI),使用 HTTP 动词(GET, POST, PUT, DELETE)来操作资源,数据格式多为 JSON。

调用 SOAP WebService

调用 SOAP 服务最经典和强大的方式是使用 JAX-WS (Java API for XML Web Services) 规范,它允许你通过一个 WSDL 文件自动生成客户端代码,然后像调用本地 Java 方法一样调用远程服务。

准备工作

  1. 获取 WSDL 文件地址:这是调用 SOAP 服务的“地图”。http://www.example.com/service?wsdl
  2. JDK 环境:确保你的 JDK 中包含了 wsimport 工具(通常在 bin 目录下),这是 JDK 自带的,无需额外安装。

操作步骤

第 1 步:使用 wsimport 生成客户端代码

打开你的命令行(CMD 或 PowerShell),进入你项目的 Java 源代码根目录(src/main/java),然后执行以下命令:

wsimport -p com.example.client -keep -Xnocompile http://www.example.com/service?wsdl

命令参数解释:

Java如何调用WebServer?-图2
(图片来源网络,侵删)
  • -p com.example.client: 指定生成的 Java 包名。
  • -keep: 生成源代码文件(.java),方便查看和理解。
  • -Xnocompile: 只生成源代码,不编译成 .class 文件。
  • http://www.example.com/service?wsdl: 你的 WSDL 文件地址。

执行成功后,会在你指定的包下生成一堆 Java 文件,包括:

  • 服务接口:如 YourService.java
  • 服务端点接口:如 YourServicePortType.java (或 YourServiceSoap.java),这里面包含了你在 WSDL 中定义的所有方法。
  • 数据模型类:用于封装请求和响应的 XML 数据。
  • 工厂类和异常类等。

第 2 步:在 Java 代码中调用服务

你可以像使用普通 Java 对象一样调用服务了。

示例代码:

假设 wsimport 生成的核心接口是 WeatherServiceWeatherServiceSoap

Java如何调用WebServer?-图3
(图片来源网络,侵删)
package com.example.client;
public class SoapWebServiceClient {
    public static void main(String[] args) {
        try {
            // 1. 创建服务对象 (Service)
            // WeatherService 是 wsimport 生成的服务接口
            WeatherService service = new WeatherService();
            // 2. 获取服务端口 (Port)
            // WeatherServiceSoap 是 wsimport 生成的包含具体业务方法的接口
            WeatherServiceSoap port = service.getWeatherServiceSoap();
            // 3. 调用远程方法
            // 假设 WSDL 中定义了一个 getCityWeather 方法,接受一个城市名,返回一个天气信息对象
            String cityName = "北京";
            GetCityWeatherResponse response = port.getCityWeather(cityName);
            // 4. 处理响应
            // GetCityWeatherResult 是 wsimport 生成的响应对象
            if (response != null && response.getGetCityWeatherResult() != null) {
                String weatherInfo = response.getGetCityWeatherResult();
                System.out.println("城市: " + cityName);
                System.out.println("天气信息: " + weatherInfo);
            } else {
                System.out.println("获取天气信息失败,响应为空。");
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("调用 SOAP 服务时发生错误: " + e.getMessage());
        }
    }
}

注意事项

  • 依赖wsimport 生成的代码依赖于标准的 Java SE 库,如 javax.xml.*jakarta.xml.*(取决于你的 JDK 版本),所以通常不需要额外添加 Maven/Gradle 依赖。
  • 网络代理:如果你的服务需要通过代理服务器访问,可能需要配置 JVM 参数:
    -Dhttp.proxyHost=your_proxy_host
    -Dhttp.proxyPort=your_proxy_port
    -Dhttps.proxyHost=your_proxy_host
    -Dhttps.proxyPort=your_proxy_port
  • 超时设置:对于长时间运行的服务,可以设置连接和读取超时。
    // 在获取 port 之后,设置超时时间(单位:毫秒)
    ((BindingProvider) port).getRequestContext().put(
        "javax.xml.ws.client.connectionTimeout", 5000);
    ((BindingProvider) port).getRequestContext().put(
        "javax.xml.ws.client.receiveTimeout", 10000);

调用 RESTful WebService

RESTful 服务本质上是 HTTP 服务,调用它就是发送 HTTP 请求并处理响应,在 Java 中,有多种 HTTP 客户端库可以使用。

方案 A:使用 HttpURLConnection (JDK 内置)

这是最基础的方式,无需任何第三方库,但代码比较繁琐。

示例代码:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class JdkHttpURLConnectionClient {
    public static void main(String[] args) {
        // 目标 API 地址,例如一个获取用户信息的 REST API
        String apiUrl = "https://jsonplaceholder.typicode.com/users/1";
        try {
            // 1. 创建 URL 对象
            URL url = new URL(apiUrl);
            // 2. 打开连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            // 3. 设置请求方法
            connection.setRequestMethod("GET");
            // 4. 设置请求头
            connection.setRequestProperty("Accept", "application/json");
            connection.setRequestProperty("User-Agent", "MyJavaApp/1.0");
            // 5. 获取响应码
            int responseCode = connection.getResponseCode();
            System.out.println("Response Code: " + responseCode);
            if (responseCode == HttpURLConnection.HTTP_OK) { // 200
                // 6. 读取响应数据
                BufferedReader in = new BufferedReader(
                        new InputStreamReader(connection.getInputStream()));
                String inputLine;
                StringBuilder response = new StringBuilder();
                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();
                // 7. 打印结果
                System.out.println("API Response: " + response.toString());
            } else {
                System.out.println("GET request failed.");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

方案 B:使用 Apache HttpClient (推荐)

Apache HttpClient 是一个功能强大、稳定且成熟的 HTTP 客户端库,是目前 Java 开发中的事实标准。

添加 Maven 依赖:

<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.3.1</version> <!-- 使用最新版本 -->
</dependency>

示例代码:

import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.net.URIBuilder;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class ApacheHttpClientExample {
    public static void main(String[] args) {
        // 1. 创建 HttpClient 实例
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            // 2. 创建 HTTP GET 请求
            // 使用 URIBuilder 可以方便地处理 URL 参数
            URI uri = new URIBuilder("https://jsonplaceholder.typicode.com/posts")
                    .addParameter("userId", "1")
                    .build();
            HttpGet request = new HttpGet(uri);
            request.addHeader("Accept", "application/json");
            request.addHeader("User-Agent", "MyJavaApp/1.0");
            // 3. 执行请求并获取响应
            try (CloseableHttpResponse response = httpClient.execute(request)) {
                // 4. 获取响应实体
                HttpEntity entity = response.getEntity();
                // 5. 打印响应状态码
                System.out.println("Response Code: " + response.getCode());
                if (entity != null) {
                    // 6. 将响应实体内容转换为字符串
                    String result = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                    System.out.println("API Response: " + result);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

方案 C:使用 OkHttp (流行)

OkHttp 是另一个非常流行的 HTTP 客户端,以其高效和简洁的 API 而闻名,尤其常用于 Android 开发。

添加 Maven 依赖:

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.12.0</version> <!-- 使用最新版本 -->
</dependency>

示例代码:

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
public class OkHttpExample {
    public static void main(String[] args) {
        // 1. 创建 OkHttpClient 实例
        OkHttpClient client = new OkHttpClient();
        // 2. 创建 Request 对象
        Request request = new Request.Builder()
                .url("https://jsonplaceholder.typicode.com/users/1")
                .addHeader("Accept", "application/json")
                .addHeader("User-Agent", "MyJavaApp/1.0")
                .build();
        // 3. 同步执行请求
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response);
            }
            // 4. 获取并打印响应体
            String responseBody = response.body().string();
            System.out.println("API Response: " + responseBody);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

总结与选择

场景 推荐方案 优点 缺点
调用 SOAP 服务 JAX-WS (wsimport) 标准化、代码生成、类型安全、面向对象 依赖 WSDL、相对“重量级”
调用 RESTful 服务 Apache HttpClient 功能全面、稳定、高度可配置、社区成熟 API 相对 OkHttp 稍显复杂
OkHttp API 简洁、性能高、支持异步、对现代网络友好 功能比 HttpClient 略少
简单快速调用 (SE) JDK HttpURLConnection 无需依赖、轻量 代码繁琐、功能有限

给你的建议:

  1. 明确你调用的服务是 SOAP 还是 RESTful。 这是决定你使用哪种技术的第一步。
  2. 如果是 SOAP,直接使用 wsimport 生成客户端,这是最标准、最可靠的方式。
  3. 如果是 RESTful
    • 企业级 Java 后端项目中,Apache HttpClient 是一个非常稳妥和强大的选择。
    • 如果你希望代码更简洁,或者项目涉及异步调用OkHttp 是一个极佳的选择。
    • 如果只是做一个简单的测试或脚本,且不想引入第三方库,可以考虑使用 HttpURLConnection

如果你使用的是 Spring Boot 框架,情况会更简单,因为 Spring 提供了 RestTemplate (已不推荐) 和 WebClient (推荐,支持响应式编程) 这两个强大的 HTTP 客户端,它们内部也使用了像 OkHttp 或 Apache HttpClient 这样的库,并对它们进行了优秀的封装。

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