通过HttpResponse Java下载Zip文件

6
所以我正在从数据库中获取一系列blob(各种mimetypes),并尝试将它们压缩成zip文件,通过http响应供用户下载。虽然我能够实现下载,但是当我尝试打开下载的zip文件时,它会显示“存档文件格式未知或已损坏”。我已经尝试使用application/zip、application/octet-stream和application/x-zip-compressed这些代码,但我开始认为问题在于我添加文件的方式。我还在使用Java 7和Grails 2.2.4。如有帮助,感激不尽。谢谢!
  final ZipOutputStream out = new ZipOutputStream(new FileOutputStream("test.zip"));


        for (Long id : ids){

            Object[] stream = inlineSamplesDataProvider.getAttachmentStream(id);


            if (stream) {

                String fileName = stream[0]
                String mimeType = (String) stream[1];
                InputStream inputStream = stream[2]
                byte[] byteStream = inputStream.getBytes();

                ZipEntry zipEntry = new ZipEntry(fileName)
                out.putNextEntry(zipEntry);
                out.write(byteStream, 0, byteStream.length);
                out.closeEntry();
            }
        }

        out.close();
        response.setHeader("Content-Disposition", "attachment; filename=\"" + "test.zip" + "\"");
        response.setHeader("Content-Type", "application/zip");
        response.outputStream << out;
        response.outputstream.flush();

这看起来基本上没问题,至少你编写文件的方式应该可以工作。您尝试运行此代码并将其保存到磁盘以查看是否可以打开它,然后再将其发送到网络吗? - Shaun Stone
@ShaunStone 感谢您的回复,Shaun。我直接将它下载到了我的电脑上,我能够毫无问题地打开它。我想这意味着问题出在我将它推入响应的方式上? - Brewster
1个回答

10

我在这里找到了答案:Returning ZipOutputStream to browser

好的,最终对我有用的方法是将ZipOutputStream转换为ByteArrayOutputStream,并将其作为byte[]写入响应中:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
final ZipOutputStream out = new ZipOutputStream(baos);

Calendar cal = Calendar.getInstance();
String date = new SimpleDateFormat("MMM-dd").format(cal.getTime());

final String zipName = "COA_Images-" + date + ".zip";

for (Long id: ids) {

    Object[] stream = inlineSamplesDataProvider.getAttachmentStream(id);

    if (stream) {

        String fileName = stream[0];
        String mimeType = (String) stream[1];
        InputStream inputStream = stream[2];
        byte[] byteStream = inputStream.getBytes();

        ZipEntry zipEntry = new ZipEntry(fileName)
        out.putNextEntry(zipEntry);
        out.write(byteStream, 0, byteStream.length);
        out.closeEntry();
    }
}

out.close();

response.setHeader("Content-Disposition", "attachment; filename=\"" + zipName + "\"");
response.setHeader("Content-Type", "application/zip");
response.getOutputStream().write(baos.toByteArray());
response.flushBuffer();
baos.close();

谢谢所有帮助过我的人!


你可以将自己的答案标记为正确的,以获得徽章 :) - manuna
谢谢你的回答,它为我省去了很多烦恼! - JJT
我使用从数据库BLOB读取的一组字节并制作zip文件。 zip文件可以下载,但无法打开。 有人能帮忙吗? dataBytes = doc.getPdfData(); ZipEntry entry = new ZipEntry(pdfFileName); entry.setSize(dataBytes.length); zos.putNextEntry(entry); zos.write(dataBytes, 0,dataBytes.length); zos.closeEntry(); response.setContentType("application / zip"); response.addHeader(“Content-Disposition”,“attachment;filename =”+ zipName); response.setContentLength(baos.toByteArray().length); stream.write(baos.toByteArray()); - BPeela

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接