数据对接 模板设计模式的使用

ops/2024/10/22 2:44:54/

与上游系统常有数据对接的需求,对接的接口在入参 返回值 数据处理逻辑上常有一定的规律性,使用模板方法 可以减少样本代码 提高代码效率
这里给出一个示例

同步上游系统的账号 组织(业务方请求接口)

抽象类

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.ContentType;
import cn.hutool.http.Header;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;@Slf4j
public abstract class AbstractSync<T,K extends ServiceImpl<? extends BaseMapper<T>,T>> {@Value("${xxx}")private String appId;@Value("${xxx}")private String appSecret;abstract protected void sync();abstract protected String getReqUrl();abstract protected String getCallbackUrl();abstract protected String getReqFailedMsg();abstract protected String getCallbackFailedMsg();abstract protected Class<T> entityClass();abstract protected K getBaseService();abstract protected Function<T,Date> sortFunc();abstract protected SFunction<T,String> bizIdFunc();abstract protected Function<T,String> callbackIdFunc();public void doSync() {JSONArray dataJsonArray = new JSONArray();this.getReqData(dataJsonArray,1,100,LocalDateTime.now().plusMinutes(-30).toInstant(ZoneOffset.ofHours(8)).toEpochMilli());List<T> tList = dataJsonArray.toJavaList(this.entityClass());tList.sort(Comparator.comparing(this.sortFunc()));K baseService = this.getBaseService();tList.forEach(t -> {T existedT = baseService.lambdaQuery().eq(this.bizIdFunc(), this.bizIdFunc().apply(t)).one();if(Objects.nonNull(existedT)){baseService.lambdaUpdate().eq(this.bizIdFunc(),this.bizIdFunc().apply(t)).update(t);}else{baseService.save(t);}});this.callback(tList,this.callbackIdFunc());}public void callback(List<T> tList, Function<T,String> func){if(CollectionUtil.isNotEmpty(tList)){String ids = tList.stream().map(func).collect(Collectors.joining(","));JSONObject reqParamsJson = new JSONObject();reqParamsJson.put("ids",ids);String response = this.doReq(reqParamsJson,this.getCallbackUrl());String code = JSONObject.parseObject(response).getString("code");if(!"0".equals(code)){throw new RuntimeException(this.getCallbackFailedMsg());}}}public JSONArray getReqData(JSONArray dataJsonArray, Integer page, Integer pageSize, Long startTime){String response = this.request(page,pageSize,startTime);JSONObject resultJson = JSONObject.parseObject(response);JSONObject dataJson = resultJson.getJSONObject("data");String code = resultJson.getString("code");JSONArray data = dataJson.getJSONArray("list");if(!"0".equals(code)){throw new RuntimeException(this.getReqFailedMsg());}if(!data.isEmpty()){dataJsonArray.addAll(data);}if(data.size() >= pageSize){getReqData(dataJsonArray,++page,pageSize,startTime);}return dataJsonArray;}public String request(Integer page,Integer size,Long startTime){JSONObject reqParamsJson = new JSONObject();reqParamsJson.put("page",page.toString());reqParamsJson.put("size",size.toString());reqParamsJson.put("startTime",startTime.toString());return this.doReq(reqParamsJson,this.getReqUrl());}private String doReq(JSONObject reqParamsJson,String url){return HttpUtil.createPost(url).header("Authorization","Bearer "+ generateToken()).header(Header.CONTENT_TYPE, ContentType.JSON.toString()).body(reqParamsJson.toString()).execute().body();}private String generateToken(){return JWT.create().withIssuer(appId).withIssuedAt(new Date()).withJWTId(UUID.randomUUID().toString()).sign(Algorithm.HMAC256(appSecret));}}

账号同步子类

import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;
import java.util.Date;
import java.util.function.Function;@Service
@Slf4j
public class SyncAccountService extends AbstractSync<SyncAccount,SyncAccountBaseService> {@Resourceprivate SyncAccountBaseService syncAccountBaseService;@Value("${xxx}")private String reqUrl;@Value("${xxx}")private String callbackUrl;@Overrideprotected String getReqUrl() {return reqUrl;}@Overrideprotected String getCallbackUrl() {return callbackUrl;}@Overrideprotected String getReqFailedMsg() {return "调用账号同步-回调接口失败,请查看";}@Overrideprotected String getCallbackFailedMsg() {return "调用账号同步接口失败,请查看";}@Overrideprotected Class<SyncAccount> entityClass() {return SyncAccount.class;}@Overrideprotected SyncAccountBaseService getBaseService() {return syncAccountBaseService;}@Overrideprotected Function<SyncAccount, Date> sortFunc() {return SyncAccount::getRequestLogCreateTime;}@Overrideprotected SFunction<SyncAccount, String> bizIdFunc() {return SyncAccount::getAppAccountId;}@Overrideprotected Function<SyncAccount, String> callbackIdFunc() {return SyncAccount::getRequestLogId;}@Override@Transactional@Scheduled(cron = "0 */30 * * * ?")public void sync() {this.doSync();}}

