springboot 使用zip4j下载压缩包,压缩包内的数据来自oss文件管理服务器

pom引入zip4j的包

复制代码
      <zip4j.version>2.11.1</zip4j.version>
      <dependency>
        <groupId>net.lingala.zip4j</groupId>
        <artifactId>zip4j</artifactId>
        <version>${zip4j.version}</version>
      </dependency>

两种写法,一种是传统写法

复制代码
@GetMapping(value = {"/companyFileExportZip/{companyId}"})
    @ApiOperation("丰台-演出团队附件批量导出")
    public void companyFileExportZip(@PathVariable String companyId, HttpServletResponse response) {
        log.info("companyFileExportZip companyId is {}", companyId);
        // 声明需要手动关闭的流变量(提升作用域)
        ZipOutputStream zipOut = null;
        BufferedOutputStream bufferedOut = null;

        try {
            CompanyBean companyBean = performTeamService.getById(companyId);
            response.setContentType("application/zip");
            // 处理文件名中文编码(可选优化:避免文件名乱码)
            String fileName = new String((companyBean.getCompanyName() + ".zip").getBytes("UTF-8"), "ISO-8859-1");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

            List<FileBean> fileBeanList = fileService.getFileBeanByBizId(companyId);
            String domainName = obsProperties.getDomainName();

            // 初始化输出流(替代try-with-resources)
            bufferedOut = new BufferedOutputStream(response.getOutputStream());
            zipOut = new ZipOutputStream(bufferedOut);

            for (int i = 0; i < fileBeanList.size(); i++) {
                FileBean fileBean = fileBeanList.get(i);
                String fileRealName = fileBean.getFileName();
                String fileUrl = fileBean.getFileUrl();
                String objKey = fileUrl.substring(domainName.length());
                log.info("companyFileExportZip fileName is {},objKey is {}", fileRealName, objKey);

                GetObjectRequest request = new GetObjectRequest(obsProperties.getBucketName(), objKey);
                ObsObject obsObject = obsClient.getObject(request);

                ZipEntry zipEntry = new ZipEntry(fileRealName);
                zipOut.putNextEntry(zipEntry);

                // 处理单个文件的输入流(手动关闭)
                InputStream fileIn = null;
                try {
                    fileIn = obsObject.getObjectContent();
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = fileIn.read(buffer)) != -1) {
                        zipOut.write(buffer, 0, bytesRead);
                    }
                } catch (IOException e) {
                    log.error("读取OBS文件流失败,文件名:{}", fileRealName, e);
                    throw e; // 抛出异常,让外层捕获统一处理
                } finally {
                    // 手动关闭单个文件的输入流
                    if (fileIn != null) {
                        try {
                            fileIn.close();
                        } catch (IOException e) {
                            log.warn("关闭OBS文件输入流失败,文件名:{}", fileRealName, e);
                        }
                    }
                }
                zipOut.closeEntry();
            }
            zipOut.finish();
            log.info("companyFileExportZip companyId is {} success", companyId);

        } catch (IOException e) {
            log.error("文件压缩下载失败,companyId:{}", companyId, e);
            // 确保响应状态码设置生效(避免流已提交的异常)
            if (!response.isCommitted()) {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            }
        } finally {
            // 统一关闭外层的ZipOutputStream和BufferedOutputStream
            // 关闭顺序:先关包装流(zipOut),再关底层流(bufferedOut)
            if (zipOut != null) {
                try {
                    zipOut.close();
                } catch (IOException e) {
                    log.warn("关闭ZipOutputStream失败", e);
                }
            }
            if (bufferedOut != null) {
                try {
                    bufferedOut.close();
                } catch (IOException e) {
                    log.warn("关闭BufferedOutputStream失败", e);
                }
            }
        }
    }

一种是简便写法

复制代码
 @GetMapping(value = {"/companyFileExportZip/{companyId}"})
    @ApiOperation("丰台文旅-演出团队附件批量导出")
    public void companyFileExportZip(@PathVariable String companyId,HttpServletResponse response) {
        log.info("companyFileExportZip companyId is {}",companyId);
        CompanyBean companyBean = performTeamService.getById(companyId);
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename="+companyBean.getCompanyName()+".zip");
        try {
            List<FileBean> fileBeanList = fileService.getFileBeanByBizId(companyId);
            String domainName = obsProperties.getDomainName();
            try (ZipOutputStream zipOut = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()))) {
                for (int i = 0 ;i < fileBeanList.size();i++) {
                    FileBean fileBean = fileBeanList.get(i);
                    String fileName = fileBean.getFileName();
                    String fileUrl = fileBean.getFileUrl();
                    String objKey = fileUrl.substring(domainName.length());
                    log.info("companyFileExportZip fileName is {},objKey is {}",fileName,objKey);

                    GetObjectRequest request = new GetObjectRequest(obsProperties.getBucketName(), objKey);
                    ObsObject obsObject = obsClient.getObject(request);

                    ZipEntry zipEntry = new ZipEntry(fileName);
                    zipOut.putNextEntry(zipEntry);

                    try (InputStream fileIn = obsObject.getObjectContent()) {
                        byte[] buffer = new byte[4096];
                        int bytesRead;
                        while ((bytesRead = fileIn.read(buffer)) != -1) {
                            zipOut.write(buffer, 0, bytesRead);
                        }
                    }
                    zipOut.closeEntry();
                }
                zipOut.finish();
            }
            log.info("companyFileExportZip companyId is {} success",companyId);
        } catch (IOException e) {
            log.error("文件压缩下载失败", e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

两种写法,主要起别在try、catch的使用上。这两种写法,都支持下载的压缩文件中包含压缩文件的情况

相关推荐
若亦_4 分钟前
排序>>交换排序
java·数据结构·算法
Wang's Blog10 分钟前
MongoDB 地理位置上报实战:从接口设计到覆盖写入的完整实现
java·交友
鬼手点金28 分钟前
Skills:领域能力的可组合单元
java·人工智能·笔记·自动化·1024程序员节
ShineWinsu29 分钟前
对于Qt:QLCDNumber常见属性以及QTimer的解析
服务器·数据库·c++·qt·gui·qtimer·qlcdnumber
SEO-狼术40 分钟前
Aspose.Email for .NET 26 Crack
运维·服务器
captain3769 小时前
MyBatis(入门5)其他查询操作
java·数据库·spring boot·mybatis
Novproxy_Z9 小时前
商用代理避坑:如何识别商家拿机房 IP 冒充住宅 IP
java·网络·tcp/ip
无足鸟ICT9 小时前
【RHCA+】vmstat命令(监控系统资源)
linux·服务器
垆边人似月.10 小时前
RDMA 文件传输踩坑(五):READY 发送成功后,为什么出现 Work Request Flushed Error?
服务器·网络·tcp/ip
闪亮的路灯10 小时前
Linux 安装mqtt服务mosquitto
linux·运维·服务器