请求三方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;
}
相关推荐
Cx330❀3 分钟前
【Linux网络】打破“一问一答”局限:从零构建全双工多线程UDP群聊系统
linux·运维·服务器·网络·网络协议·udp
纳祥科技8 分钟前
音频ADC芯片基础解析:为什么计算机需要它来理解真实世界?
网络·单片机·音视频·智能音箱
学且思13 分钟前
SSE 是 HTTP/2 的服务器推送?
服务器·网络协议·http
草莓熊Lotso20 分钟前
【Linux网络】深入理解 HTTP 协议(四):完善 C++ HTTP 服务器:从协议原理到生产级实现
linux·运维·服务器·c语言·网络·c++·http
weixin_6042366725 分钟前
华为三层交换机 企业标准完整配置
网络·华为·华为交换机命令·华为三层交换机
J-Tony1126 分钟前
【计算机网络】TCP的可靠性保证
网络·tcp/ip·计算机网络
Yang961126 分钟前
煤矿 SDH/PDH 线路检修难?鼎讯 HM-G2500 手持式传输分析仪实用解析
运维·服务器·网络
逆境不可逃35 分钟前
【WebSocket 02】 握手拦截实现 Token 鉴权、Ping/Pong 心跳保活、前端断线自动重连
网络·websocket·网络协议
Seven9735 分钟前
网页为什么越来越快?一文看懂 HTTP 的三次进化
http·http3
安当加密37 分钟前
汽车OTA升级怎么保证安全?从固件签名到密钥全生命周期管理
网络·安全·汽车