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

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

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

抽象类

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> {

    @Resource
    private SyncAccountBaseService syncAccountBaseService;

    @Value("${xxx}")
    private String reqUrl;

    @Value("${xxx}")
    private String callbackUrl;


    @Override
    protected String getReqUrl() {
        return reqUrl;
    }

    @Override
    protected String getCallbackUrl() {
        return callbackUrl;
    }

    @Override
    protected String getReqFailedMsg() {
        return "调用账号同步-回调接口失败,请查看";
    }

    @Override
    protected String getCallbackFailedMsg() {
        return "调用账号同步接口失败,请查看";
    }

    @Override
    protected Class<SyncAccount> entityClass() {
        return SyncAccount.class;
    }

    @Override
    protected SyncAccountBaseService getBaseService() {
        return syncAccountBaseService;
    }

    @Override
    protected Function<SyncAccount, Date> sortFunc() {
        return SyncAccount::getRequestLogCreateTime;
    }

    @Override
    protected SFunction<SyncAccount, String> bizIdFunc() {
        return SyncAccount::getAppAccountId;
    }

    @Override
    protected 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> {

    @Resource
    private SyncOrgBaseService syncOrgBaseService;

    @Value("xxx")
    String reqUrl;

    @Value("xxx")
    String callbackUrl;


    @Override
    public String getReqUrl() {
        return reqUrl;
    }

    @Override
    public String getCallbackUrl() {
        return callbackUrl;
    }

    @Override
    public String getReqFailedMsg() {
        return "调用组织同步-回调接口失败,请查看";
    }

    @Override
    public String getCallbackFailedMsg() {
        return "调用组织同步接口失败,请查看";
    }

    @Override
    protected Class<SyncOrg> entityClass() {
        return SyncOrg.class;
    }

    @Override
    protected SyncOrgBaseService getBaseService() {
        return syncOrgBaseService;
    }

    @Override
    protected Function<SyncOrg, Date> sortFunc() {
        return SyncOrg::getRequestLogCreateTime;
    }

    @Override
    protected SFunction<SyncOrg, String> bizIdFunc() {
        return SyncOrg::getIdtOrgId;
    }

    @Override
    protected Function<SyncOrg, String> callbackIdFunc() {
        return SyncOrg::getRequestLogId;
    }

    @Override
    @Transactional
    @Scheduled(cron = "0 */30 * * * ?")
    public void sync() {
        this.doSync();
    }


}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值