组织同步子类

import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;
import java.util.Date;
import java.util.function.Function;@Service
@Slf4j
public class SyncOrgService extends AbstractSync<SyncOrg,SyncOrgBaseService> {@Resourceprivate SyncOrgBaseService syncOrgBaseService;@Value("xxx")String reqUrl;@Value("xxx")String callbackUrl;@Overridepublic String getReqUrl() {return reqUrl;}@Overridepublic String getCallbackUrl() {return callbackUrl;}@Overridepublic String getReqFailedMsg() {return "调用组织同步-回调接口失败,请查看";}@Overridepublic String getCallbackFailedMsg() {return "调用组织同步接口失败,请查看";}@Overrideprotected Class<SyncOrg> entityClass() {return SyncOrg.class;}@Overrideprotected SyncOrgBaseService getBaseService() {return syncOrgBaseService;}@Overrideprotected Function<SyncOrg, Date> sortFunc() {return SyncOrg::getRequestLogCreateTime;}@Overrideprotected SFunction<SyncOrg, String> bizIdFunc() {return SyncOrg::getIdtOrgId;}@Overrideprotected Function<SyncOrg, String> callbackIdFunc() {return SyncOrg::getRequestLogId;}@Override@Transactional@Scheduled(cron = "0 */30 * * * ?")public void sync() {this.doSync();}}

模板方法还有一个典型运用场景 AQS(抽象队列同步器)


http://www.ppmy.cn/ops/118934.html

相关文章

深入浅出MongoDB(三)

深入浅出MongoDB&#xff08;三&#xff09; 文章目录 深入浅出MongoDB&#xff08;三&#xff09;复制副本集设置分片分片实例备份与恢复监控ObjectId 复制 复制时将数据同步在多个服务器的过程&#xff0c;提供了数据的冗余备份&#xff0c;在多个服务器上存储数据副本&#…

【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【上篇】

【STM32开发笔记】移植AI框架TensorFlow到STM32单片机【上篇】 一、TFLM是什么&#xff1f;二、TFLM开源项目2.1 下载TFLM源代码2.2 TFLM基准测试说明2.3 TFLM基准测试命令 三、TFLM初步体验3.1 PC上运行Keyword基准测试3.2 PC上运行Person detection基准测试3.3 No module nam…

企微软件:重塑企业沟通与管理的新生态

在数字化转型的浪潮中&#xff0c;企业沟通与管理方式正经历着前所未有的变革。企微软件&#xff0c;作为这一变革中的佼佼者&#xff0c;以其强大的功能、灵活的部署和卓越的用户体验&#xff0c;正逐步成为企业提升运营效率、优化内部沟通、促进团队协作的重要工具。本文将深…

【Wireshark笔记】通过Wireshark检测和分析TCP重传

通过Wireshark检测和分析TCP重传 在网络通信中&#xff0c;TCP重传&#xff08;TCP Retransmission&#xff09;是一种非常重要的现象&#xff0c;特别是在分析网络性能和故障排查时。重传数据包会影响网络性能&#xff0c;导致延迟增加&#xff0c;甚至引发网络拥塞等问题。为…

基于Arduino的自弹尤克里里机器人

需要项目源码资料的可以私信我 基于Arduino的自弹尤克里里机器人 一、简介二、材料清单三、工具四、实现过程步骤1&#xff1a;实物图步骤2&#xff1a;3D打印部件步骤3&#xff1a;组装上半部分步骤4&#xff1a;组装下半部分步骤5&#xff1a;安装导轨步骤6&#xff1a;设置…

Kafka和RabbitMQ比较

Kafka和RabbitMQ都是流行的消息队列系统&#xff0c;它们在分布式系统中扮演着至关重要的角色&#xff0c;用于异步消息传递和解耦应用组件。尽管它们共享一些基本的概念&#xff0c;但它们在设计目标、性能特性、使用场景等方面有着显著的差异。 设计目标 Kafka&#xff1a;Ka…

记一次教学版内网渗透流程

信息收集 如果觉得文章写的不错可以共同交流 http://aertyxqdp1.target.yijinglab.com/dirsearch dirsearch -u "http://aertyxqdp1.target.yijinglab.com/"发现 http://aertyxqdp1.target.yijinglab.com/joomla/http://aertyxqdp1.target.yijinglab.com/phpMyA…

凤凰模拟器V6中无人机如何设置“有头模式”

凤凰模拟器是一款专为航模新手设计的飞行模拟器&#xff0c;它能够模拟大疆无人机、各种穿越机、固定翼等多种飞行器&#xff0c;提供逼真的飞行体验。该软件的操作简单易懂&#xff0c;适合新手练习使用。 一般来说&#xff0c;打开凤凰模拟器&#xff0c;选择好机型&#xf…