业务场景: 跨系统业务数据同步的时候,需要调用三方系统的api,此时为了代码复用,想要设计一个较为通用的方法,这个方法有固定的步骤,但是具体执行的业务逻辑是不相同的,所以就需要用到函数式接口,传递方法来进行方法复用
待复用方法的执行过程如下:
public static String sendDataRequest(Map<String, Object> headerParam, FunInterfaceSelf funInterfaceSelf) {
// 第一步(固定):发送请求;查询token
if (CollUtil.isEmpty(headerParam)) {
String token = "abcccc";
System.out.println("第一步(固定):获取token,1.1 查询token");
headerParam = new HashMap<>(1);
headerParam.put("token", token);
} else {
System.out.println("第一步(固定):获取token,1.2 传入的token");
}
System.out.println("\r\n------------------------执行业务请求start----------------------------");
// todo 第二步(灵活):判断;解析三方系统的响应结果,如果是200,
System.out.println("------------------------执行业务请求end----------------------------\r\n");
// 第三步(固定):发送请求记录到mysql中,便于排查
System.out.println("第三步(固定):存入数据库请求记录:" + JSONUtil.toJsonStr(apiLogData));
return null;
}
第一思路就是利用函数式接口,将不同的业务执行判断逻辑进行传入,在调用的地方书写逻辑,最后思路大致如下,函数式接口可以理解为实现类的方法调用。
最终的代码版本如下:
package com.lzq.learn.test.测试函数式编程;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* @author 刘志强
* @date 2023/12/2 10:30
*/
public class FunctionalTest {
public static void main(String[] a) {
HashMap<String, Object> tokenParam = new HashMap<>(1);
tokenParam.put("token", "lzq123456");
sendDataRequest(tokenParam, (headerParam) -> {
// 1.处理参数
String address = "http://abc.com/addStudent";
String requestMethod = "get";
String requestData = null;
String requestHeader = Optional.ofNullable(headerParam).map(JSONUtil::toJsonStr).orElse(null);
String response = "添加成功";
String createTime = LocalDateTime.now().toString();
String result = String.format("请求方式 %s, 地址ulr %s, 请求头 %s, 请求数据 %s, 响应结果 %s, 请求时间 %s", requestMethod, address, requestHeader, requestData, response, createTime);
// 2.执行调用
System.out.println("执行调用 , 执行过程为 = " + result);
// 3.返回需要记录的日志结果
return ApiLogData.builder()
.apiAddress(address)
.apiRequestMethod(requestMethod)
.apiRequestData(requestData)
.apiResponse(response)
.creatTime(createTime)
.build();
});
}
/**
* <p>@Description: 公共方法,统一入口</p >
* <p>@param [bodyParam, funInterfaceSelf]</p >
* <p>@return java.lang.String</p >
* <p>@throws </p >
* <p>@author LiuZhiQiang</p >
* <p>@date 2023/12/2 11:31</p >
*/
public static String sendDataRequest(Map<String, Object> headerParam, FunInterfaceSelf funInterfaceSelf) {
// 第一步(固定):发送请求;查询token
if (CollUtil.isEmpty(headerParam)) {
String token = "abcccc";
System.out.println("第一步(固定):获取token,1.1 查询token");
headerParam = new HashMap<>(1);
headerParam.put("token", token);
} else {
System.out.println("第一步(固定):获取token,1.2 传入的token");
}
System.out.println("\r\n------------------------执行业务请求start----------------------------");
// 第二步(灵活):判断;解析三方系统的响应结果,如果是200,
ApiLogData apiLogData = funInterfaceSelf.sendSelfApi(headerParam);
System.out.println("------------------------执行业务请求end----------------------------\r\n");
// 第三步(固定):发送请求记录到mysql中,便于排查
System.out.println("第三步(固定):存入数据库请求记录:" + JSONUtil.toJsonStr(apiLogData));
return null;
}
}
@FunctionalInterface
interface FunInterfaceSelf {
/**
* 执行不同的业务请求,我不关心具体的逻辑,只要返回给我对应的请求日志信息即可,我要记录入库
*
* @return
*/
public abstract ApiLogData sendSelfApi(Map<String, Object> headerParam);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
class ApiLogData {
private String apiAddress;
private String apiRequestMethod;
private String apiHeaderParam;
private String apiRequestData;
private String apiResponse;
private String creatTime;
}
调用结果: