无法即时生成 ZIP 文件并将其发送到用户的浏览器以供下载

Posted

技术标签:

【中文标题】无法即时生成 ZIP 文件并将其发送到用户的浏览器以供下载【英文标题】:unable to Generate a ZIP file on the fly and send it to the user’s browser for download 【发布时间】:2014-07-23 10:29:58 【问题描述】:

我有音频剪辑的 URL。我想从他们的 URL 下载所有这些剪辑,并希望将所有这些剪辑放在单个 zip 文件中。如果我在代码中指定硬编码路径,我可以成功地在指定位置以 zip 格式下载所有剪辑。但是,我想生成弹出窗口,提示用户指定下载该 zip 文件的路径。 这是我的代码:

  ByteArrayOutputStream baos = new ByteArrayOutputStream()
  ZipOutputStream zipFile = new ZipOutputStream(baos)

  for (int i = 0; i < clipsCount; i++)             

        String fileName = getSessionId() + ".mp4";

        try 

            //Opening Connection to the Downloading Link
            URLConnection conn = new URL(sessionToDownload.getConvertedLinkURL()).openConnection();
            conn.setRequestProperty("Authorization", "Basic " + encodedString);

            //Adding File in the Zipped Resource
            def file1Entry = new ZipEntry(fileName);
            zipFile.putNextEntry(file1Entry);

            //Getting Required File
            zipFile << conn.getInputStream();

            //Closing Current Zip Entry
            zipFile.closeEntry();

            println "Session to Download: " + listofId.getAt(i);
         catch (Exception ex) 
            println "Exception while Downloading Session: "+ex.getMessage();
        
    

    zipFile.close()
    response.setHeader("Content-disposition", "attachment; filename=\"/download.zip\" ")
    response.setContentType("application/zip");
    response.outputStream << baos
    response.outputStream.flush()
    webRequest.renderView = false;

因此,在 Loop 中,它会针对每个剪辑进行迭代,下载并使其成为 zip 文件的一部分。

如果我做错了什么,请指导我,或者我可以通过其他方式实现这一点。 感谢您的时间、考虑和指导。

【问题讨论】:

您是否使用相同的文件名保存所有文件? 不,该 zip 文件中的每个文件都有不同的名称 您的代码正好相反。您使用相同的 fileName 变量命名所有 zipEntries 如果你仔细看,我会在循环的每次迭代中更改“文件名”变量 如果getSessionId() 做了我认为的那样,它不仅对整个循环,而且对整个会话都应该具有相同的值:) 【参考方案1】:

您的操作应该确实有效。 如果浏览器看到"Content-disposition"-header 和"attachment; filename=aaa.zip" 作为响应中的值,则浏览器Save as.. 对话框会自动打开。

尝试删除引号:

response.setHeader 'Content-disposition', 'attachment; filename=download.zip'

【讨论】:

您在浏览器/日志中看到了什么?如果你将baos 转储到磁盘,它是一个有效的 zip 文件吗? 它根本不生成 Zip 文件【参考方案2】:

我已经调查了这个问题,实际上它是由于此处描述的问题而产生的: Sending Multiple Selected Items from Controller to View

还有一个问题是不允许它出现在浏览器端。这对我有用:

    //Setting Response Required Parameters
    response.setContentType('APPLICATION/OCTET-STREAM')
    response.setHeader('Content-Disposition', 'Attachment;Filename="example.zip"')

     InputStream contentStream = null;
    ZipOutputStream zip = new ZipOutputStream(response.outputStream);

    for (int i = 0; i < listofId.length; i++) 

        def sessionToDownload = Sessions.get(listofId.getAt(i));

        if (sessionsToDownload != null) 

            String fileName = sessionToDownload.getSessionId() + ".mp4";

            try 

                //Opening Connection to the Downloading Link
                URLConnection conn = new URL(sessionToDownload.getConvertedLinkURL()).openConnection();
                conn.setRequestProperty("Authorization", "Basic " + encodedString);

                //Getting file contents
                contentStream = conn.getInputStream();

                //Adding File in the Zipped Resource
                def file1Entry = new ZipEntry(fileName);
                zip.putNextEntry(file1Entry);
                zip.write(IOUtils.toByteArray(contentStream));

                println "Session to Download: " + fileName;
             catch (Exception ex) 
                println "Exception while Downloading Session: " + ex.getMessage();
            
        
    

    zip.close();

【讨论】:

以上是关于无法即时生成 ZIP 文件并将其发送到用户的浏览器以供下载的主要内容,如果未能解决你的问题,请参考以下文章

Spring REST - 创建 .zip 文件并将其发送到客户端

PHP中的压缩流

PHP中的压缩流

如何在 zip 文件中生成 xls 文件并将其发送到电子邮件以在那里下载 - groovy [关闭]

想要从 React UI 上传 zip 文件夹并将其发送到后端节点 js 服务器,我可以从那里将该文件夹放置在我系统上的某个路径中

提取 zip 文件并将其存储到图像或文件字段