【问题标题】:How do I return a zip file to the browser via the response OutputStream?如何通过响应 OutputStream 将 zip 文件返回到浏览器?
【发布时间】:2012-01-11 16:45:14
【问题描述】:

在这种情况下,我创建了一个包含搜索结果文件的 zip 文件,并尝试将其发送给用户。这是我目前正在尝试使用的代码块。

File[] zippable = new File[files.size()];
File resultFile = ZipCreator.zip(files.toArray(zippable), results);
InputStream result = new FileInputStream(resultFile);
IOUtils.copy(result, response.getOutputStream());

但是,目前这并不完全正确。它没有返回我创建的 zip 文件,而是返回一个 html 文件。如果我之后手动更改文件扩展名,我可以看到文件的内容仍然是我需要的搜索结果。所以问题只在于返回响应的正确扩展。

有人对这种情况有什么建议吗?

【问题讨论】:

    标签: java zip outputstream


    【解决方案1】:

    您需要将Content-Type 响应标头设置为值application/zip(或application/octet-stream,具体取决于目标浏览器)。此外,您可能希望发送额外的响应标头来指示附件状态和文件名。

    【讨论】:

    • 我想我可能会误解你的意思。我在代码中添加了一行,所以现在显示为response.setHeader("Content-Type", "application/zip"); 仍然没有成功。这个调用是在调用 IOUtils.copy 之前进行的
    • @Bennie:看起来不错,但同样,对于用于 ZIP 文件的“正确”MIME 类型存在一些混淆,因此您可能想要使用这些值。
    • 好吧,它看起来现在可以工作了,至少在返回文件方面。不过,它正在做一件奇怪的事情,文件名为“exportZipSearchResults.htm.zip”。是否有内置方法可以更改响应中的文件名?
    • @Bennie:尝试使用Content-Disposition header(可能带有值“inline”)和您选择的文件名。
    【解决方案2】:

    在流式传输结果之前,您需要将内容类型标头设置为 application/octet-stream。取决于您实际使用的response 的实现方式。

    【讨论】:

      【解决方案3】:

      这是一些工作代码,以防万一有人需要:

      protected void doGet(HttpServletRequest request, HttpServletResponse response) {
      
              // The zip file you want to download
              File zipFile = new File(zipsResourcesPath + zipFileName);
      
              response.setContentType("application/zip");
              response.addHeader("Content-Disposition", "attachment; filename=" + zipFileName);
              response.setContentLength((int) zipFile.length());
      
              try {
      
                  FileInputStream fileInputStream = new FileInputStream(zipFile);
                  OutputStream responseOutputStream = response.getOutputStream();
                  int bytes;
                  while ((bytes = fileInputStream.read()) != -1) {
                      responseOutputStream.write(bytes);
                  }
              } catch (IOException e) {
                  logger.error("Exception: " + e);
              }
      }
      

      还有 HTML:

      <a class="btn" href="/path_to_servlet" target="_blank">Download zip</a>
      

      希望这会有所帮助!

      【讨论】:

      • 请说明您是如何定义“zipFile”的?您是如何将文件添加到此“zipFile”中的?
      • 我已经编辑了代码,因此您可以看到 zipFile 是如何定义的。请重新考虑否决@Yithirash。我感谢 cmets,因为这有助于我改进我的答案。
      • 这是已经创建的 zip 文件。但是如何获取多个文件并使用 Java 将它们压缩成 zip?然后发送到响应。
      【解决方案4】:

      所以我找到了一个 hack :) 只需在文件名中添加“.zip”并将内容类型设置为 application/zip。像魅力一样工作。

      response.setContentType("application/zip");
      String licenseFileName = eId;
      response.setHeader("Content-disposition", "attachment; filename=\"" + licenseFileName +".zip");
      

      【讨论】:

      • 本例中的 eId 是什么?
      猜你喜欢
      • 1970-01-01
      • 2016-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-23
      • 2015-03-07
      • 2018-11-26
      相关资源
      最近更新 更多