我们的项目中有1个场景需要下载图片然后转换为base64传输给第三方,由于下载比较耗时,加上转换base64已经导致文件大小增大,所以执行比较慢,修改为CompletableFuture来处理。
第一种是不关心返回结果的写法:
// 存储所有CompletableFuture的列表 List<CompletableFuture<?>> futures = new ArrayList<>(); // 循环创建请求 for (GicStyleImageRequest gicStyleImageRequest : targetData) { futures.add(sendRequest(gicStyleImageRequest)); } // 直接返回成功 return BaseResponseUtil.baseResponseSuccess(MSG_KEY + "处理成功", targetData);
private CompletableFuture<?> sendRequest(GicStyleImageRequest gicStyleImageRequest) { return CompletableFuture.runAsync(() -> { // 转换图片 convertImage(gicStyleImageRequest); // 请求参数 BusinessRequest<GicStyleRequest> request = new BusinessRequest<>(); // 按品牌获取对应店仓编码 String depotId = ConfigGicUtil.getDepotId(gicStyleImageRequest.getBrandCode()); // 设置请求地址 request.setUrl(GicApiEnums.updateStoreGoodsImage.getApiUrl()); // 设置请求token request.setToken(biz.queryToken(depotId)); request.setEntMicroSignal(biz.queryEntMicroSignal(depotId)); // 设置请求Json参数 request.getMap().put("goodsImageInfo", Collections.singletonList(JsonUtil.toJSONString(gicStyleImageRequest))); // 获取请求结果 String jsonResult = GICRequestUtil.gicPost(request); // 解析请求结果 GicUpdateStoreGoodsSpuImageResponse gicBaseResponse = JsonUtil.parseObject(jsonResult, GicUpdateStoreGoodsSpuImageResponse.class); // 是否为空 if (gicBaseResponse == null || gicBaseResponse.getUpdateStoreGoodsImage_response() == null) { log.info("达摩商品图片接口返回响应为空:{}", JSON.toJSONString(request)); return; } // 状态码是不是 1 if (!"1".equals(gicBaseResponse.getUpdateStoreGoodsImage_response().getResult())) { // 如果失败 log.info("达摩商品图片接口返回错误:{}", JSON.toJSONString(gicBaseResponse)); return; } // 成功上传 log.info("达摩商品图片接口调用成功:{}", JSON.toJSONString(gicBaseResponse)); }); }
第二种是需要返回结果的写法,需要supplyAsync而不是runAsync,改下sendRequest中的runAsync为supplyAsync即可,然后主线程等待任务执行完成,循环每个任务的结果即可
// 等待所有请求完成 CompletableFuture<?> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); try { allFutures.get(); // 等待所有请求完成,但不获取结果 } catch (InterruptedException | ExecutionException e) { return BaseResponseUtil.baseResponseFail(MSG_KEY + "处理过程存在失败", e.getMessage(), errorMap, successMap); } // 获取每个请求结果 for (CompletableFuture<GicUpdateStoreGoodsSpuImageResponse> future : futures) { try { GicUpdateStoreGoodsSpuImageResponse gicBaseResponse = future.get(); // 是否为空 if (gicBaseResponse == null || gicBaseResponse.getUpdateStoreGoodsImage_response() == null) { errorMap.add(GicBaseApiMsg.fail("达摩商品接口返回响应为空", "")); continue; } // 状态码是不是 1 if (!"1".equals(gicBaseResponse.getUpdateStoreGoodsImage_response().getResult())) { // 如果失败 errorMap.add(GicBaseApiMsg.fail("达摩商品接口返回错误:".concat(gicBaseResponse.getUpdateStoreGoodsImage_response().getCause()) , gicBaseResponse.getUpdateStoreGoodsImage_response())); continue; } // 成功数据 successMap.add(GicBaseApiMsg.succeed(gicBaseResponse.getUpdateStoreGoodsImage_response().getData(), gicBaseResponse)); } catch (InterruptedException | ExecutionException e) { errorMap.add(GicBaseApiMsg.fail("执行请求失败", e.getMessage())); } }
public class test { public static void main(String[] args) { &...
java一个类可以有多个构造方法,根据传参类型和个数来匹配执行哪个构造方法。public class Member { public Member(){  ...
java限制1个方法同一时间只能被一个线程访问public synchronized void setOrderPay(){ }加上synchronized 修饰符即可...
Java5 引入了一种主要用于数组的增强型 for 循环,类似js中的for inpublic class Member { public static void main(String[]&...
java判断字符是否是一个字母System.out.println(Character.isLetter('a'));java判断字符是否是一个数字System.out.println(Character.isDigit('0'));java判断字符是否是一个空白Sy...
在java中字符串属于对象,刚开始我就疑惑为什么int char等类型都是小写,结果String是大写,java太反人类,后来才知道String是对象。(1).java创建字符串String text = "net"; String tex...