有一批查詢介面,只有引數,返回值,介面地址不通,如何抽象出通用的呼叫方式呢?
分析一下,每個介面返回型別不一樣,我想到了泛型,引數,介面地址不一樣,可以通過引數區分。於是先定義一個帶泛型的介面
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方法即可。隱藏了呼叫細節,不必拷貝重複的程式碼。(程式碼刪除了註釋部分,避免不必要的隱私洩露)。