http连接无法通过后端多次遍历的方式一个一个文件的下载,一次下载完成后连接就断开了,所以必须把多个文件压缩后输出





  @ApiOperation(value = "批量文件下载", notes = "批量文件下载")
  @RequestMapping(value = "/bigdossierDownload", method = RequestMethod.POST)
  public APIResult bigdossierDownload(@RequestBody @Valid BigDossierDownloadRequestDTO bigDossierDownloadRequestDTO,
      HttpServletResponse response) throws Exception {
    log.info(bigDossierDownloadRequestDTO.getCaseId() + "***" + bigDossierDownloadRequestDTO.getFileId().size());
    List<String> list = bigDossierDownloadRequestDTO.getFileId();
    //存放--服务器上zip文件的目录
    String directory = "/data/storage" + File.separator + "temp";
//    String directory = "D:\\data" + File.separator + "temp"; //本地测试
    log.info(" server zip directory:" + directory);
    File directoryFile = new File(directory);
    if (!directoryFile.isDirectory() && !directoryFile.exists()) {
      directoryFile.mkdirs();
    }
    //设置最终输出zip文件的目录+文件名
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
    String zipFileName = formatter.format(new Date()) + ".zip";
    String strZipPath = directory + File.separator + zipFileName;
    ZipOutputStream zipStream = null;
    FileInputStream zipSource = null;
    BufferedInputStream bufferStream = null;
    File zipFile = new File(strZipPath);
    try {
      //构造最终压缩包的输出流
      zipStream = new ZipOutputStream(new FileOutputStream(zipFile));
      for (int i = 0; i < list.size(); i++) {
        //解码获取真实路径与文件名
        // 调文件服务器
        DubboResult<FileInfoResponseDTO> fileInfo = fileStorageApi.getFileInfo(list.get(i));
        log.info("FileName():" + fileInfo.getData().getFileName() + "filepath:" + fileInfo.getData().getFilePath());
        String realFileName = fileInfo.getData().getFileName();
        String realFilePath = fileInfo.getData().getFilePath();
//        String realFilePath = "D:\\data" + File.separator +  list.get(i); //本地测试
        File file = new File(realFilePath);
        if (file.exists()) {
          zipSource = new FileInputStream(file); //将需要压缩的文件格式化为输入流
          /**
           * 压缩条目不是具体独立的文件,而是压缩包文件列表中的列表项,称为条目,就像索引一样这里的name就是文件名,
           * 文件名和之前的重复就会导致文件被覆盖
           */
          ZipEntry zipEntry = new ZipEntry(realFileName); //在压缩目录中文件的名字
          zipStream.putNextEntry(zipEntry); //定位该压缩条目位置,开始写入文件到压缩包中
          bufferStream = new BufferedInputStream(zipSource, 1024 * 10);
          int read = 0;
          byte[] buf = new byte[1024 * 10];
          while ((read = bufferStream.read(buf, 0, 1024 * 10)) != -1) {
            zipStream.write(buf, 0, read);
          }
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      //关闭流
      if (null != bufferStream) {
        bufferStream.close();
      }
      if (null != zipStream) {
        zipStream.flush();
        zipStream.close();
      }
      if (null != zipSource) {
        zipSource.close();
      }
    }
    log.info("zipFileName:" + zipFileName + "  strZipPath:" + strZipPath);
    if (zipFile.exists()) {
      downFile(response, zipFileName, strZipPath);
      zipFile.delete();
    }
    log.info("big upload end");
    return  null;
  }

请求参数:

@Data
@ApiModel(description = "批量下载文件请求参数")
public class BigDossierDownloadRequestDTO implements Serializable {

  private static final long serialVersionUID = 1L;
  @ApiModelProperty(notes = "recordId", required = true, example = "666")
  @NotNull(message = "记录ID参数为空")
  private Long recordId;
  @ApiModelProperty(notes = "文件IDs", required = false, example = "['53348bbf7f3f450aad61d3dc20544f10','53348bbf7f3f450aad61d3dc20544f10']")
  private List<String> fileId;

}