Java SpringBoot批量获取Minio中多个文件进行压缩成zip下载

FileController 接口请求为Post

java 复制代码
@RestController
@RequestMapping("/file")
@Api(tags = "file文件操作")
public class FileController {

    private static final Logger LOGGER = LoggerFactory.getLogger(FileController.class);

    @Autowired
    private IFileService fileService;
    @ApiOperation(value = "下载压缩文件Zip", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    @RequestMapping(value = "/downZipFile", produces = "application/octet-stream", method = RequestMethod.POST)
    public void downZipFile(@RequestBody ZipFileDto zipFileDto, HttpServletResponse response) {
        try {
            fileService.downZipFile(zipFileDto, response);
        } catch (Exception e) {
            new CommonResult().failed(e.getMessage());
        }
    }
}

ZipFileDto.java 入参实体类

java 复制代码
@Data
public class ZipFileDto {
    /**
     * 文件名称.zip
     */
    private String downName;

    private List<fileListDto> fileList;

    @Data
    public static class fileListDto {
        /**
         * 下载文件名称
         */
        private String fileName;
        /**
         * 下载文件路径
         */
        private String filePath;
    }
}

IFileService.java 接口层

java 复制代码
public interface IFileService {

    void downZipFile(ZipFileDto zipFileDto, HttpServletResponse response) throws Exception;

}

MinioFileServiceImpl.java 实现类

java 复制代码
@Service
public class MinioFileServiceImpl implements IFileService {

	private static final Logger LOGGER = LoggerFactory.getLogger(MinioFileServiceImpl.class);
	@Value("${minio.storageClass}")
	private String STORAGECLASS; //存储类型
	@Value("${minio.endpoint}")
	private String ENDPOINT; //连接地址
	@Value("${minio.bucketName}")
	private String BUCKET_NAME; //存储桶名称
	@Value("${minio.accessKey}")
	private String ACCESS_KEY; //用户名
	@Value("${minio.secretKey}")
	private String SECRET_KEY; //密码

	@Override
	public void downZipFile(ZipFileDto zipFileDto, HttpServletResponse response) throws Exception {
		try {
			// 获取minio中多个文件进行压缩成zip下载
			InputStream fis;
			MinioClient minioClient = new MinioClient(ENDPOINT, ACCESS_KEY, SECRET_KEY);
			String bucketName = BUCKET_NAME;
			ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
			try (ZipOutputStream zos = new ZipOutputStream(byteArrayOutputStream)) {
				for (ZipFileDto.fileListDto fileListDto : makeUnique(zipFileDto.getFileList())) {
					String filePath = StringUtils.substringAfter(fileListDto.getFilePath(), "/mall");
					try (InputStream is = minioClient.getObject(bucketName, filePath)) {
						zos.putNextEntry(new ZipEntry(fileListDto.getFileName()));
						byte[] buffer = new byte[1024];
						int len;
						while ((len = is.read(buffer)) > 0) {
							zos.write(buffer, 0, len);
						}
						zos.closeEntry();
					}
				}
			} catch (NoSuchAlgorithmException e) {
				throw new RuntimeException(e);
			} catch (InvalidKeyException e) {
				throw new RuntimeException(e);
			}
			// 从 ByteArrayOutputStream 获取字节数组
			byte[] zipData = byteArrayOutputStream.toByteArray();
			ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(zipData);
			fis = new BufferedInputStream(byteArrayInputStream);
			byte[] buffer = new byte[fis.available()];
			fis.read(buffer);
			fis.close();
			response.reset();
			// 设置response的Header
			response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(zipFileDto.getDownName(), "UTF-8"));
			OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
			response.setContentType("application/octet-stream;charset=UTF-8");
			toClient.write(buffer);
			toClient.flush();
			toClient.close();
		} catch (MinioException | IOException e) {
			e.printStackTrace();
			LOGGER.error(e.getMessage());
		}
	}


	public static List<ZipFileDto.fileListDto> makeUnique(List<ZipFileDto.fileListDto> fileListDtos) {
		Map<String, Integer> nameCount = new HashMap<>();
		List<ZipFileDto.fileListDto> uniqueNames = new ArrayList<>();
		fileListDtos.forEach(t->{
			ZipFileDto.fileListDto fileListDto=new ZipFileDto.fileListDto();
			String str = t.getFileName();
			int lastIndex = str.lastIndexOf(".");
			String suffix = str.substring(lastIndex + 1);
			String name = str.substring(0,lastIndex);
			if (nameCount.containsKey(name)) {
				nameCount.put(name, nameCount.get(name) + 1);
				fileListDto.setFilePath(t.getFilePath());
				fileListDto.setFileName(name + "(" + nameCount.get(name) + ")."+suffix);
				uniqueNames.add(fileListDto);
			} else {
				nameCount.put(name, 1);
				fileListDto.setFilePath(t.getFilePath());
				fileListDto.setFileName(name+"."+suffix);
				uniqueNames.add(fileListDto);
			}
		});
		return uniqueNames;
	}
}

项目yml配置

XML 复制代码
minio:
  storageClass: minio  # nfs/minio
  accessKey: minioadmin
  bucketName: mall
  endpoint: http://10.110.xx.xx:9000
  secretKey: minioadmin

下载后就是这样的

相关推荐
csbysj20202 小时前
CSS3 圆角
开发语言
IT 行者2 小时前
Spring Security Session 序列化策略分析
java·spring boot·后端·spring
__万波__2 小时前
二十三种设计模式(十六)--迭代器模式
java·设计模式·迭代器模式
消失的旧时光-19432 小时前
从 Kotlin 到 Flutter:架构迁移指南
开发语言·flutter·kotlin
IT 行者2 小时前
Spring Boot 4.0 整合Spring Security 7 后的统一异常处理指南
spring boot·后端·spring
phil zhang2 小时前
Celer:为大型C/C++项目打造的极简包管理器
开发语言·c++·elasticsearch
L Jiawen3 小时前
【Go · Gin】基础知识
开发语言·golang·gin
学博成3 小时前
在 Spring Boot 中使用 Kafka 并保证顺序性(Topic 分区为 100)的完整案例
spring boot·kafka
無欲無为4 小时前
Spring Boot 整合 RabbitMQ 详细指南:从入门到实战
spring boot·rabbitmq·java-rabbitmq