一种后台文件处理进度的简单实现方式

一种后台文件处理进度回显的简单实现方案

  1. 前段时间收到,客户反馈看不到前端上传大量文件给后端处理的实时进度,不知道啥时候能够处理完,为此添加了后台批处理实时进度的回显

  2. 这里采用的是前端短轮询传入文件名,到后台接口查询实时进度,这里只提供后台代码的简单实现

  3. 代码:

    1. 在controller层添加ConcurrentHashMap存储处理进度,由于添加了static关键字,所以可以在多个调用线程之间共享

      /**
       * 文件正在处理标识,key=上传压缩包名称,value=正在处理进度.
       */
      public static Map<String,String> UPLOAD_STATISTIC_MAP = new ConcurrentHashMap<>();
      
    2. 在文件上传接收接口判断文件是否重复上传,并赋值处理进度0.00%

      //判断当前文件是否在处理
              if(UPLOAD_STATISTIC_MAP.containsKey(zipFileName)){
                  log.info("当前文件:"+zipFileName
                          +"正在处理中,请勿重复上传");
                  return BaseApiService.setResultError("当前文件:"+zipFileName
                          +"正在处理中,请勿重复上传");
              }
              UPLOAD_STATISTIC_MAP.put(zipFileName,"0.00%");
      
    3. 在单个文件批处理逻辑处,每处理完一张文件,计算并更新进度

      //文件总数
      int count = files.size();
      //已经处理完文件数
      int nowSize = 0;
      
      //计算并更新处理进度
                      nowSize = nowSize+1;
                      BigDecimal a = new BigDecimal(nowSize);
                      BigDecimal b = new BigDecimal(count);
                      String divide = a.divide(b,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).setScale(2,BigDecimal.ROUND_HALF_UP).toString();
                      UPLOAD_STATISTIC_MAP.put(zipFileName,divide+"%");
      
    4. 文件处理结束,移除此文件

      //移除正在上传记录
      UPLOAD_STATISTIC_MAP.remove(zipFileName);
      
    5. 提供查询接口供前端短轮询回显

      @PostMapping("/progress")
          public String progress(String fileName) throws BussinessException {
              if (UPLOAD_STATISTIC_MAP.containsKey(fileName)){
                  return UPLOAD_STATISTIC_MAP.get(fileName);
              }else {
                  throw new BussinessException("未查询到"+fileName+":解析进度,请先上传文件");
              }
      
          }
      
  4. 这里只是最基础的短轮询实现,其他实现方式如WebSocket等这里不做示例

你可能感兴趣的:(java,java,spring,boot)