3

通用查询的抽象 - 孙工的编程生涯

 2 years ago
source link: https://www.cnblogs.com/javaddd/p/16461757.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

通用查询的抽象

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

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

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方法即可。隐藏了调用细节,不必拷贝重复的代码。(代码删除了注释部分,避免不必要的隐私泄露)。


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK