6

So I'm grabbing a collection of blobs from a database (various mimetypes) and trying to zip them up to be downloaded by users through an http response. I can get the download to happen, but when I try to open the downloaded zip file it says "The archive is either in unknown format or damaged." I've tried the following code with application/zip, application/octet-stream, and application/x-zip-compressed, but I'm starting to assume that the issue is in how I'm adding the files. I'm also using Java 7 and Grails 2.2.4.

Any help with this would be greatly appreciated. Thanks!

  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();
Brewster
  • 195
  • 1
  • 1
  • 9
  • this seems more or less fine, at least the way you are writing the file should work. have you tried running this code and having it save the file to disk to see if you can open it, prior to sending it over the wire. – Shaun Stone Oct 19 '15 at 21:40
  • @ShaunStone Thanks for responding, Shaun. I downloaded it directly to my computer and I was able to open it without a problem. I guess that means the issue lies with the way I'm pushing it into the response? – Brewster Oct 20 '15 at 16:02

1 Answers1

10

I found the answer here: Returning ZipOutputStream to browser

All right, so what ended up working for me was converting the ZipOutputStream to a ByteArrayOutputStream and writing it to a response as a 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();

Thanks to everyone who helped!

Origin
  • 2,009
  • 5
  • 19
  • 19
Brewster
  • 195
  • 1
  • 1
  • 9
  • You can mark your own answer as a correct one, to get a badge :) – manuna May 12 '17 at 12:10
  • Thanks for this answer, it saved me a lot of head ache! – JJT Oct 13 '17 at 18:13
  • I used a set of bytes read from db blob and making the zip file. The zip file download but cant open it. Can anyone help? 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 Jan 03 '19 at 18:19