Java调用第三方接口、http请求详解,一文学会

Java 调用第三方接口的封装方法详解

在开发企业级应用时,调用第三方接口是非常常见的场景。我们可能需要与外部服务集成,如支付接口、短信接口、天气服务接口等。为了提高代码的可维护性、复用性和易扩展性,封装第三方接口调用的方法非常重要。

本文将详细介绍如何封装一个 Java 调用第三方接口的通用方法,确保代码具有良好的可读性和扩展性。


1. 第三方接口调用的基本步骤

在 Java 中调用第三方接口通常包含以下几个步骤:

  1. 确定接口 URL:通常接口会提供一个 HTTP/HTTPS 的 URL。
  2. 传递请求参数 :使用 GET 或 POST 方法,根据接口文档发送请求参数。
  3. 发送请求 :使用 HttpClient 或 HttpURLConnection 发送 HTTP 请求。
  4. 处理响应:接收并处理返回的 JSON 或 XML 格式的数据。
  5. 异常处理:捕获和处理网络错误或接口返回的错误。

为了使接口调用的代码更加通用化、简洁化,我们可以通过封装来减少重复代码和提升代码复用性。


2. Java HttpClient 简介

在 Java 11 之后,官方推出了 HttpClient 作为原生的 HTTP 请求工具,替代了旧的 HttpURLConnection。相比 HttpURLConnection,HttpClient 提供了更现代化的 API,且支持同步和异步请求。

引入依赖

如果使用的是 Java 11 及其以上版本,HttpClient 已经内置,无需额外依赖。如果你使用的是 Java 8 或之前的版本,则可以使用 Apache HttpClient 或 OkHttp。


3. 封装第三方接口的步骤

我们将以一个常见的 POST 请求为例,封装一个通用的第三方接口调用方法。此方法将支持:

  • GET 和 POST 请求。
  • 传递请求头和请求体。
  • 处理 JSON 响应。
第一步:定义工具类

首先,我们定义一个工具类 HttpUtils,封装通用的 HTTP 请求方法。

java 复制代码
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;

public class HttpUtils {

    private static final HttpClient httpClient = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10)) // 设置连接超时
            .build();
    
    private static final ObjectMapper objectMapper = new ObjectMapper(); // 用于处理JSON

    /**
     * 发送GET请求
     * @param url 请求的URL地址
     * @param headers 请求头的Map集合
     * @return 返回响应的结果,JSON格式
     * @throws Exception 请求失败时抛出异常
     */
    public static String sendGet(String url, Map<String, String> headers) throws Exception {
        // 创建GET请求
        HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(10)) // 请求超时时间
                .GET();

        // 设置请求头
        if (headers != null) {
            headers.forEach(requestBuilder::header);
        }

        HttpRequest request = requestBuilder.build();

        // 发送请求并获取响应
        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

        // 判断响应状态码
        if (response.statusCode() == 200) {
            return response.body(); // 返回响应体
        } else {
            throw new RuntimeException("GET请求失败,状态码: " + response.statusCode());
        }
    }

    /**
     * 发送POST请求
     * @param url 请求的URL地址
     * @param headers 请求头的Map集合
     * @param requestBody 请求体,可以是JSON格式的字符串
     * @return 返回响应的结果,JSON格式
     * @throws Exception 请求失败时抛出异常
     */
    public static String sendPost(String url, Map<String, String> headers, String requestBody) throws Exception {
        // 创建POST请求
        HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(10)) // 请求超时时间
                .POST(HttpRequest.BodyPublishers.ofString(requestBody)); // 设置请求体

        // 设置请求头
        if (headers != null) {
            headers.forEach(requestBuilder::header);
        }

        HttpRequest request = requestBuilder.build();

        // 发送请求并获取响应
        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

        // 判断响应状态码
        if (response.statusCode() == 200) {
            return response.body(); // 返回响应体
        } else {
            throw new RuntimeException("POST请求失败,状态码: " + response.statusCode());
        }
    }

    /**
     * 将对象转换为JSON字符串
     * @param obj 需要转换的对象
     * @return 对象的JSON格式字符串
     * @throws Exception 转换失败时抛出异常
     */
    public static String convertObjectToJson(Object obj) throws Exception {
        return objectMapper.writeValueAsString(obj);
    }

    /**
     * 将JSON字符串转换为指定类型的对象
     * @param json JSON字符串
     * @param clazz 转换后的对象类型
     * @param <T> 泛型
     * @return 转换后的对象
     * @throws Exception 转换失败时抛出异常
     */
    public static <T> T convertJsonToObject(String json, Class<T> clazz) throws Exception {
        return objectMapper.readValue(json, clazz);
    }
}
代码说明:
  1. HttpClient:这是 Java 11 引入的 HTTP 客户端,用于发送 HTTP 请求。我们将其设置为 10 秒的连接超时。
  2. GET 请求 :sendGet() 方法用于发送 GET 请求,并接受一个 URL 和请求头。
  3. POST 请求 :sendPost() 方法用于发送 POST 请求,接受 URL、请求头和请求体(通常为 JSON 格式的字符串)。
  4. JSON 处理 :ObjectMapper 用于将对象与 JSON 字符串之间相互转换,便于发送和解析 JSON 格式数据。

