SpringBoot流式打包并返回Zip文件
本文最后更新于 485 天前,其中的信息可能已经有所发展或是发生改变。

实体类

@Data
public class File implements Serializable {
    @Serial
    private static final long serialVersionUID = -8010947317726351477L;

    /**
     * 文件名
     */
    private String name;


    /**
     * 文件地址
     */
    private String objectName;

    /**
     * 文件地址
     */
    private String url;
}

Zip工具方法

MinIO

    /**
     * 打包下载文件
     * 已知问题:
     *  在下载时浏览器不会显示文下载进度
     * @param response HttpServletResponse
     * @param files List<File> File实体类
     * @param zipName 返回的zip文件名
     */
    public void downloadPackFileMinIO(@NotNull HttpServletResponse response,
                                 @NotNull List<File> files,
                                 @NotNull String zipName) throws IOException {
        if (files.isEmpty()) {
            throw new RuntimeException("文件不存在!");
        }
        response.reset();
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        String headerFilename = "filename=\""+zipName+"\"; filename*=utf-8''"
                + URLEncoder.encode(zipName, StandardCharsets.UTF_8);
        response.addHeader("Content-disposition", "attachment; " + headerFilename);

        MinioClient minioClient = MinioClient.builder()
                .endpoint(endpoint)
                .credentials(accessKeyId, accessKeySecret)
                .build();
        try {
            if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
                throw new LocalRuntimeException("Bucket不存在!");
            }
        } catch (IOException | NoSuchAlgorithmException | InvalidKeyException | ErrorResponseException |
                 InsufficientDataException | InternalException | InvalidResponseException | ServerException |
                 XmlParserException e) {
            e.printStackTrace();
            throw new RuntimeException("文件下载失败!");
        }

        ServletOutputStream outputStream = response.getOutputStream();
        ZipArchiveOutputStream zipStream = new ZipArchiveOutputStream(outputStream);
        zipStream.setUseZip64(Zip64Mode.AsNeeded);
        for (File file : files) {
            log.info("获取MinIO中文件的比特流,文件地址:{}", file.getName());
            String objectName = file.getObjectName();
            try (GetObjectResponse content = minioClient.getObject(GetObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .build())) {
                ArchiveEntry entry = new ZipArchiveEntry(file.getName());
                zipStream.putArchiveEntry(entry);
                byte[] buffer = new byte[1024];
                int len;
                while ((len = content.read(buffer)) != -1) {
                    zipStream.write(buffer, 0, len);
                }
                zipStream.closeArchiveEntry();
            } catch (IOException | NoSuchAlgorithmException | InvalidKeyException | ErrorResponseException |
                     InsufficientDataException | InternalException | InvalidResponseException | ServerException |
                     XmlParserException e) {
                e.printStackTrace();
                throw new RuntimeException("文件下载失败!");
            }
        }
        zipStream.close();
    }

阿里云OSS

/**
     * 打包下载文件
     * 已知问题:
     *  在下载时浏览器不会显示文下载进度
     * @param response HttpServletResponse
     * @param files List<File> File实体类
     * @param zipName 返回的zip文件名
     */
    public void downloadPackFileOSS(@NotNull HttpServletResponse response,
                                 @NotNull List<File> files,
                                 @NotNull String zipName) throws IOException {
        if (files.isEmpty()) {
            throw new LocalRuntimeException("文件不存在!");
        }
        response.reset();
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        String headerFilename = "filename=\""+zipName+"\"; filename*=utf-8''"
                + URLEncoder.encode(zipName, StandardCharsets.UTF_8);
        response.addHeader("Content-disposition", "attachment; " + headerFilename);

        ServletOutputStream outputStream = response.getOutputStream();
        ZipArchiveOutputStream zipStream = new ZipArchiveOutputStream(outputStream);
        zipStream.setUseZip64(Zip64Mode.AsNeeded);
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        for (File file : files) {
            log.info("获取OSS中文件的比特流,文件地址:{}", file.getUrl());
            String objectName = file.getObjectName();
            if (!ossClient.doesBucketExist(bucketName)) {
                throw new RuntimeException("Bucket不存在!");
            }
            if (!ossClient.doesObjectExist(bucketName, objectName)) {
                throw new RuntimeException("文件不存在!");
            }
            OSSObject ossObject = ossClient.getObject(bucketName, objectName);
            try (InputStream content = ossObject.getObjectContent()) {
                ArchiveEntry entry = new ZipArchiveEntry(file.getName());
                zipStream.putArchiveEntry(entry);
                byte[] buffer = new byte[1024];
                int len;
                while ((len = content.read(buffer)) != -1) {
                    zipStream.write(buffer, 0, len);
                }
                zipStream.closeArchiveEntry();
            } catch (OSSException oe) {
                log.error("Error Message:" + oe.getErrorMessage());
                log.error("Error Code:" + oe.getErrorCode());
                log.error("Request ID:" + oe.getRequestId());
                log.error("Host ID:" + oe.getHostId());
                throw new RuntimeException("文件下载失败!");
            } catch (ClientException ce) {
                log.error("Error Message:" + ce.getMessage());
                throw new RuntimeException("文件下载失败!");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        ossClient.shutdown();
        zipStream.close();
    }
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