请求三方http工具
请求三方接口工具封装
实现逻辑:
- 发起请求,输入基本请求信息:请求地址,请求类型,请求参数,是否需要认证
- 工具自动为需要添加认证的请求添加认证,如果发现token快要过期或返回的错误编码为定义的认证失败code,则自动重新获取token重新请求
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 "";
}
}
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);
}
}
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;
}