4. 使用封装方法调用第三方接口

封装好工具类后,我们可以通过简单的调用来处理第三方接口请求。假设我们要调用一个天气服务的 API,获取指定城市的天气数据。

调用示例
java 复制代码
import java.util.HashMap;
import java.util.Map;

public class WeatherService {

    // 示例:获取天气信息
    public static void getWeather(String cityName) {
        String url = "https://api.weather.com/v3/wx/conditions/current"; // 第三方API的URL

        // 请求头信息
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        headers.put("Authorization", "Bearer your_api_key");

        try {
            // 调用GET请求
            String response = HttpUtils.sendGet(url + "?city=" + cityName, headers);

            // 解析返回的JSON结果
            WeatherResponse weather = HttpUtils.convertJsonToObject(response, WeatherResponse.class);

            // 打印天气信息
            System.out.println("当前温度:" + weather.getTemperature());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        // 调用获取天气的方法
        getWeather("Beijing");
    }
}

// WeatherResponse 类用于接收解析后的 JSON 响应
class WeatherResponse {
    private double temperature;

    public double getTemperature() {
        return temperature;
    }

    public void setTemperature(double temperature) {
        this.temperature = temperature;
    }
}
代码说明:
  1. 请求头 :我们设置了 Content-Type 和 Authorization 请求头,用于标识请求的数据格式和认证信息。
  2. 调用工具类方法 :通过 HttpUtils.sendGet() 发送 GET 请求,并将响应结果转换为自定义的 WeatherResponse 对象。
  3. 解析 JSON :HttpUtils.convertJsonToObject() 将返回的 JSON 字符串转换为 Java 对象。

5. 错误处理与重试机制

在实际项目中,第三方接口调用可能会出现超时、网络故障等问题。为了提高接口调用的稳定性,通常会增加错误处理和重试机制。我们可以在封装的工具类中添加重试逻辑:

java 复制代码
public static String sendGetWithRetry(String url, Map<String, String> headers, int maxRetries) throws Exception {
    int retryCount = 0;
    while (retryCount < maxRetries) {
        try {
            return sendGet(url, headers); // 尝试发送请求
        } catch (Exception e) {
            retryCount++;
            if (retryCount >= maxRetries) {
                throw new RuntimeException("GET请求失败,重试次数:" + retryCount, e);
           

 }
            System.out.println("请求失败,正在重试...(" + retryCount + ")");
            Thread.sleep(1000); // 暂停一秒再重试
        }
    }
    return null;
}

6. 总结

封装第三方接口的调用不仅可以提高代码的复用性,还能降低出错的概率。在本文中,我们使用 Java 11 的 HttpClient 封装了 GET 和 POST 请求的通用方法,并提供了 JSON 的处理能力。通过这种方式,你可以轻松地调用和扩展任何第三方 API,适用于各种应用场景。

希望通过这篇文章,大家能学会如何封装第三方接口调用方法,并将其应用到实际项目中。

相关推荐
小羊没烦恼!4 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
俊昭喜喜里4 天前
java中的继承和多态的区别
java
小羊没烦恼!4 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
譕痕4 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码4 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖4 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时4 天前
01-06-A-JVM排查实战详解
java·jvm
伞伞悦读4 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
vipxieliang4 天前
ValidX 在 DDD 领域驱动设计中的实践
java·spring boot
C语言小火车4 天前
C/C++ 为什么需要编译器?
开发语言·c++