请求三方http工具

请求三方接口工具封装

实现逻辑:

  1. 发起请求,输入基本请求信息:请求地址,请求类型,请求参数,是否需要认证
  2. 工具自动为需要添加认证的请求添加认证,如果发现token快要过期或返回的错误编码为定义的认证失败code,则自动重新获取token重新请求
java 复制代码
package com.xxx;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.Method;
import com.alibaba.fastjson.JSON;
import lombok.Data;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;


/**
 * GeneralRequest
 * 通用请求
 *
 * @author cd
 * @date 2024/12/18 10:51
 */
@Data
public class GeneralRequest {
    /**
     * 请求路径
     */
    private String url;
    /**
     * 方法类型
     */
    private Method method;
    /**
     * 请求头
     */
    private Map<String, String> headers;
    /**
     * form表单类型参数
     */
    private Map<String, Object> form;
    /**
     * 请求体body
     */
    private String body;
    /**
     * 是否需要鉴权
     */
    private Boolean needAuth;
    /**
     * http请求工具
     */
    private HttpRequest httpRequest;


    public GeneralRequest(String url, Method method, Boolean needAuth) {
        this.url = url;
        this.method = method;
        this.form = new HashMap<>();
        this.headers = new HashMap<>();
        this.needAuth = Objects.equals(needAuth, true);
        this.httpRequest = HttpRequest.of(url).method(method);
    }

    public GeneralRequest body(String body) {
        this.body = body;
        this.httpRequest.body(body);
        return this;
    }

    public GeneralRequest form(Map<String, Object> form) {
        this.form = form;
        this.httpRequest.form(form);
        return this;
    }

    public GeneralRequest addHeader(String name, String value) {
        this.headers.put(name, value);
        this.httpRequest.header(name, value);
        return this;
    }

    public String getParameter() {
        if (StrUtil.isNotBlank(this.body)) {
            return this.body;
        }
        if (CollUtil.isNotEmpty(this.form)) {
            return JSON.toJSONString(this.form);
        }
        return "";
    }
}
java 复制代码
package com.xxx;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.Method;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * XxxHttpUtil
 *
 * @author cd
 * @date 2024/12/18 13:46
 */
@Slf4j
public class XxxHttpUtil {

    private TokenResponse cacheTokenResponse = null;

    /**
     * 获取token
     *
     * @param refreshToken 刷新token
     * @return
     */
    public TokenResponse getToken(boolean refreshToken) {
        TokenResponse tokenResponse = null;
        if (!refreshToken) {
            tokenResponse = this.cacheTokenResponse;
        }
        if (tokenResponse != null) {
            return tokenResponse;
        }

//        模拟重新获取token
        BaseRes<TokenResponse> baseRes = executeFrom("http://localhost:8080/getToken", Method.GET, false, null, new TypeReference<>() {
        });

        tokenResponse = baseRes.getData();
        this.cacheTokenResponse = tokenResponse;
        return tokenResponse;
    }

    public String signRequest(GeneralRequest generalRequest, boolean refreshToken) {
        TokenResponse tokenResponse = null;
        if (generalRequest.getNeedAuth()) {
            tokenResponse = getToken(refreshToken);
//            判断token是否快过期
            if (LocalDateTime.now().plusSeconds(10).isAfter(tokenResponse.getExpiresTime())) {
                tokenResponse = getToken(true);
            }
//            添加认证请求头
            generalRequest.addHeader("Authorization", tokenResponse.getAccessToken());
        }

        HttpResponse httpResponse = generalRequest.getHttpRequest().execute();
        int httpResponseStatus = httpResponse.getStatus();
        boolean success = httpResponseStatus == HttpStatus.HTTP_OK;
        String result = null;
        if (success) {
            result = httpResponse.body();
        }
        log.info("接口调用记录,HttpStatusCode:{},请求是否成功:{},请求地址:{},参数:{},结果:{}",
            httpResponseStatus, success ? "成功" : "失败", generalRequest.getUrl(), generalRequest.getParameter(), result);
        return result;
    }

    public <R> R doAction(GeneralRequest generalRequest, TypeReference<R> type) {
        String result = signRequest(generalRequest, false);
//        按三方返回格式判断,一般返回有code、success、data
        if (StrUtil.contains(result, "code")) {
            JSONObject jsonObject = JSON.parseObject(result);
            String code = jsonObject.getString("code");
//            200:成功
            if (StrUtil.equals(code, "200")) {
                return JSON.parseObject(result, type);
            }
//            200:鉴权失败
//            刷新token重试
            else if (StrUtil.equals(code, "500")) {
                result = signRequest(generalRequest, true);
                if (StrUtil.isNotBlank(result)) {
                    return JSON.parseObject(result, type);
                }
            } else {
                return JSON.parseObject(result, type);
            }
        }
        return null;
    }

    public <R> R execute(String url, Method method, Boolean needAuth, String body, Map<String, Object> formParams, TypeReference<R> type) {
        GeneralRequest generalRequest = new GeneralRequest(url, method, needAuth);
        if (body != null) {
            generalRequest.body(body);
        }
        if (formParams != null) {
            generalRequest.form(formParams);
        }
        return doAction(generalRequest, type);
    }

    public <R> R executeJson(String url, Method method, String body, TypeReference<R> type) {
        return this.execute(url, method, true, body, null, type);
    }

    public <R> R executeJson(String url, Method method, Boolean needAuth, String body, TypeReference<R> type) {
        return this.execute(url, method, needAuth, body, null, type);
    }

    public <R> R executeFrom(String url, Method method, Boolean needAuth, Map<String, Object> formParams, TypeReference<R> type) {
        return this.execute(url, method, needAuth, null, formParams, type);
    }

    public <R> R executeFrom(String url, Method method, Map<String, Object> formParams, TypeReference<R> type) {
        return this.execute(url, method, true, null, formParams, type);
    }
}
java 复制代码
package com.xxx;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

/**
 * TokenResponse
 *
 * @author cd
 * @date 2024/12/18 13:50
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TokenResponse {
    /**
     * token
     */
    private String accessToken;
    /**
     * 过期时间
     */
    private LocalDateTime expiresTime;
}
相关推荐
范什么特西43 分钟前
回答网络-01
网络
rockingdingo2 小时前
Codex Claude 智能体做3D/潮玩/IP设计——装上Craftsman Agent工匠智能体Skills 游泳男孩IP案例分享
网络协议·tcp/ip·3d
Zenova EdgeOS2 小时前
工业网关心跳机制:从 Keepalive 到健康判定的工程实战
大数据·网络·数据库·边缘计算·工业网关
泡海椒3 小时前
告别手写 HTTP 模板!JQuick-Curl:直接把 curl 命令跑在 Java 中
java·网络协议·http
郝学胜-神的一滴3 小时前
Effective Python 条款4:字符串格式化大乱斗
开发语言·网络·python·程序人生·软件工程
云絮.4 小时前
网络编程套接字
网络
AI备忘录4 小时前
(十六)GRE/IPSec 隧道配置命令五厂商对照:华为 华三 锐捷 迈普 思科
运维·服务器·网络·网络协议·网络安全·华为
2601_967659894 小时前
芯片设计企业DMS落地实践:昂宝电子如何用八骏管好“代理-价格-订单-库存-费控-分析“全链路
网络
实心儿儿4 小时前
Linux —— 数据链路层
linux·网络·智能路由器
牛马工作号5 小时前
大二层组网技术详解:VXLAN、GRETAP 等
网络·网络协议·安全·arp·大二层网络