Commit e2e34483 authored by 郝彦辉's avatar 郝彦辉

2020.04.29黑灰名单数据更新增加钉钉通知

parent 10fd2d1e
package cn.quantgroup.qgblservice.job.blimport; package cn.quantgroup.qgblservice.job.blimport;
import cn.quantgroup.qgblservice.constant.Constant;
import cn.quantgroup.qgblservice.constant.ConstantBlackGrey; import cn.quantgroup.qgblservice.constant.ConstantBlackGrey;
import cn.quantgroup.qgblservice.service.IBlackGreyListService; import cn.quantgroup.qgblservice.service.IBlackGreyListService;
import cn.quantgroup.qgblservice.service.IBlackListManagerService; import cn.quantgroup.qgblservice.utils.dingding.DingTalk;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -34,6 +33,8 @@ public class BlackGreyListJob { ...@@ -34,6 +33,8 @@ public class BlackGreyListJob {
@Autowired @Autowired
private IBlackGreyListService blackGreyListService; private IBlackGreyListService blackGreyListService;
@Autowired
private DingTalk dingTalk;
private Boolean increment(String key){ private Boolean increment(String key){
Long increment = redisTemplate.opsForValue().increment(key, 1); Long increment = redisTemplate.opsForValue().increment(key, 1);
...@@ -81,7 +82,7 @@ public class BlackGreyListJob { ...@@ -81,7 +82,7 @@ public class BlackGreyListJob {
if(increment(ConstantBlackGrey.REDIS_KEY.JOB_ADD_BLACK_LIST_INCREMENT_KEY)){ if(increment(ConstantBlackGrey.REDIS_KEY.JOB_ADD_BLACK_LIST_INCREMENT_KEY)){
redisTemplate.expire(ConstantBlackGrey.REDIS_KEY.JOB_ADD_BLACK_LIST_INCREMENT_KEY, 10, TimeUnit.SECONDS); redisTemplate.expire(ConstantBlackGrey.REDIS_KEY.JOB_ADD_BLACK_LIST_INCREMENT_KEY, 10, TimeUnit.SECONDS);
//yyyy-MM-dd //yyyy-MM-dd
String todayNyr = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME); String todayNyr = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE);
long statUtc = 0L; long statUtc = 0L;
//1、导入-现金分期15+逾期黑名单 约耗时65866.ms //1、导入-现金分期15+逾期黑名单 约耗时65866.ms
...@@ -94,6 +95,7 @@ public class BlackGreyListJob { ...@@ -94,6 +95,7 @@ public class BlackGreyListJob {
log.error(todayNyr+", 每天执行新增现金分期15+逾期黑名单异常", e); log.error(todayNyr+", 每天执行新增现金分期15+逾期黑名单异常", e);
}finally { }finally {
log.info(todayNyr+", 每天执行新增现金分期15+逾期黑名单结束, Msg: {} , 总耗时: {} ", xianJinDai, (System.currentTimeMillis()-statUtc)+".ms"); log.info(todayNyr+", 每天执行新增现金分期15+逾期黑名单结束, Msg: {} , 总耗时: {} ", xianJinDai, (System.currentTimeMillis()-statUtc)+".ms");
dingTalk.talkByWebHook(DingTalk.WEBHOOK_BLACKGREY, "Info", DingTalk.TITLETAGS_BLACKGREY, "导入"+todayNyr+"现金贷黑名单结束", xianJinDai);
} }
//2、导入-Vcc15+逾期黑名单 约耗时14369.ms //2、导入-Vcc15+逾期黑名单 约耗时14369.ms
...@@ -106,10 +108,11 @@ public class BlackGreyListJob { ...@@ -106,10 +108,11 @@ public class BlackGreyListJob {
log.error(todayNyr+", 每天执行新增Vcc15+逾期黑名单异常", e); log.error(todayNyr+", 每天执行新增Vcc15+逾期黑名单异常", e);
}finally { }finally {
log.info(todayNyr+", 每天执行新增Vcc15+逾期黑名单结束, Msg: {} , 总耗时: {} ", vcc, (System.currentTimeMillis()-statUtc)+".ms"); log.info(todayNyr+", 每天执行新增Vcc15+逾期黑名单结束, Msg: {} , 总耗时: {} ", vcc, (System.currentTimeMillis()-statUtc)+".ms");
dingTalk.talkByWebHook(DingTalk.WEBHOOK_BLACKGREY, "Info", DingTalk.TITLETAGS_BLACKGREY, "导入"+todayNyr+"VCC黑名单结束", vcc);
} }
//3、将逾期已还清黑名单转灰名单 耗时1206283.ms 约20分钟 //3、将逾期已还清黑名单转灰名单 耗时1206283.ms 约20分钟 1588550
String removeBlackToGrey = null; String removeBlackToGrey = null;
try { try {
statUtc = System.currentTimeMillis(); statUtc = System.currentTimeMillis();
...@@ -119,6 +122,7 @@ public class BlackGreyListJob { ...@@ -119,6 +122,7 @@ public class BlackGreyListJob {
log.error(todayNyr+", 每天执行将逾期已还清黑名单转灰名单异常", e); log.error(todayNyr+", 每天执行将逾期已还清黑名单转灰名单异常", e);
}finally { }finally {
log.info(todayNyr+", 每天执行将逾期已还清黑名单转灰名单结束, Msg: {} , 总耗时: {} ", removeBlackToGrey, (System.currentTimeMillis()-statUtc)+".ms"); log.info(todayNyr+", 每天执行将逾期已还清黑名单转灰名单结束, Msg: {} , 总耗时: {} ", removeBlackToGrey, (System.currentTimeMillis()-statUtc)+".ms");
dingTalk.talkByWebHook(DingTalk.WEBHOOK_BLACKGREY, "Info", DingTalk.TITLETAGS_BLACKGREY, "转移"+todayNyr+"黑名单转灰名单结束", removeBlackToGrey);
} }
...@@ -198,7 +202,7 @@ public class BlackGreyListJob { ...@@ -198,7 +202,7 @@ public class BlackGreyListJob {
//判断是否有执行 //判断是否有执行
if (getRedisValStr(ConstantBlackGrey.REDIS_KEY.SIGN_IS_RUN_UPDATE_BLACK_OVERDUEDAY_KEY)) { if (getRedisValStr(ConstantBlackGrey.REDIS_KEY.SIGN_IS_RUN_UPDATE_BLACK_OVERDUEDAY_KEY)) {
//yyyy-MM-dd //yyyy-MM-dd
String todayNyr = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME); String todayNyr = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE);
long statUtc = System.currentTimeMillis(); long statUtc = System.currentTimeMillis();
String updateBLOverdueDay = null; String updateBLOverdueDay = null;
...@@ -206,13 +210,14 @@ public class BlackGreyListJob { ...@@ -206,13 +210,14 @@ public class BlackGreyListJob {
//删掉执行标记 //删掉执行标记
redisTemplate.delete(ConstantBlackGrey.REDIS_KEY.SIGN_IS_RUN_UPDATE_BLACK_OVERDUEDAY_KEY); redisTemplate.delete(ConstantBlackGrey.REDIS_KEY.SIGN_IS_RUN_UPDATE_BLACK_OVERDUEDAY_KEY);
//耗时3807471.ms 约64分钟, //耗时3807471.ms 约64分钟, 3648346.ms
updateBLOverdueDay = blackGreyListService.updateBlackListOverdueDay(); updateBLOverdueDay = blackGreyListService.updateBlackListOverdueDay();
}catch (Exception e){ }catch (Exception e){
log.error(todayNyr+", 每天执行更新黑名单最大逾期天数和累计逾期天数异常", e); log.error(todayNyr+", 每天执行更新黑名单最大逾期天数和累计逾期天数异常", e);
}finally { }finally {
redisTemplate.delete(ConstantBlackGrey.REDIS_KEY.SIGN_IS_RUN_UPDATE_BLACK_OVERDUEDAY_KEY); redisTemplate.delete(ConstantBlackGrey.REDIS_KEY.SIGN_IS_RUN_UPDATE_BLACK_OVERDUEDAY_KEY);
log.info(todayNyr+", 每天执行更新黑名单最大逾期天数和累计逾期天结束, Msg: {} , 总耗时: {} ", updateBLOverdueDay, (System.currentTimeMillis()-statUtc)+".ms"); log.info(todayNyr+", 每天执行更新黑名单最大逾期天数和累计逾期天结束, Msg: {} , 总耗时: {} ", updateBLOverdueDay, (System.currentTimeMillis()-statUtc)+".ms");
dingTalk.talkByWebHook(DingTalk.WEBHOOK_BLACKGREY, "Info", DingTalk.TITLETAGS_BLACKGREY, "更新"+todayNyr+"黑名单最大逾期天数和累计逾期天结束", updateBLOverdueDay);
} }
} }
......
...@@ -516,7 +516,8 @@ public class BlackGreyListServiceImpl implements IBlackGreyListService { ...@@ -516,7 +516,8 @@ public class BlackGreyListServiceImpl implements IBlackGreyListService {
public String importXianJinDaiBlackGreyList() { public String importXianJinDaiBlackGreyList() {
Stopwatch queryStopwatch = Stopwatch.createStarted(); Stopwatch queryStopwatch = Stopwatch.createStarted();
List<TmpBlackGreyList> xjdBlackGreyList = xyqbJdbcTemplate.query(ConstantBlackGrey.SQL.XYQB_QUERY_XianJinDai_15DAY, new BeanPropertyRowMapper<>(TmpBlackGreyList.class)); List<TmpBlackGreyList> xjdBlackGreyList = xyqbJdbcTemplate.query(ConstantBlackGrey.SQL.XYQB_QUERY_XianJinDai_15DAY, new BeanPropertyRowMapper<>(TmpBlackGreyList.class));
log.info("每天执行-现金分期15+逾期用户黑名单-查询结束, listSize: {} , 耗时: {} ", xjdBlackGreyList.size(), queryStopwatch.stop().elapsed(TimeUnit.MILLISECONDS)); long queryCost = queryStopwatch.stop().elapsed(TimeUnit.MILLISECONDS);
log.info("每天执行-现金分期15+逾期用户黑名单-查询结束, listSize: {} , 耗时: {} ", xjdBlackGreyList.size(), queryCost);
Stopwatch checkStopwatch = Stopwatch.createStarted(); Stopwatch checkStopwatch = Stopwatch.createStarted();
List<TmpBlackGreyList> newIncreasedList = new ArrayList<>(); List<TmpBlackGreyList> newIncreasedList = new ArrayList<>();
...@@ -553,10 +554,11 @@ public class BlackGreyListServiceImpl implements IBlackGreyListService { ...@@ -553,10 +554,11 @@ public class BlackGreyListServiceImpl implements IBlackGreyListService {
e.printStackTrace(); e.printStackTrace();
} }
} }
log.info("每天执行-现金分期15+逾期用户黑名单-插入结束, listSize: {} , details_haveCount: {} , newIncreasedList: {} , saveOkCount: {} , 耗时: {} ", xjdBlackGreyList.size(), details_haveCount.get(), newIncreasedList.size(), saveOkCount, saveStopwatch.stop().elapsed(TimeUnit.MILLISECONDS)); long saveCost = saveStopwatch.stop().elapsed(TimeUnit.MILLISECONDS);
log.info("每天执行-现金分期15+逾期用户黑名单-插入结束, listSize: {} , details_haveCount: {} , newIncreasedList: {} , saveOkCount: {} , 耗时: {} ", xjdBlackGreyList.size(), details_haveCount.get(), newIncreasedList.size(), saveOkCount, saveCost);
String resMsgTemp = "新增黑名单(现金分期15+逾期) 查询 %d条, 明细表已存在 %d条, 需要插入 %d条, 插入成功 %d条;"; String resMsgTemp = "新增黑名单(现金分期15+逾期) 查询 %d条, 查询耗时 %d.毫秒, 明细表已存在 %d条, 需要插入 %d条, 插入成功 %d条, 插入耗时 %d毫秒;";
return String.format(resMsgTemp, xjdBlackGreyList.size(), details_haveCount.get(), newIncreasedList.size(), saveOkCount); return String.format(resMsgTemp, xjdBlackGreyList.size(), queryCost, details_haveCount.get(), newIncreasedList.size(), saveOkCount, saveCost);
} }
...@@ -580,7 +582,8 @@ public class BlackGreyListServiceImpl implements IBlackGreyListService { ...@@ -580,7 +582,8 @@ public class BlackGreyListServiceImpl implements IBlackGreyListService {
}catch (Exception e){ }catch (Exception e){
log.error("每天执行-vcc逾期15+用户黑名单-查询acsdb用户userId异常!", e); log.error("每天执行-vcc逾期15+用户黑名单-查询acsdb用户userId异常!", e);
} }
log.info("每天执行-vcc逾期15+用户黑名单-查询acsdb用户userId结束, vccUserIdList: {} , 耗时: {} ", (vccUserIdList!=null ? vccUserIdList.size(): "null"), queryStopwatch1.stop().elapsed(TimeUnit.MILLISECONDS)); long queryCost = queryStopwatch1.stop().elapsed(TimeUnit.MILLISECONDS);
log.info("每天执行-vcc逾期15+用户黑名单-查询acsdb用户userId结束, vccUserIdList: {} , 耗时: {} ", (vccUserIdList!=null ? vccUserIdList.size(): "null"), queryCost);
Stopwatch queryStopwatch2 = Stopwatch.createStarted(); Stopwatch queryStopwatch2 = Stopwatch.createStarted();
List<TmpBlackGreyList> vccBlackGreyList = new ArrayList<TmpBlackGreyList>(); List<TmpBlackGreyList> vccBlackGreyList = new ArrayList<TmpBlackGreyList>();
...@@ -663,10 +666,11 @@ public class BlackGreyListServiceImpl implements IBlackGreyListService { ...@@ -663,10 +666,11 @@ public class BlackGreyListServiceImpl implements IBlackGreyListService {
e.printStackTrace(); e.printStackTrace();
} }
} }
log.info("每天执行-vcc逾期15+用户黑名单-插入结束, vccBlackGreyList: {} , details_haveCount: {} , newIncreasedList: {} , saveOkCount: {} , 耗时: {} ", vccBlackGreyList.size(), details_haveCount.get(), newIncreasedList.size(), saveOkCount, saveStopwatch.stop().elapsed(TimeUnit.MILLISECONDS)); long saveCost = saveStopwatch.stop().elapsed(TimeUnit.MILLISECONDS);
log.info("每天执行-vcc逾期15+用户黑名单-插入结束, vccBlackGreyList: {} , details_haveCount: {} , newIncreasedList: {} , saveOkCount: {} , 耗时: {} ", vccBlackGreyList.size(), details_haveCount.get(), newIncreasedList.size(), saveOkCount, saveCost);
String resMsgTemp = "新增黑名单(vcc逾期15+逾期) 查询 %d条, 明细表已存在 %d条, 需要插入 %d条, 插入成功 %d条;"; String resMsgTemp = "新增黑名单(vcc逾期15+逾期) 查询 %d条, 查询耗时 %d毫秒, 明细表已存在 %d条, 需要插入 %d条, 插入成功 %d条, 插入耗时 %d毫秒;";
return String.format(resMsgTemp, vccBlackGreyList.size(), details_haveCount.get(), newIncreasedList.size(), saveOkCount); return String.format(resMsgTemp, vccBlackGreyList.size(), queryCost, details_haveCount.get(), newIncreasedList.size(), saveOkCount, saveCost);
} }
/*@Override /*@Override
...@@ -798,9 +802,12 @@ public class BlackGreyListServiceImpl implements IBlackGreyListService { ...@@ -798,9 +802,12 @@ public class BlackGreyListServiceImpl implements IBlackGreyListService {
//批量 逾期已还清黑名单>>转灰名单 //批量 逾期已还清黑名单>>转灰名单
if(blackListResults!=null && blackListResults.size() >0 ){ if(blackListResults!=null && blackListResults.size() >0 ){
return blackToGreyListParallel.removeBlackToGrey(blackListResults); String resMsg1 = "黑名单转灰名单查询 "+blackListResults.size()+"条, 查询耗时 "+(System.currentTimeMillis()-startTime)+"毫秒, ";
String resMsg2 = blackToGreyListParallel.removeBlackToGrey(blackListResults);
return resMsg1+resMsg2;
}else {
return "黑名单转灰名单查询 0条, 查询耗时 "+(System.currentTimeMillis()-startTime)+"毫秒, 跳过转移!";
} }
return null;
} }
...@@ -914,9 +921,13 @@ public class BlackGreyListServiceImpl implements IBlackGreyListService { ...@@ -914,9 +921,13 @@ public class BlackGreyListServiceImpl implements IBlackGreyListService {
//批量更新黑名单>>逾期天数 //批量更新黑名单>>逾期天数
if(blackListResults!=null && blackListResults.size() >0 ){ if(blackListResults!=null && blackListResults.size() >0 ){
return updateBlackListOverdueDayParallel.runUpdate(blackListResults); String resMsg1 = "更新黑名单逾期天数查询 "+blackListResults.size()+"条, 查询耗时 "+(System.currentTimeMillis()-startTime)+"毫秒, ";
String resMsg2 = updateBlackListOverdueDayParallel.runUpdate(blackListResults);
return resMsg1+resMsg2;
}else {
return "更新黑名单逾期天数查询 0条, 查询耗时 "+(System.currentTimeMillis()-startTime)+"毫秒, 跳过更新!";
} }
return null;
} }
} }
...@@ -70,15 +70,51 @@ public class BlackToGreyListParallel implements ParallelComputingProcess<BlackGr ...@@ -70,15 +70,51 @@ public class BlackToGreyListParallel implements ParallelComputingProcess<BlackGr
p.processForThread(tmpQueryList, this, THREAD_COUNT, optSet); p.processForThread(tmpQueryList, this, THREAD_COUNT, optSet);
//并行框架执行结果 //并行框架执行结果
if (optSet.size() > 0) {//并行框架执行异常 Set<String> resultSet = new HashSet<>();
log.info(log_inf + "-removeBlackToGrey黑名单转灰名单执行结束-部分失败, cost: {} <<<<<< process optSet size: {} , json: {} ", (System.currentTimeMillis()-startProcess), optSet.size(), JSONObject.toJSONString(optSet)); Map<String, String> dingTalkMap = new HashMap<>();
for(String logInfo : optSet){
if(logInfo.startsWith("dingTalk_CPU_")){
//dingTalk_CPU_1:type_11=1,uuid_isNull=2,update_r_count=3,update_d_count=4,err_count=5
String[] tmpArray = logInfo.split(":");
dingTalkMap.put(tmpArray[0], tmpArray[1]);
}else{
resultSet.add(logInfo);
}
}
//判断,输出日志
if (resultSet.size() > 0) {//并行框架执行异常
log.info(log_inf + "-removeBlackToGrey黑名单转灰名单执行结束-部分失败, cost: {} <<<<<< process resultSet size: {} , json: {} ", (System.currentTimeMillis()-startProcess), resultSet.size(), JSONObject.toJSONString(resultSet));
} else { } else {
//执行成功 //执行成功
log.info(log_inf + "-removeBlackToGrey黑名单转灰名单执行结束-成功, cost: {} <<<<<< process is OK!", (System.currentTimeMillis() - startProcess)); log.info(log_inf + "-removeBlackToGrey黑名单转灰名单执行结束-成功, cost: {} <<<<<< process is OK!", (System.currentTimeMillis() - startProcess));
} }
String resMsgTemp = "总共 %d条, 执行成功 %d条, 失败 %d条;";
return String.format(resMsgTemp, listSize, listSize-optSet.size(), optSet.size()); //拼接构建钉钉通知的信息
int type_11=0, uuid_isNull=0,update_r_count=0,update_d_count=0,err_count=0;
try{
//type_11=1,uuid_isNull=2,update_r_count=3,update_d_count=4,err_count=5
for(Map.Entry<String, String> entry: dingTalkMap.entrySet()){
String context = entry.getValue();
String[] tmpArry = context.trim().split(",");
try {
type_11+=Integer.parseInt(tmpArry[0].split("=")[1].trim());
uuid_isNull+=Integer.parseInt(tmpArry[1].split("=")[1].trim());
update_r_count+=Integer.parseInt(tmpArry[2].split("=")[1].trim());
update_d_count+=Integer.parseInt(tmpArry[3].split("=")[1].trim());
err_count+=Integer.parseInt(tmpArry[4].split("=")[1].trim());
}catch (Exception e){
log.error("黑名单转灰名单拼接钉钉告警信息,Integer转换异常", e);
}
}
}catch (Exception e){
log.error("黑名单转灰名单拼接钉钉告警信息异常", e);
}
String resMsgTemp = "总共 %d条, type11 %d条, uuid为空 %d条, 结果表更新 %d条, 明细表更新 %d条, 失败 %d条, 处理耗时 %d分钟;";
return String.format(resMsgTemp, listSize, type_11, uuid_isNull, update_r_count, update_d_count, err_count, (int)(System.currentTimeMillis()-startProcess)/1000/60);
} catch (Exception e) { } catch (Exception e) {
log.error(log_inf +"-removeBlackToGrey黑名单转灰名单执行异常.", e); log.error(log_inf +"-removeBlackToGrey黑名单转灰名单执行异常.", e);
} }
...@@ -95,6 +131,7 @@ public class BlackToGreyListParallel implements ParallelComputingProcess<BlackGr ...@@ -95,6 +131,7 @@ public class BlackToGreyListParallel implements ParallelComputingProcess<BlackGr
AtomicInteger err_count = new AtomicInteger(); AtomicInteger err_count = new AtomicInteger();
AtomicInteger uuid_isNull_count = new AtomicInteger();
AtomicInteger type_11 = new AtomicInteger(); AtomicInteger type_11 = new AtomicInteger();
AtomicInteger update_d_count = new AtomicInteger(); AtomicInteger update_d_count = new AtomicInteger();
AtomicInteger update_r_count = new AtomicInteger(); AtomicInteger update_r_count = new AtomicInteger();
...@@ -247,14 +284,17 @@ public class BlackToGreyListParallel implements ParallelComputingProcess<BlackGr ...@@ -247,14 +284,17 @@ public class BlackToGreyListParallel implements ParallelComputingProcess<BlackGr
log.error(log_inf + "黑名单转灰名单执行异常process() threadId:" + threadId, e); log.error(log_inf + "黑名单转灰名单执行异常process() threadId:" + threadId, e);
} }
}else { }else {
err_count.getAndIncrement(); uuid_isNull_count.getAndIncrement();
optSet.add("uuid空:" + rId); optSet.add("uuid空:" + rId);
log.error("查询逾期黑名单是否已还清-发现uuid为空, threadId_{} , r_Id: {} , uuid: {} , blackType: {} ", threadId, rId, uuid, blackResult.getBlackType()); log.error("查询逾期黑名单是否已还清-发现uuid为空, threadId_{} , r_Id: {} , uuid: {} , blackType: {} ", threadId, rId, uuid, blackResult.getBlackType());
} }
} }
log.info(log_inf + "黑名单转灰名单process处理结束CPU_{} , this_list_size: {} , type_11: {} , update_r_count: {} , update_d_count: {} , 失败: {} , 耗时: {} ", log.info(log_inf + "黑名单转灰名单process处理结束CPU_{} , this_list_size: {} , type_11: {} , uuid_isNull_count: {} , update_r_count: {} , update_d_count: {} , 失败: {} , 耗时: {} ",
threadId, list_size, type_11.get(), update_r_count.get(), update_d_count.get(), err_count.get(), (System.currentTimeMillis()-start)); threadId, list_size, type_11.get(), uuid_isNull_count.get(), update_r_count.get(), update_d_count.get(), err_count.get(), (System.currentTimeMillis()-start));
String dingTalk = "type_11="+type_11.get()+",uuid_isNull="+uuid_isNull_count.get()+",update_r_count="+update_r_count.get()+",update_d_count="+update_d_count.get()+",err_count="+err_count.get();
optSet.add("dingTalk_CPU_"+threadId + ":"+dingTalk);
} }
...@@ -495,4 +535,11 @@ public class BlackToGreyListParallel implements ParallelComputingProcess<BlackGr ...@@ -495,4 +535,11 @@ public class BlackToGreyListParallel implements ParallelComputingProcess<BlackGr
return 0; return 0;
} }
public static void main(String[] args) {
String dingTalk = "dingTalk_CPU_1:type_11=1,uuid_isNull=2,update_r_count=3,update_d_count=4,err_count=5";
String[] tmpArry = dingTalk.split(":");
String[] tmpArry2 = tmpArry[1].split(",");
String[] tmpArry3 = tmpArry2[0].split("=");
}
} }
...@@ -14,6 +14,7 @@ import cn.quantgroup.qgblservice.service.IBlackListUpdateThreeEleService; ...@@ -14,6 +14,7 @@ import cn.quantgroup.qgblservice.service.IBlackListUpdateThreeEleService;
import cn.quantgroup.qgblservice.service.IThirdPartBlackListManagerService; import cn.quantgroup.qgblservice.service.IThirdPartBlackListManagerService;
import cn.quantgroup.qgblservice.utils.MD5Util; import cn.quantgroup.qgblservice.utils.MD5Util;
import cn.quantgroup.qgblservice.utils.blacklist.BlackListUtils; import cn.quantgroup.qgblservice.utils.blacklist.BlackListUtils;
import cn.quantgroup.qgblservice.utils.dingding.DingTalk;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
...@@ -63,6 +64,9 @@ public class ThirdPartBlackListServiceImpl implements IThirdPartBlackListManager ...@@ -63,6 +64,9 @@ public class ThirdPartBlackListServiceImpl implements IThirdPartBlackListManager
@Autowired @Autowired
private IBlackGreyListService blackGreyListService; private IBlackGreyListService blackGreyListService;
@Autowired
private DingTalk dingTalk;
@Override @Override
public GlobalResponse saveThirdPartBlackList(String uuid, String name, String phoneNo, String idCard, String type) { public GlobalResponse saveThirdPartBlackList(String uuid, String name, String phoneNo, String idCard, String type) {
...@@ -159,6 +163,7 @@ public class ThirdPartBlackListServiceImpl implements IThirdPartBlackListManager ...@@ -159,6 +163,7 @@ public class ThirdPartBlackListServiceImpl implements IThirdPartBlackListManager
log.info("插入黑灰名单入参, uuid: {} , name: {} , phoneNo: {} , idCard: {} , type: {} , typeCode: {} , reasonCode: {} , reasonExplain: {} ", uuid, name, phoneNo, idCard, type, typeCode, reasonCode, reasonExplain); log.info("插入黑灰名单入参, uuid: {} , name: {} , phoneNo: {} , idCard: {} , type: {} , typeCode: {} , reasonCode: {} , reasonExplain: {} ", uuid, name, phoneNo, idCard, type, typeCode, reasonCode, reasonExplain);
if(org.apache.commons.lang3.StringUtils.isAnyEmpty(typeCode, reasonCode, reasonExplain)){ if(org.apache.commons.lang3.StringUtils.isAnyEmpty(typeCode, reasonCode, reasonExplain)){
log.error("插入黑灰名单时-未匹配到typeCode或reason! uuid: {} , name: {} , phoneNo: {} , idCard: {} , type: {} ", uuid, name, phoneNo, idCard, type); log.error("插入黑灰名单时-未匹配到typeCode或reason! uuid: {} , name: {} , phoneNo: {} , idCard: {} , type: {} ", uuid, name, phoneNo, idCard, type);
dingTalk.talkByWebHook(DingTalk.WEBHOOK_BLACKGREY, "ERROR", DingTalk.TITLETAGS_BLACKGREY, "三方数据源进来的灰名单插入失败", "根据urlType:"+type+"未匹配到typeCode或reason! ["+uuid+", "+name+", "+phoneNo+", "+idCard+"]");
return GlobalResponse.error("参数type未匹配到typeCode!"); return GlobalResponse.error("参数type未匹配到typeCode!");
} }
BlackGreyListQueryVo queryResultParam = BlackGreyListQueryVo.builder().name(name).idNo(idCard).phoneNo(phoneNo) BlackGreyListQueryVo queryResultParam = BlackGreyListQueryVo.builder().name(name).idNo(idCard).phoneNo(phoneNo)
......
...@@ -71,15 +71,50 @@ public class UpdateBlackListOverdueDayParallel implements ParallelComputingProce ...@@ -71,15 +71,50 @@ public class UpdateBlackListOverdueDayParallel implements ParallelComputingProce
p.processForThread(tmpQueryList, this, THREAD_COUNT, optSet); p.processForThread(tmpQueryList, this, THREAD_COUNT, optSet);
//并行框架执行结果 //并行框架执行结果
if (optSet.size() > 0) {//并行框架执行异常 Set<String> resultSet = new HashSet<>();
log.info(log_inf + "-runUpdate更新逾期天数执行结束-部分失败, cost: {} <<<<<< process optSet size: {} , json: {} ", (System.currentTimeMillis()-startProcess), optSet.size(), JSONObject.toJSONString(optSet)); Map<String, String> dingTalkMap = new HashMap<>();
for(String logInfo : optSet){
if(logInfo.startsWith("dingTalk_CPU_")){
//dingTalk_CPU_1:type_11=1,uuid_isNull=2,update_r_count=3,update_d_count=4,err_count=5
String[] tmpArray = logInfo.split(":");
dingTalkMap.put(tmpArray[0], tmpArray[1]);
}else{
resultSet.add(logInfo);
}
}
//判断,输出日志
if (resultSet.size() > 0) {//并行框架执行异常
log.info(log_inf + "-runUpdate更新逾期天数执行结束-部分失败, cost: {} <<<<<< process resultSet size: {} , json: {} ", (System.currentTimeMillis()-startProcess), resultSet.size(), JSONObject.toJSONString(resultSet));
} else { } else {
//执行成功 //执行成功
log.info(log_inf + "-runUpdate更新逾期天数执行结束-成功, cost: {} <<<<<< process is OK!", (System.currentTimeMillis() - startProcess)); log.info(log_inf + "-runUpdate更新逾期天数执行结束-成功, cost: {} <<<<<< process is OK!", (System.currentTimeMillis() - startProcess));
} }
String resMsgTemp = "更新逾期天数总共 %d条, 执行成功 %d条, 失败 %d条;"; //拼接构建钉钉通知的信息
return String.format(resMsgTemp, listSize, listSize-optSet.size(), optSet.size()); int type_11=0, uuid_isNull=0,update_r_count=0,update_d_count=0,err_count=0;
try{
//type_11=1,uuid_isNull=2,update_r_count=3,update_d_count=4,err_count=5
for(Map.Entry<String, String> entry: dingTalkMap.entrySet()){
String context = entry.getValue();
String[] tmpArry = context.trim().split(",");
try {
type_11+=Integer.parseInt(tmpArry[0].split("=")[1].trim());
uuid_isNull+=Integer.parseInt(tmpArry[1].split("=")[1].trim());
update_r_count+=Integer.parseInt(tmpArry[2].split("=")[1].trim());
update_d_count+=Integer.parseInt(tmpArry[3].split("=")[1].trim());
err_count+=Integer.parseInt(tmpArry[4].split("=")[1].trim());
}catch (Exception e){
log.error("更新逾期天数拼接钉钉告警信息,Integer转换异常", e);
}
}
}catch (Exception e){
log.error("更新逾期天数拼接钉钉告警信息异常", e);
}
String resMsgTemp = "总共 %d条, type11 %d条, uuid为空 %d条, 结果表更新 %d条, 明细表更新 %d条, 失败 %d条, 处理耗时 %d分钟;";
return String.format(resMsgTemp, listSize, type_11, uuid_isNull, update_r_count, update_d_count, err_count, (int)(System.currentTimeMillis()-startProcess)/1000/60);
} catch (Exception e) { } catch (Exception e) {
log.error(log_inf +"-runUpdate更新逾期天数执行异常.", e); log.error(log_inf +"-runUpdate更新逾期天数执行异常.", e);
} }
...@@ -94,11 +129,11 @@ public class UpdateBlackListOverdueDayParallel implements ParallelComputingProce ...@@ -94,11 +129,11 @@ public class UpdateBlackListOverdueDayParallel implements ParallelComputingProce
String dateName = ConstantBlackGrey.PARAM.DF_YMD.format(Calendar.getInstance().getTime()); String dateName = ConstantBlackGrey.PARAM.DF_YMD.format(Calendar.getInstance().getTime());
int list_size = blackResultList.size(); int list_size = blackResultList.size();
AtomicInteger ok_count = new AtomicInteger();
AtomicInteger err_count = new AtomicInteger(); AtomicInteger err_count = new AtomicInteger();
AtomicInteger uuid_isNull_count = new AtomicInteger();
AtomicInteger type_11 = new AtomicInteger(); AtomicInteger type_11 = new AtomicInteger();
AtomicInteger update_d_count = new AtomicInteger();
AtomicInteger update_count = new AtomicInteger(); AtomicInteger update_r_count = new AtomicInteger();
int index = 0; int index = 0;
for (BlackGreyListResult blackResult : blackResultList) { for (BlackGreyListResult blackResult : blackResultList) {
...@@ -146,7 +181,7 @@ public class UpdateBlackListOverdueDayParallel implements ParallelComputingProce ...@@ -146,7 +181,7 @@ public class UpdateBlackListOverdueDayParallel implements ParallelComputingProce
int update = updateOverdueDay(overdueDays, detailsVo, "现金贷"); int update = updateOverdueDay(overdueDays, detailsVo, "现金贷");
if(update>0){ if(update>0){
details_is_update = true; details_is_update = true;
update_count.getAndAdd(update); update_d_count.getAndAdd(update);
} }
} }
...@@ -173,7 +208,7 @@ public class UpdateBlackListOverdueDayParallel implements ParallelComputingProce ...@@ -173,7 +208,7 @@ public class UpdateBlackListOverdueDayParallel implements ParallelComputingProce
int update = updateOverdueDay(overdueDays, detailsVo, "白条"); int update = updateOverdueDay(overdueDays, detailsVo, "白条");
if(update>0){ if(update>0){
details_is_update = true; details_is_update = true;
update_count.getAndAdd(update); update_d_count.getAndAdd(update);
} }
} }
...@@ -203,7 +238,7 @@ public class UpdateBlackListOverdueDayParallel implements ParallelComputingProce ...@@ -203,7 +238,7 @@ public class UpdateBlackListOverdueDayParallel implements ParallelComputingProce
int update = updateOverdueDay(overdueDays, detailsVo, "白条"); int update = updateOverdueDay(overdueDays, detailsVo, "白条");
if(update>0){ if(update>0){
details_is_update = true; details_is_update = true;
update_count.getAndAdd(update); update_d_count.getAndAdd(update);
} }
} }
}else{ }else{
...@@ -218,8 +253,10 @@ public class UpdateBlackListOverdueDayParallel implements ParallelComputingProce ...@@ -218,8 +253,10 @@ public class UpdateBlackListOverdueDayParallel implements ParallelComputingProce
//如果明细表有修改,更新一下结果表修改时间 //如果明细表有修改,更新一下结果表修改时间
if(details_is_update){ if(details_is_update){
//更新结果表 //更新结果表
updateResultUpdatedAt(blackResult.getRId()); int update_r = updateResultUpdatedAt(blackResult.getRId());
ok_count.getAndIncrement(); if(update_r>0){
update_r_count.getAndIncrement();
}
} }
}else { }else {
...@@ -234,13 +271,17 @@ public class UpdateBlackListOverdueDayParallel implements ParallelComputingProce ...@@ -234,13 +271,17 @@ public class UpdateBlackListOverdueDayParallel implements ParallelComputingProce
log.error(log_inf + "更新黑名单逾期天执行异常process() threadId:" + threadId, e); log.error(log_inf + "更新黑名单逾期天执行异常process() threadId:" + threadId, e);
} }
}else { }else {
err_count.getAndIncrement(); uuid_isNull_count.getAndIncrement();
optSet.add("uuid空:" + rId); optSet.add("uuid空:" + rId);
log.error("查询黑名单逾期天-发现uuid为空, threadId_{} , r_Id: {} , uuid: {} , blackType: {} ", threadId, rId, uuid, blackResult.getBlackType()); log.error("查询黑名单逾期天-发现uuid为空, threadId_{} , r_Id: {} , uuid: {} , blackType: {} ", threadId, rId, uuid, blackResult.getBlackType());
} }
} }
log.info(log_inf + "更新黑名单逾期天数process处理结束CPU_{} , this_list_size: {} , ok_count: {} , err_count: {} , type_11: {} , update_count: {} , 耗时: {} ", threadId, list_size, ok_count.get(), err_count.get(), type_11.get(), update_count.get(), (System.currentTimeMillis()-start)); log.info(log_inf + "更新黑名单逾期天数process处理结束CPU_{} , this_list_size: {} , type_11: {} , uuid_isNull_count: {} , update_r_count: {} , update_d_count: {} , 失败: {} , 耗时: {} ",
threadId, list_size, type_11.get(), uuid_isNull_count.get(), update_r_count.get(), update_d_count.get(), err_count.get(), (System.currentTimeMillis()-start));
String dingTalk = "type_11="+type_11.get()+",uuid_isNull="+uuid_isNull_count.get()+",update_r_count="+update_r_count.get()+",update_d_count="+update_d_count.get()+",err_count="+err_count.get();
optSet.add("dingTalk_CPU_"+threadId + ":"+dingTalk);
} }
......
package cn.quantgroup.qgblservice.utils.dingding;
import java.io.PrintWriter;
import java.io.StringWriter;
/**
* @author :dongjianhua
* @date :Created in 2019/11/4 10:38
* @description:异常类
* @modified By:
* @version: 1.0
*/
public class DingException extends RuntimeException {
//提醒标题
public String alarm;
//堆栈信息 或者报错信息
public String message;
public DingException(String exMsg) {
alarm = exMsg;
}
public DingException(String exMsg, String message) {
super(message,null);
alarm = exMsg;
this.message = message;
}
public DingException(String exMsg, Exception e) {
super(e);
alarm = exMsg;
message = getStackTrace(e);
}
public static String getStackTrace(Throwable t) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
try {
t.printStackTrace(pw);
return sw.toString();
} finally {
pw.close();
}
}
}
package cn.quantgroup.qgblservice.utils.dingding;
import cn.quantgroup.qgblservice.utils.http.HttpRequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* -----------------------------------------------------------------------------<br>
* 类描述: 黑灰名单数据插入更新 钉钉提醒 <br>
* 创建人: yanhui.Hao <br>
* 创建时间: 2020.04.29 14:45 <br>
* 公司: 北京众信利民信息技术有限公司 <br>
* -----------------------------------------------------------------------------
*/
@Component
@Slf4j
public class DingTalk {
//@Autowired
//private IHttpService iHttpService;
@Value("${isDebug}")
private Boolean isDebug;
public static final String talkUri = "https://alertserv-dataservice.quantgroup.cn/common/alert/dingtalk";
//黑灰名单 钉钉机器人
public static final String WEBHOOK_BLACKGREY = "https://oapi.dingtalk.com/robot/send?access_token=959647751bda08896d69b570393d788d16b2307a50d127d6b6c6e284148aef0f";
public static final String TITLETAGS_BLACKGREY = "黑灰名单";
/**
* -----------------------------------------------------------------------------<br>
* 描 述: 正常去情况下钉钉通知 <br>
* 创建人: yanhui.Hao <br>
* 创建时间: 2020.04.29 15:31 <br>
* 最后修改人: <br>
* 最后修改时间: 2020.04.29 15:31 <br>
* 入参说明: <br>
* 出参说明: <br>
* -----------------------------------------------------------------------------
*/
@Async
public void talkByWebHook(String webHook, String alarmLevel, String titleTags, String titleMsg, String contentMsg) {
if (BooleanUtils.isTrue(isDebug)) {
log.info("测试环境下不钉钉通知, webHook: {} , alarmLevel: {} , titleTags: {} , titleMsg: {} , contentMsg: {} ", webHook, alarmLevel, titleTags, titleMsg, contentMsg);
return;
}
try{
if(StringUtils.isEmpty(webHook)){
log.error("钉钉日常通知接口调用失败, webHook参数不能为空!");
return;
}
Map<String, String> param = new HashMap<>();
param.put("webhook", webHook);
param.put("alarmLevel", alarmLevel);//"Warn"
param.put("msgTitle", titleTags + ":" + titleMsg);
param.put("msgContent", contentMsg);
//String resp = iHttpService.post(talkUri, param);
String resp = HttpRequestUtil.doPost(talkUri, param, "dingtalk");
log.info("钉钉日常通知接口调用结束, resp: {} ", resp);
}catch (Exception e){
log.error("钉钉日常通知接口调用异常! ",e);
}
}
/**
* -----------------------------------------------------------------------------<br>
* 描 述: 异常情况下钉钉通知 <br>
* 创建人: yanhui.Hao <br>
* 创建时间: 2020.04.29 15:32 <br>
* 最后修改人: <br>
* 最后修改时间: 2020.04.29 15:32 <br>
* 入参说明: <br>
* 出参说明: <br>
* -----------------------------------------------------------------------------
*/
@Async
public void talkByWebHook(String webHook, String alarmLevel, String titleTags, String titleMsg, Exception ex) {
if (BooleanUtils.isTrue(isDebug)) {
log.info("测试环境下不钉钉通知, webHook: {} , alarmLevel: {} , titleTags: {} , titleMsg: {} , contentMsg: {} ", webHook, alarmLevel, titleTags, titleMsg, ex.toString());
return;
}
try{
if(StringUtils.isEmpty(webHook)){
log.error("钉钉日常通知接口调用失败, webHook参数不能为空!");
return;
}
Map<String, String> param = new HashMap<>();
param.put("webhook", webHook);
param.put("alarmLevel", alarmLevel);//"Warn"
param.put("msgTitle", titleTags + ":" + titleMsg);
String msg = ex.getMessage();
if(StringUtils.isBlank(msg)){
msg = ex.toString();
}
param.put("msgContent", msg);
//String resp = iHttpService.post(talkUri, param);
String resp = HttpRequestUtil.doPost(talkUri, param, "dingtalk");
log.info("钉钉日常通知接口调用结束, resp: {} ", resp);
}catch (Exception e){
log.error("钉钉日常通知接口调用异常! ", e);
}
}
/**
* -----------------------------------------------------------------------------<br>
* 描 述: @某某的通知 <br>
* 创建人: yanhui.Hao <br>
* 创建时间: 2020.04.29 15:36 <br>
* 最后修改人: <br>
* 最后修改时间: 2020.04.29 15:36 <br>
* 入参说明: <br>
* 出参说明: <br>
* -----------------------------------------------------------------------------
*/
@Async
public void talk_ToUser(String webHook, String alarmLevel, String titleTags, String titleMsg, String contentMsg) {
if (BooleanUtils.isTrue(isDebug)) {
log.info("测试环境下不钉钉通知, webHook: {} , alarmLevel: {} , titleTags: {} , titleMsg: {} , contentMsg: {} ", webHook, alarmLevel, titleTags, titleMsg, contentMsg);
return;
}
try{
Map<String, String> param = new HashMap<>();
param.put("webhook", webHook);
param.put("alarmLevel", alarmLevel);
param.put("msgTitle", titleTags+ " :"+titleMsg);
param.put("msgContent", contentMsg);
param.put("toUsers", "18010105506");
//String resp = iHttpService.post(talkUri, param);
String resp = HttpRequestUtil.doPost(talkUri, param, "dingtalk");
log.info("钉钉报警接口调用结束, resp: {} ", resp);
}catch (Exception e){
log.warn("钉钉报警接口调用异常! ",e);
}
}
}
package cn.quantgroup.qgblservice.utils.http;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Predicates;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.CharEncoding;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.*;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.Args;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.*;
import java.net.*;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPOutputStream;
/**
* Created by suh on 2017/12/18.
*/
@Slf4j
public class HttpRequestUtil {
private static PoolingHttpClientConnectionManager connMgr;
private static RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000).setSocketTimeout(10000).build();
private static CloseableHttpClient httpClient=null;
private final static Object syncLock = new Object();
/** 针对中诚信手机号实名验证 调用频繁 Read timed out问题 */
private static RequestConfig requestConfig2 = RequestConfig.custom().setConnectTimeout(6000).setSocketTimeout(15000).build();
private static CloseableHttpClient httpClient2 = null;
/** 增加线程池重试机制 2019.10.30 **/
private static PoolingHttpClientConnectionManager connMgr_check;
private static CloseableHttpClient httpClient_check = null;
static {
try {
//添加对https的支持,该sslContext没有加载客户端证书
// 如果需要加载客户端证书,请使用如下sslContext,其中KEYSTORE_FILE和KEYSTORE_PASSWORD分别是你的证书路径和证书密码
//KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()
//FileInputStream instream = new FileInputStream(new File(KEYSTORE_FILE));
//keyStore.load(instream, KEYSTORE_PASSWORD.toCharArray());
//SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(keyStore,KEYSTORE_PASSWORD.toCharArray())
// .loadTrustMaterial(null, new TrustSelfSignedStrategy())
//.build();
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(null, new TrustSelfSignedStrategy())
.build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,SSLConnectionSocketFactory.getDefaultHostnameVerifier());
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslsf)
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.build();
connMgr = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
connMgr.setMaxTotal(50);
connMgr.setDefaultMaxPerRoute(25);
//增加空闲连接回收和有效性校验。 modify by haoyanhui 2019.10.30
connMgr_check = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
connMgr_check.setMaxTotal(100);
connMgr_check.setDefaultMaxPerRoute(50);
//多次请求用一个长链接的话,连接断开感知不到,再次请求就会org.apache.http.NoHttpResponseException
//可选的, 关闭15秒内不活动的连接 (2019.12.20 孚临对方说nginx里keepAlive是15秒)
connMgr_check.closeIdleConnections(15, TimeUnit.SECONDS);
//检测有效连接的间隔 毫秒 官方推荐使用这个来检查永久链接的可用性,而不推荐每次请求的时候才去检查
connMgr_check.setValidateAfterInactivity(1000);
}catch (Exception e){
log.warn("httpUtils init get exception:",e);
}
}
public static CloseableHttpClient getHttpClient(){
if(httpClient == null){
synchronized (syncLock){
if(httpClient == null){
httpClient =HttpClients.custom().setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig)
.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy(){
@Override
public long getKeepAliveDuration(final HttpResponse response, final HttpContext context) {
Args.notNull(response, "HTTP response");
final HeaderElementIterator it = new BasicHeaderElementIterator(
response.headerIterator(HTTP.CONN_KEEP_ALIVE));
while (it.hasNext()) {
final HeaderElement he = it.nextElement();
final String param = he.getName();
final String value = he.getValue();
if (value != null && param.equalsIgnoreCase("timeout")) {
try {
return 40 * 1000;
} catch(final NumberFormatException ignore) {
}
}
}
return 40 * 1000;
}
})
.setRetryHandler(new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException arg0, int retryTimes, HttpContext arg2) {
if (retryTimes > 2)
return false;
//当且仅当是可恢复的异常,才能进行重连
//可以重连的异常有NoHttpResponseException,ConnectTimeoutException ,SocketTimeoutException等
if (arg0 instanceof NoHttpResponseException
|| arg0 instanceof ConnectTimeoutException
|| arg0 instanceof SocketTimeoutException
|| arg0 instanceof InterruptedIOException
|| arg0 instanceof UnknownHostException){
try {
HttpRequest request = HttpClientContext.adapt(arg2).getRequest();
if(null!=request && null!=request.getRequestLine()){
RequestLine requestLine = request.getRequestLine();
log.warn("Again retryCount: {} , method: {} , uri: {} , exception: {} ", retryTimes, requestLine.getMethod(), requestLine.getUri(), arg0.toString());
}
}catch (Exception e){
log.warn("Again Out Log Error",e);
}
return true;
}
HttpClientContext clientContext = HttpClientContext.adapt(arg2);
HttpRequest request = clientContext.getRequest();
if (!(request instanceof HttpEntityEnclosingRequest)) // 如果请求被认为是幂等的,那么就重试。即重复执行不影响程序其他效果的
return true;
return false;
}
}).build();
}
}
}
return httpClient;
}
public static CloseableHttpClient getHttpClient2(){
if(httpClient2 == null){
synchronized (syncLock){
if(httpClient2 == null){
httpClient2 =HttpClients.custom().setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig2).build();
}
}
}
return httpClient2;
}
/**
* 描述: 增加重试机制的HttpClient线程池 <br/>
* 参数: [] <br/>
* 返回值: org.apache.http.impl.client.CloseableHttpClient <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.10.30 <br/>
*/
public static CloseableHttpClient getHttpClientOfcheck(){
if(httpClient_check == null){
synchronized (syncLock){
if(httpClient_check == null){
//请求计数,当发生异常的时候,如果重试次数大于某个值,则重连结束
HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int retryCount, HttpContext httpContext) {
if (retryCount > 2)
return false;
if (exception instanceof NoHttpResponseException
|| exception instanceof ConnectTimeoutException
|| exception instanceof SocketTimeoutException
|| exception instanceof InterruptedIOException
|| exception instanceof UnknownHostException){
try {
HttpRequest request = HttpClientContext.adapt(httpContext).getRequest();
if(null!=request && null!=request.getRequestLine()){
RequestLine requestLine = request.getRequestLine();
log.warn("httpClient_check Again retryCount: {} , method: {} , uri: {} , exception: {} ", retryCount, requestLine.getMethod(), requestLine.getUri(), exception.toString());
}
}catch (Exception e){
log.warn("httpClient_check Again Out Log Error",e);
}
return true;
}
// 如果请求被认为是幂等的,那么就重试。即重复执行不影响程序其他效果的
if (!(HttpClientContext.adapt(httpContext).getRequest() instanceof HttpEntityEnclosingRequest)){
return true;
}
return false;
}
};
// keep alive strategy
//ConnectionKeepAliveStrategy keepAliveStrategy = new DefaultConnectionKeepAliveStrategy();
DefaultConnectionKeepAliveStrategy myKeepAliveStrategy = new DefaultConnectionKeepAliveStrategy(){
@Override
public long getKeepAliveDuration(final HttpResponse response, final HttpContext context) {
Args.notNull(response, "HTTP response");
final HeaderElementIterator it = new BasicHeaderElementIterator(
response.headerIterator(HTTP.CONN_KEEP_ALIVE));
while (it.hasNext()) {
final HeaderElement he = it.nextElement();
final String param = he.getName();
final String value = he.getValue();
if (value != null && param.equalsIgnoreCase("timeout")) {
try {
return 40 * 1000;
} catch(final NumberFormatException ignore) {
}
}
}
return 40 * 1000;
}
};
httpClient_check = HttpClients.custom()
.setConnectionManager(connMgr_check)
.setRetryHandler(retryHandler)
.setKeepAliveStrategy(myKeepAliveStrategy)
//.setDefaultRequestConfig(requestConfig)
.build();
}
}
}
return httpClient_check;
}
/**
* 发送 GET 请求(HTTP),不带输入数据
*
* @param url
* @return
*/
public static RiskHttpResponse doGet(String url) {
return doGet(url, new HashMap<String, Object>());
}
/**
* 发送 GET 请求(HTTP),K-V形式
*
* @param url
* @param params
* @return
*/
public static RiskHttpResponse doGet(String url, Map<String, Object> params) {
String apiUrl = url;
StringBuffer param = new StringBuffer();
int i = 0;
for (String key : params.keySet()) {
if (i == 0)
param.append("?");
else
param.append("&");
param.append(key).append("=").append(params.get(key));
i++;
}
apiUrl += param;
//CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
//modify 2019.09.18
//httpClient = getHttpClient();
long startUtc = System.currentTimeMillis();
httpClient2 = getHttpClient();
HttpGet httpGet = new HttpGet(apiUrl);
try {
HttpResponse response = httpClient2.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
JSONObject jsonObject = JSONObject.parseObject(EntityUtils.toString(entity));
EntityUtils.consume(entity);
return new RiskHttpResponse(jsonObject,statusCode);
} catch (Exception e){
long endtUtc = System.currentTimeMillis();
log.error("方法doGet调用异常, apiUrl: "+apiUrl+"请求失败, cost: "+(endtUtc-startUtc)+".ms ", e);
// throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_FAIL,e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, e.toString() + ";url:"+apiUrl);
}finally {
httpGet.releaseConnection();
}
}
/**
* 发送 POST 请求(HTTP),不带输入数据
*
* @param apiUrl
* @return
*/
public static RiskHttpResponse doPost(String apiUrl) {
return doPost(apiUrl, new HashMap<String, Object>());
}
/**
* 发送 POST 请求(HTTP),K-V形式
*
* @param apiUrl API接口URL
* @param params 参数map
* @return
*/
public static RiskHttpResponse doPost(String apiUrl, Map<String, Object> params) {
//CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
httpClient = getHttpClient();
HttpPost httpPost = new HttpPost(apiUrl);
try {
List<NameValuePair> pairList = new ArrayList<>(params.size());
for (Map.Entry<String, Object> entry : params.entrySet()) {
NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry
.getValue().toString());
pairList.add(pair);
}
httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("UTF-8")));
HttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
JSONObject jsonObject = JSONObject.parseObject(EntityUtils.toString(entity));
EntityUtils.consume(entity);
return new RiskHttpResponse(jsonObject,statusCode);
} catch (IOException e) {
log.error("方法doPost调用异常, apiUrl: "+apiUrl+"请求失败", e);
// throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_FAIL,e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, e.toString() + ";url:"+apiUrl);
} finally {
httpPost.releaseConnection();
}
}
/**
* 发送 POST 请求(HTTP),JSON形式
*
* @param apiUrl
* @param json json对象
* @return
*/
public static RiskHttpResponse doPost(String apiUrl, JSONObject json) {
httpClient = getHttpClient();
// CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
HttpPost httpPost = new HttpPost(apiUrl);
try {
httpPost.setConfig(requestConfig);
StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");//解决中文乱码问题
stringEntity.setContentEncoding("UTF-8");
stringEntity.setContentType("application/json");
httpPost.setEntity(stringEntity);
HttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
JSONObject jsonObject = JSONObject.parseObject(EntityUtils.toString(entity));
EntityUtils.consume(entity);
return new RiskHttpResponse(jsonObject,statusCode);
} catch (IOException e) {
log.error("方法doPost2调用异常, apiUrl: "+apiUrl+"请求失败", e);
// throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_FAIL,e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, e.toString() + ";url:"+apiUrl);
} finally {
httpPost.releaseConnection();
}
}
public static RiskHttpResponse doGzipHttp(String url, JSONObject jsonObject) {
httpClient = getHttpClient();
//CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Content-Type", "text/plain");
httpPost.setHeader("Content-Encoding", "gzip");
try {
String message = JSON.toJSONString(jsonObject);
ByteArrayOutputStream originalContent = new ByteArrayOutputStream();
originalContent.write(message.getBytes(Charset.forName("UTF-8")));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzipOut = new GZIPOutputStream(baos);
originalContent.writeTo(gzipOut);
gzipOut.finish();
httpPost.setEntity(new ByteArrayEntity(baos.toByteArray()));
HttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
JSONObject object = JSONObject.parseObject(EntityUtils.toString(entity));
EntityUtils.consume(entity);
return new RiskHttpResponse(object, statusCode);
} catch (Exception e) {
log.error("方法doGzipHttp调用异常, apiUrl: "+url+"请求失败", e);
// throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_FAIL,e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, e.toString() + ";url:"+url);
} finally {
httpPost.releaseConnection();
}
}
public static RiskHttpResponse doGzipPost(String url,JSONObject jsonObject) {
try {
URL parsedUrl = new URL(url);
HttpURLConnection connection = (HttpURLConnection) parsedUrl.openConnection();
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.addRequestProperty("Content-Type", "text/plain");
connection.addRequestProperty("Content-Encoding","gzip");
connection.setDoOutput(true);
String bodyStr = JSON.toJSONString(jsonObject);
byte[] body = bodyStr.getBytes("UTF-8");
if (body != null) {
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
GZIPOutputStream gzip = new GZIPOutputStream(out);
gzip.write(body);
gzip.finish();
gzip.close();
}
connection.connect();
RiskHttpResponse response = new RiskHttpResponse();
int responseCode = connection.getResponseCode();
response.setCode(responseCode);
if (responseCode != HttpURLConnection.HTTP_OK) {
String responseData = getContent(connection.getErrorStream());
response.setJsonObject(JSONObject.parseObject(responseData));
} else {
String responseData = getContent(connection.getInputStream());
response.setJsonObject(JSONObject.parseObject(responseData));
}
return response;
} catch (Exception e) {
log.error("方法doGzipPost调用异常, apiUrl: "+url+"请求失败", e);
// throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_FAIL,e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, e.toString() + ";url:"+url);
}
}
private static String getContent(InputStream in) {
StringBuffer sb = new StringBuffer();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(in, "utf-8"));
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
/**
* 发送 SSL POST 请求(HTTPS),K-V形式
*
* @param apiUrl API接口URL
* @param params 参数map
* @return
*/
public static String doPostSSL(String apiUrl, Map<String, Object> params) {
httpClient = getHttpClient();
// CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();
HttpPost httpPost = new HttpPost(apiUrl);
CloseableHttpResponse response = null;
String httpStr = null;
try {
httpPost.setConfig(requestConfig);
List<NameValuePair> pairList = new ArrayList<NameValuePair>(params.size());
for (Map.Entry<String, Object> entry : params.entrySet()) {
NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry
.getValue().toString());
pairList.add(pair);
}
httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("utf-8")));
response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
return null;
}
HttpEntity entity = response.getEntity();
if (entity == null) {
return null;
}
httpStr = EntityUtils.toString(entity, "utf-8");
} catch (Exception e) {
log.error("方法doPostSSL调用异常, apiUrl: "+apiUrl+"请求失败", e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, e.toString() + ";url:"+apiUrl);
} finally {
if (response != null) {
try {
EntityUtils.consume(response.getEntity());
} catch (IOException e) {
e.printStackTrace();
}
}
}
return httpStr;
}
/**
* 发送 SSL POST 请求(HTTPS),K-V形式
*
* @param apiUrl API接口URL
* @param params 参数map
* @return
*/
public static String doPostSSL(String apiUrl, Map<String, String> headers, Map<String, String> params) {
httpClient = getHttpClient();
// CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();
HttpPost httpPost = new HttpPost(apiUrl);
CloseableHttpResponse response = null;
String httpStr = null;
try {
headers.forEach(httpPost::addHeader);
httpPost.setConfig(requestConfig);
StringBuilder sb = new StringBuilder("{");
params.forEach((a, b) -> {
sb.append("\"" + a + "\"" + ":\"" + b + "\",");
});
String body = sb.substring(0, sb.length() - 1) + "}";
httpPost.setEntity(new StringEntity(body));
response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
// if (statusCode != HttpStatus.SC_OK) {
// return null;
// }
HttpEntity entity = response.getEntity();
// if (entity == null) {
// return null;
// }
httpStr = EntityUtils.toString(entity, "utf-8");
} catch (Exception e) {
log.error("方法doPostSSL2调用异常, apiUrl: "+apiUrl+"请求失败", e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, e.toString() + ";url:"+apiUrl);
} finally {
if (response != null) {
try {
EntityUtils.consume(response.getEntity());
} catch (IOException e) {
e.printStackTrace();
}
}
}
return httpStr;
}
/**
* 发送 SSL POST 请求(HTTPS),JSON形式
*
* @param apiUrl API接口URL
* @param json JSON对象
* @return
*/
public static String doPostSSL(String apiUrl, JSONObject json) {
httpClient = getHttpClient();
// CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();
HttpPost httpPost = new HttpPost(apiUrl);
CloseableHttpResponse response = null;
String httpStr = null;
try {
httpPost.setConfig(requestConfig);
StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");//解决中文乱码问题
stringEntity.setContentEncoding("UTF-8");
stringEntity.setContentType("application/json");
httpPost.setEntity(stringEntity);
response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
return null;
}
HttpEntity entity = response.getEntity();
if (entity == null) {
return null;
}
httpStr = EntityUtils.toString(entity, "utf-8");
} catch (Exception e) {
log.error("方法doPostSSL3调用异常, apiUrl: "+apiUrl+"请求失败", e);
// throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_FAIL,e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, e.toString() + ";url:"+apiUrl);
} finally {
if (response != null) {
try {
EntityUtils.consume(response.getEntity());
} catch (IOException e) {
e.printStackTrace();
}
}
}
return httpStr;
}
/**
* 创建SSL安全连接
*
* @return
*/
private static SSLConnectionSocketFactory createSSLConnSocketFactory() {
SSLConnectionSocketFactory sslsf = null;
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
@Override
public void verify(String host, SSLSocket ssl) throws IOException {
}
@Override
public void verify(String host, X509Certificate cert) throws SSLException {
}
@Override
public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
}
});
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
return sslsf;
}
/**
* 描述: FaceID风控服务-多头API post请求调用 <br/>
* 参数: [apiUrl, textMap] <br/>
* 返回值: java.util.Map<java.lang.String,java.lang.String> <br/>
* responseCode:http的返回code; content:返回的结果 <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.09.11 <br/>
*/
public static Map<String,String> doRiskInfoVerifyPost(String apiUrl, Map<String, String> textMap, String log_urlType) {
Map<String,String> resultMap = new HashMap<String,String>();
HttpURLConnection conn = null;
String BOUNDARY = "-----------12345654321-------------";
try {
// 设置请求参数
URL url = new URL(apiUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(10000);
conn.setReadTimeout(10000);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("User-Agent","Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)");
conn.setRequestProperty("Content-Type","multipart/form-data; boundary=" + BOUNDARY);
conn.setRequestProperty("Charset", "UTF-8");
OutputStream out = new DataOutputStream(conn.getOutputStream());
// 对File 和 String 集合进行判空
if (textMap != null) {
StringBuffer strBuf = new StringBuffer();
Iterator iter = textMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
String inputName = (String) entry.getKey();
String inputValue = (String) entry.getValue();
if (inputValue == null) {
continue;
}
strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
strBuf.append("Content-Disposition: form-data; name=\""+ inputName + "\"\r\n\r\n");
strBuf.append(inputValue);
}
out.write(strBuf.toString().getBytes("UTF-8"));
}
byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
out.write(endData);
out.flush();
out.close();
int responseCode = conn.getResponseCode();
String res = "";
if (responseCode == 200) {
// 读取正确返回信息
StringBuffer strBuf = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
strBuf.append(line).append("\n");
}
res = strBuf.toString();
reader.close();
reader = null;
} else {
// 读取错误返回信息
StringBuffer error = new StringBuffer();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
String line1 = null;
while ((line1 = bufferedReader.readLine()) != null) {
error.append(line1).append("\n");
}
res = error.toString();
bufferedReader.close();
bufferedReader = null;
}
//log.info("responseCode:"+responseCode+",msg="+res);
resultMap.put("responseCode",""+responseCode);
resultMap.put("content",res);
} catch (Exception e) {
log.error("方法doRiskInfoVerifyPost调用异常, urlType="+log_urlType+", apiUrl: "+apiUrl+"发送POST请求失败", e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, log_urlType+":"+e.toString());
} finally {
// 关闭流
if (conn != null) {
conn.disconnect();
conn = null;
}
}
return resultMap;
}
/**
* 描述: 木槿科技借贷风险名单查询 get请求 <br/>
* 参数: [inUrl] <br/>
* 返回值: java.lang.String <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.09.17 <br/>
*/
public static String muJinReadByGet(String apiUrl,String log_urlType) {
StringBuffer sbf = new StringBuffer();
String strRead = null;
// 模拟浏览器
String userAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36";
HttpURLConnection connection = null;
try {
// 连接URL地址
URL url = new URL(apiUrl);
// 根据拼凑的URL,打开连接,URL.openConnection函数会根据URL的类型,返回不同的URLConnection子类的对象,这里URL是一个http,因此实际返回的是HttpURLConnection
connection = (HttpURLConnection) url.openConnection();
// 设置连接访问方法及超时参数
connection.setRequestMethod("GET");
connection.setReadTimeout(30000);
connection.setConnectTimeout(30000);
connection.setRequestProperty("User-agent", userAgent);
// 进行连接,但是实际上get request要在下一句的connection.getInputStream()函数中才会真正发到 服务器
connection.connect();
// 取得输入流,并使用Reader读取
InputStream is = connection.getInputStream();
// 读取数据编码处理
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
while ((strRead = reader.readLine()) != null) {
sbf.append(strRead);
}
reader.close();
}catch (IOException e) {
log.error("方法muJinReadByGet调用异常, urlType="+log_urlType+", apiUrl: "+apiUrl+"发送GET请求失败", e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, log_urlType+":"+e.toString());
} finally {
// 关闭流
if (connection != null) {
// 断开连接
connection.disconnect();
connection=null;
}
}
return sbf.toString();
}
/**
* 描述: SSLContext方式的 融慧量化派定制化模型 get请求 <br/>
* 参数: [inUrl:请求地址; jsonParam:参数; log_urlType:请求的业务模块,方便排查问题] <br/>
* 返回值: java.lang.String <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.09.20 <br/>
*/
public static String remoteCall(String apiUrl, String jsonParam,String log_urlType) {
if(log_urlType==null){
log_urlType = "";
}
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
try {
// 信任所有
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
SSLConnectionSocketFactory sslCSF = new SSLConnectionSocketFactory(sslContext,SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
httpClient = HttpClients.custom().setSSLSocketFactory(sslCSF).build();
HttpPost post = new HttpPost(apiUrl);
StringEntity s = new StringEntity(jsonParam, "UTF-8");
s.setContentType("application/json");
s.setContentEncoding("UTF-8");
post.setEntity(s);
response = httpClient.execute(post);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
// 获取响应实体
HttpEntity entity = response.getEntity();
if (entity != null) {
return EntityUtils.toString(entity, "UTF-8");
}
}else{
HttpEntity entity = response.getEntity();
String errorMsg = "";
if (entity != null) {
errorMsg = EntityUtils.toString(entity, "UTF-8");
}
log.warn("httpRequest urlType="+log_urlType+", apiUrl: {} , httpStatus: {} , errorMsg: {} ", apiUrl, response.getStatusLine().getStatusCode(),errorMsg);
}
} catch (Exception e) {
log.error("方法remoteCall调用异常, urlType="+log_urlType+", apiUrl: "+apiUrl+"发送GET请求失败", e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, log_urlType+":"+e.toString());
} finally {
try {
if (null != httpClient) {
httpClient.close();
}
if (null != response) {
response.close();
}
} catch (IOException e) {
log.error("httpRequest urlType="+log_urlType+", apiUrl: "+apiUrl+"关闭连接异常", e);
e.printStackTrace();
}
}
return null;
}
/**
* 描述: 发送 POST 请求(HTTP),JSON形式 <br/>
* 备注: 和RiskHttpResponse doPost(String apiUrl, JSONObject json)方法一样,只是新增了urlType,完了方便日志排查
* 参数: [apiUrl, json, log_urlType] <br/>
* 返回值: cn.quantgroup.risk.datasource.response.RiskHttpResponse <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.09.29 <br/>
*/
public static RiskHttpResponse doPost(String apiUrl, JSONObject json,String log_urlType) {
httpClient = getHttpClient();
// CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
HttpPost httpPost = new HttpPost(apiUrl);
try {
httpPost.setConfig(requestConfig);
StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");//解决中文乱码问题
stringEntity.setContentEncoding("UTF-8");
stringEntity.setContentType("application/json");
httpPost.setEntity(stringEntity);
HttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
JSONObject jsonObject = JSONObject.parseObject(EntityUtils.toString(entity));
EntityUtils.consume(entity);
return new RiskHttpResponse(jsonObject,statusCode);
} catch (IOException e) {
log.error("方法doPost3调用异常, urlType="+log_urlType+", apiUrl: "+apiUrl+"请求失败", e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, log_urlType+":"+e.toString());
} finally {
httpPost.releaseConnection();
}
}
public static String mySelfDoGet(String url, Map<String, Object> params) {
String apiUrl = url;
StringBuffer param = new StringBuffer();
int i = 0;
for (String key : params.keySet()) {
if (i == 0)
param.append("?");
else
param.append("&");
param.append(key).append("=").append(params.get(key));
i++;
}
apiUrl += param;
long startUtc = System.currentTimeMillis();
httpClient2 = getHttpClient();
HttpGet httpGet = new HttpGet(apiUrl);
try {
HttpResponse response = httpClient2.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
String context = EntityUtils.toString(entity,"utf-8");
EntityUtils.consume(entity);
return context;
} catch (Exception e){
long endtUtc = System.currentTimeMillis();
log.error("方法mySelfDoGet调用异常, apiUrl: "+apiUrl+"百行征信手动报送请求失败, cost: "+(endtUtc-startUtc)+".ms ", e);
}finally {
httpGet.releaseConnection();
}
return null;
}
/**
* 描述: 中互金 POST Content-Type:application/json;Charset=utf-8 <br/>
* 参数: [apiUrl, jsonObject, log_urlType] <br/>
* 返回值: java.lang.String <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.10.14 <br/>
*/
public static String doPostOfZhongHuJin(String apiUrl,JSONObject jsonObject,String log_urlType) {
String response = "";
try {
String bodyStr = JSON.toJSONString(jsonObject);
byte[] body = bodyStr.getBytes("UTF-8");
URL parsedUrl = new URL(apiUrl);
HttpURLConnection conn = (HttpURLConnection) parsedUrl.openConnection();
conn.setConnectTimeout(5000);
conn.setReadTimeout(10000);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Connection", "keep-alive");
conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
conn.setRequestProperty("Content-Length", String.valueOf(body.length));
OutputStream outStream = conn.getOutputStream();
outStream.write(body);
outStream.flush();
outStream.close();
if(conn.getResponseCode() == 200){
BufferedReader in = new BufferedReader(new InputStreamReader((InputStream) conn.getInputStream(), "UTF-8"));
response = in.readLine();
in.close();
}
conn.disconnect();
return response;
} catch (Exception e) {
log.error("方法doPostOfZhongHuJin调用异常, urlType="+log_urlType+", apiUrl: "+apiUrl+"请求失败", e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, e.toString()+";url="+apiUrl);
}
}
/**
* 描述: 孚临科技有限公司犀分查询
* application/json的Post线程池请求,有检查机制 <br/>
* 参数: [apiUrl, jsonParam, log_urlType] <br/>
* 返回值: java.lang.String <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.10.30 <br/>
*/
public static String doPostOfCheck(String apiUrl,String jsonParam,String log_urlType) {
String result = null;
httpClient_check = getHttpClientOfcheck();
HttpPost httpPost = new HttpPost(apiUrl);
try {
httpPost.setConfig(requestConfig);
StringEntity stringEntity = new StringEntity(jsonParam, "UTF-8");//解决中文乱码问题
stringEntity.setContentEncoding("UTF-8");
stringEntity.setContentType("application/json");
httpPost.setEntity(stringEntity);
HttpResponse response = httpClient_check.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if(statusCode == 200){
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity);
EntityUtils.consume(entity);
}else{
throw new IOException("HTTP Request is fail, code is " + statusCode);
}
} catch (IOException e) {
log.error("方法doPostOfCheck调用异常, urlType="+log_urlType+", apiUrl: "+apiUrl+"请求失败", e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, e.toString()+";url="+apiUrl);
} finally {
httpPost.releaseConnection();
}
return result;
}
public static String doPostOfFuLin(String apiUrl,String jsonParam,String log_urlType) {
OutputStream outputStream = null;
OutputStreamWriter outputStreamWriter = null;
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader reader = null;
StringBuilder resultBuffer = new StringBuilder();
String tempLine = null;
try {
URL localURL = new URL(apiUrl);
URLConnection connection = localURL.openConnection();
HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
httpURLConnection.setDoOutput(true);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Accept-Charset", "utf-8");
httpURLConnection.setRequestProperty("Content-Type", "application/json");
httpURLConnection.setRequestProperty("Content-Length", String.valueOf(jsonParam.length()));
// 读取数据超时时间
httpURLConnection.setReadTimeout(5000);
// 连接主机超时时间
httpURLConnection.setConnectTimeout(10000);
outputStream = httpURLConnection.getOutputStream();
outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");
outputStreamWriter.write(jsonParam.toString());
outputStreamWriter.flush();
if (httpURLConnection.getResponseCode() >= 300) {
throw new Exception(
"HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode());
}
inputStream = httpURLConnection.getInputStream();
inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
reader = new BufferedReader(inputStreamReader);
while ((tempLine = reader.readLine()) != null) {
resultBuffer.append(tempLine);
}
} catch (Exception e) {
log.error("方法doPostOfFuLin调用异常, urlType="+log_urlType+", apiUrl: "+apiUrl+"请求失败", e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, e.toString()+";url="+apiUrl);
} finally {
try{
if (outputStreamWriter != null) {
outputStreamWriter.close();
}
if (outputStream != null) {
outputStream.close();
}
if (reader != null) {
reader.close();
}
if (inputStreamReader != null) {
inputStreamReader.close();
}
if (inputStream != null) {
inputStream.close();
}
}catch (Exception e){
log.error("doPost方法关闭流异常.",e);
}
}
return resultBuffer.toString();
}
/**
* 中智诚黑名单专用
* @param apiUrl
* @param headers
* @param params
* @return
*/
public static CloseableHttpResponse doPostSSLForZZC(String apiUrl, Map<String, String> headers, Map<String, String> params) {
httpClient = getHttpClient();
HttpPost httpPost = new HttpPost(apiUrl);
CloseableHttpResponse response = null;
try {
headers.forEach(httpPost::addHeader);
httpPost.setConfig(requestConfig);
StringEntity stringEntity = new StringEntity(JSON.toJSONString(params), "UTF-8");//解决中文乱码问题
stringEntity.setContentEncoding("UTF-8");
stringEntity.setContentType("application/json");
httpPost.setEntity(stringEntity);
response = httpClient.execute(httpPost);
} catch (Exception e) {
log.error("方法doPostSSLForZZC调用异常, apiUrl: "+apiUrl+"请求失败", e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, e.toString() + ";url:"+apiUrl);
}finally {
httpPost.releaseConnection();
}
return response;
}/**
* 51征信
* @param apiUrl
* @return
*/
public static JSONObject doPostSSLFor51(String apiUrl, Map<String, Object> params) {
httpClient = getHttpClient();
HttpPost httpPost = new HttpPost(apiUrl);
CloseableHttpResponse response = null;
try {
httpPost.setConfig(requestConfig);
StringEntity stringEntity = new StringEntity(JSON.toJSONString(params),ContentType.APPLICATION_JSON);//
httpPost.setEntity(stringEntity);
response = httpClient.execute(httpPost);
if (response.getStatusLine().getStatusCode() != 200) {
throw new Exception(
"HTTP Request is not success, Response code is " + response.getStatusLine().getStatusCode());
}
HttpEntity entity = response.getEntity();
if (null == entity) {
throw new Exception(
"response is null ");
}
String s = EntityUtils.toString(entity);
try {
return JSON.parseObject(s);
} catch (Exception e) {
throw new Exception(
"报文解析失败,result=" + s);
}
} catch (Exception e) {
log.error("方法doPostSSLFor51调用异常, apiUrl: " + apiUrl + "请求失败", e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, e.getMessage() == null ? e.toString() : e.getMessage() + ";url:" + apiUrl);
} finally {
httpPost.releaseConnection();
}
}
/**
* 发送 POST 请求(HTTP),K-V形式
*
* @param apiUrl API接口URL
* @param params 参数map
* @return
*/
public static String doPost(String apiUrl, Map<String, String> params, String log_urlType) {
//CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
httpClient = getHttpClient();
HttpPost httpPost = new HttpPost(apiUrl);
try {
List<NameValuePair> pairList = new ArrayList<>(params.size());
for (Map.Entry<String, String> entry : params.entrySet()) {
NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry
.getValue().toString());
pairList.add(pair);
}
httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("UTF-8")));
HttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity);
EntityUtils.consume(entity);
log.info("httpRequest urlType: {} , params: {} , statusCode: {} ",log_urlType, JSON.toJSONString(params), statusCode);
return result;
} catch (IOException e) {
log.error("方法doPost4调用异常, urlType="+log_urlType+", apiUrl: "+apiUrl+"请求失败", e);
throw new QGException(QGExceptionType.COMMON_THIRD_PART_CALL_EXCEPTION, e.toString() + ";url:"+apiUrl);
} finally {
httpPost.releaseConnection();
}
}
}
/*
* Copyright 2014-present Miyou tech inc. All Rights Reserved.
*/
package cn.quantgroup.qgblservice.utils.http;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.SocketTimeoutException;
import java.util.Arrays;
import static cn.quantgroup.qgblservice.utils.http.QGExceptionType.COMMON_SERVER_ERROR;
import static cn.quantgroup.qgblservice.utils.http.QGExceptionType.COMMON_THIRD_PARTY_TIMEOUT;
public class QGException extends RuntimeException {
private static final Logger LOGGER = LoggerFactory.getLogger(QGException.class);
public QGExceptionType qgExceptionType;
public boolean isToastFormat = false;
public String detail;
public QGException(String detail, QGExceptionType qgExceptionType, Object... args) {
super(detail);
try {
if (StringUtils.isNoneBlank(qgExceptionType.frontEndToastTemplate)) {
isToastFormat = true;
initException(String.format(qgExceptionType.frontEndToastTemplate, args), qgExceptionType);
} else {
initException(qgExceptionType);
}
} catch (Exception e) {
LOGGER.error("format front end toast err, " + qgExceptionType + ", args: " + Arrays.toString(args), e);
initException(COMMON_SERVER_ERROR);
}
}
public QGException(QGExceptionType qgExceptionType, Object... args) {
super(qgExceptionType.text);
try {
if (StringUtils.isNoneBlank(qgExceptionType.frontEndToastTemplate)) {
isToastFormat = true;
initException(String.format(qgExceptionType.frontEndToastTemplate, args), qgExceptionType);
} else {
initException(qgExceptionType);
}
} catch (Exception e) {
LOGGER.error("format front end toast err, " + qgExceptionType + ", args: " + Arrays.toString(args), e);
initException(COMMON_SERVER_ERROR);
}
}
public QGException(String detail, Throwable cause, QGExceptionType qgExceptionType) {
super(detail, cause);
this.initException(detail, qgExceptionType);
}
public QGException(String detail, QGExceptionType qgExceptionType) {
super(detail);
initException(detail, qgExceptionType);
}
public QGException(QGExceptionType qgExceptionType) {
super(qgExceptionType.text);
initException(qgExceptionType);
}
public QGException(Throwable cause, QGExceptionType qgExceptionType, Object... args) {
super(qgExceptionType.text, cause);
try {
if (StringUtils.isNoneBlank(qgExceptionType.frontEndToastTemplate)) {
isToastFormat = true;
initException(String.format(qgExceptionType.frontEndToastTemplate, args), qgExceptionType);
} else {
initException(qgExceptionType);
}
} catch (Exception e) {
LOGGER.error("format front end toast err, " + qgExceptionType + ", args: " + Arrays.toString(args), e);
initException(COMMON_SERVER_ERROR);
}
}
public static QGException wrap(Throwable e) {
return wrap(e, COMMON_SERVER_ERROR);
}
public static QGException wrap(Throwable e, QGExceptionType exceptionType) {
if (e instanceof QGException) {
return (QGException) e;
}
if (e instanceof SocketTimeoutException)
return new QGException(COMMON_THIRD_PARTY_TIMEOUT);
return new QGException(e, exceptionType);
}
public static QGException wrap(Throwable e, QGExceptionType exceptionType, Object... args) {
if (e instanceof QGException) {
return (QGException) e;
}
if (e instanceof SocketTimeoutException)
return new QGException(COMMON_THIRD_PARTY_TIMEOUT);
return new QGException(e, exceptionType, args);
}
private void initException(QGExceptionType QGExceptionType) {
this.initException(QGExceptionType.text, QGExceptionType);
}
private void initException(String detail, QGExceptionType QGExceptionType) {
this.qgExceptionType = QGExceptionType;
this.detail = detail;
}
}
\ No newline at end of file
/*
* Copyright 2014-present Miyou tech inc. All Rights Reserved.
*/
package cn.quantgroup.qgblservice.utils.http;
import lombok.extern.slf4j.Slf4j;
/**
* 系统使用Exception来进行Error Code处理。如果LogType为Error,
* 代表这种Error不应该返回给客户端,应该统一打印出服务器端错误;
* 如果是WARNING的话,就将对应的Exception Text返回给客户端。
*/
@Slf4j
public enum QGExceptionType {
COMMON_SERVER_ERROR(1001, "系统异常,请稍后再试"),
COMMON_ILLEGAL_STATE(1002, "断言错误"),
COMMON_ILLEGAL_PARAM_TOAST(1003, "参数异常", "%s"),
COMMON_AUTH_ERROR(1004, "系统异常,请稍后再试"),
COMMON_ILLEGAL_PARAM(1010, "参数异常"),
COMMON_THIRD_PARTY_TIMEOUT(1011, "第三方服务超时"),
COMMON_INVALID_PARAM(1012, "参数错误"),
COMMON_ID_INVALID(1013, "id数据非法"),
COMMON_STRING_PARAM_GREATER_THAN_LENGTH(1014, "参数的长度过长", "%s的长度不能大于%s"),
COMMON_STRING_PARAM_IS_ALL_NULL(1015, "参数不能为空", "%s不能为空"),
COMMON_STRING_PARAM_IS_NULL(1016, "参数不能同时为空", "%s不能同时为空"),
COMMON_THIRD_PARTY_ERROR(1017, "第三方服务报错", "第三方服务报错,错误编码:%s,错误提示:%s"),
COMMON_THIRD_PART_CALL_EXCEPTION(3001,"第三方服务调用异常", "异常信息:%s"),
;
public int code;
public String text;
public String frontEndToastTemplate;
QGExceptionType(int code, String text) {
this.code = code;
this.text = text;
this.frontEndToastTemplate = text;
}
QGExceptionType(int code, String text, String frontEndToastTemplate) {
this.code = code;
this.text = text;
this.frontEndToastTemplate = frontEndToastTemplate;
}
public static QGExceptionType fromCode(int code) {
for (QGExceptionType exceptionType : QGExceptionType.values()) {
if (exceptionType.code == code) {
return exceptionType;
}
}
return null;
}
@Override
public String toString() {
return "error_code: " + code + ", text: " + text + ", frontEndToastTemplate: " + frontEndToastTemplate;
}
}
package cn.quantgroup.qgblservice.utils.http;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
/**
* Created by suh on 2017/12/18.
*/
@Data
public class RiskHttpResponse {
private int code;
private JSONObject jsonObject;
public RiskHttpResponse(JSONObject jsonObject, int code){
this.jsonObject = jsonObject;
this.code = code;
}
public RiskHttpResponse(){}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment