通用查询的抽象

有一批查询接口,只有参数,返回值,接口地址不通,如何抽象出通用的调用方式呢?

分析一下,每个接口返回类型不一样,我想到了泛型,参数,接口地址不一样,可以通过参数区分。于是先定义一个带泛型的接口

public interface CommonQueryService<T> {
    /**
     * 通用查询
     * @param requestDto 请求dto
     * @param apiUrl  请求地址
     * @param msg 日志消息表示
     * @return 查询返回对象
     * @throws InvalidCipherTextException
     */
    GenericReturnObject<List<T>> commonQuery(Object requestDto,String apiUrl, String msg)  throws InvalidCipherTextException;
}

谁来实现它呢?我定义一个实现类吧

@Slf4j
public abstract class CommonQueryServiceImpl<T> implements CommonQueryService<T> {
    @Autowired
    private BusinessCenterTokenHelper businessCenterTokenHelper;
    @Autowired
    private EpServiceConfig epServiceConfig;
    protected String returnJson;
    public GenericReturnObject<List<T>> commonQuery(Object requestDto,String apiUrl,String msg) throws InvalidCipherTextException {
        String jsonBody = com.alibaba.fastjson.JSON.toJSONString(requestDto);
        long date = System.currentTimeMillis();
        log.info("esServiceConfig:{}", com.alibaba.fastjson.JSON.toJSONString(epServiceConfig));
        String appPubKey = epServiceConfig.getApp().getPubkey() ;
        log.info("appPubKey:{}",appPubKey);
        String  token = businessCenterTokenHelper.getToken();
        log.info("token:{}",token);
        String signature = EncryptUtil.sign("POST" + '\n' + date + '\n'+ token + '\n' + appPubKey +'\n'+ jsonBody);
        log.info("signature:{}",signature);
        String dateX = String.valueOf(date);
        log.info("dataX:{}",dateX);
        EPRequestCaller caller = null;
        try {
            caller = EPRequestCaller.newBuilder(apiUrl)
                    .token(token)
                    .apiVersion(epServiceConfig.getApp().getVersion())
                    .clientId(epServiceConfig.getClient().getId())
                    .putHeadParamsMap("x-date", dateX)
                    .putHeadParamsMap("x-token",token)
                    .putHeadParamsMap("x-signature",signature)
                    .appPubKey(appPubKey);
            caller.setContentBody(jsonBody);
            this.returnJson = caller.doPost();
            GenericReturnObject<List<T>> returnObject = convertJson(returnJson);
            log.info(">>>>>>>>>>>>>>>>>>>>>>>>>{},返回:{}>>>>>>>>>>>>>>>>>>>>>",msg, com.alibaba.fastjson.JSON.toJSONString(returnObject));
            return returnObject;
        } catch (HttpCallerException e) {
            log.error("msg:{} 失败:{}",msg,e);
            GenericReturnObject genericReturnObject = new GenericReturnObject();
            genericReturnObject.setErrors(e.getMessage());
            return genericReturnObject;
        } catch (Exception e) {
            log.error("msg:{}.e:{}",msg,e);
            GenericReturnObject genericReturnObject = new GenericReturnObject();
            genericReturnObject.setErrors(e.getMessage());
            return genericReturnObject;
        }
    }

    /**
     * 中台返回的json转换为json对象,由子类实现
     * @param json
     * @return 返回对象
     */
    public abstract GenericReturnObject<List<T>> convertJson(String json);

大家看到这是一个抽象类,本来不打算用抽象类的,奈何JSON转对象的时候,不支持泛型的转换,于是定义为抽象类,再定义一个抽象方法 convertJson,把转换的工作交给子类来实现,这样就不涉及JSON转泛型对象的问题了。

对于不同的查询,再定义不用的实现类继承上述抽象类,并实现通用查询接口。下面举2个例子。

@Service("commonQueryServiceFire")
public class CommonQueryServiceFireImpl<FireInfoDto> extends CommonQueryServiceImpl<FireInfoDto> implements CommonQueryService<FireInfoDto> {
    @Override
    public GenericReturnObject<List<FireInfoDto>> commonQuery(Object requestDto, String apiUrl,String msg) throws InvalidCipherTextException {
        GenericReturnObject<List<FireInfoDto>> listGenericReturnObject = super.commonQuery(requestDto, apiUrl,msg);
        return listGenericReturnObject;
    }

    @Override
    public GenericReturnObject<List<FireInfoDto>> convertJson(String json) {
            GenericReturnObject<List<FireInfoDto>> returnObject = com.alibaba.fastjson.JSON.parseObject(returnJson,
                new TypeReference<GenericReturnObject<List<FireInfoDto>>>(){});
        return returnObject;
    }
}
@Service("commonQueryServiceFireReport")
public class CommonQueryServiceFireReport<ForecastReportDto> extends CommonQueryServiceImpl<ForecastReportDto> implements CommonQueryService<ForecastReportDto> {
    @Override
    public GenericReturnObject<List<ForecastReportDto>> commonQuery(Object requestDto, String apiUrl,String msg) throws InvalidCipherTextException {
        GenericReturnObject<List<ForecastReportDto>> listGenericReturnObject = super.commonQuery(requestDto, apiUrl,msg);
        return listGenericReturnObject;
    }

    @Override
    public GenericReturnObject<List<ForecastReportDto>> convertJson(String json) {
            GenericReturnObject<List<ForecastReportDto>> returnObject = com.alibaba.fastjson.JSON.parseObject(returnJson,
                new TypeReference<GenericReturnObject<List<ForecastReportDto>>>(){});
        return returnObject;
    }
}

controller调用端

@Resource(name = "commonQueryServiceFire")
private CommonQueryService commonQueryServiceFire;
@Resource(name = "commonQueryServiceFireReport")
private CommonQueryService commonQueryServiceFireReport;
 
@PostMapping("/environCenter/fire/fireRealData")
public GenericReturnObject fireRealData(String date,
String fireCode ) throws Exception {
FireRealDataReqDto fireRealDataReqDto = new FireRealDataReqDto();
fireRealDataReqDto.setFireCode(fireCode);
fireRealDataReqDto.setDate(date);
GenericReturnObject<List<FireInfoDto>> listGenericReturnObject = commonQueryServiceFire.commonQuery(fireRealDataReqDto,
"/environCenter/fire/fireRealData",
"查询xxx信息");
return listGenericReturnObject;
}

@PostMapping("/environCenter/fire/fireReport")
public GenericReturnObject fireReport(String date ) throws Exception {
date );
FireReportReqDto fireReportReqDto = new FireReportReqDto();
fireReportReqDto.setDate(date);
GenericReturnObject<List<ForecastReportDto>> listGenericReturnObject = commonQueryServiceFireReport.commonQuery(fireReportReqDto,
"/environCenter/fire/fireReport",
"yyy查询");
return listGenericReturnObject;
}

 新增不用的查询,需要增加新的实现类,参数dto,返回dto,调用方注入实现类,调用commonQuery方法即可。隐藏了调用细节,不必拷贝重复的代码。(代码删除了注释部分,避免不必要的隐私泄露)。

posted @ 2022-07-09 19:56  孙工的编程生涯  阅读(192)  评论(0编辑  收藏  举报