Search code examples
javaspringspring-mvczipoutputstreamzipinputstream

How to convert byte array to ZipOutputStream in spring MVC?


Trying to read a zip file stored in a database as a byte array.

.zip is getting downloaded using the following code but the size of files included in the zip is none. No data is there.

I already went through lots of answers but not sure what's wrong with the following code.

Please assist.

@RequestMapping(value = ApplicationConstants.ServiceURLS.TRANSLATIONS + "/{resourceId}/attachments", produces = "application/zip")
    public void attachments(HttpServletResponse response, @PathVariable("resourceId") Long resourceId) throws IOException {

        TtTranslationCollection tr = translationManagementDAO.getTranslationCollection(resourceId);
        byte[] fileData = tr.getFile();

        // setting headers
        response.setStatus(HttpServletResponse.SC_OK);
        response.addHeader("Content-Disposition", "attachment; filename=\"attachements.zip\"");

        ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream());

        ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(fileData));
        ZipEntry ent = null;
        while ((ent = zipStream.getNextEntry()) != null) {
            zipOutputStream.putNextEntry(ent);
        }
        zipStream.close();
        zipOutputStream.close();
    }

Solution

  • You have to copy the byte data (content) of the zip file to the output as well...

    This should work (untested):

    while ((ent = zipStream.getNextEntry()) != null) {
        zipOutputStream.putNextEntry(ent);
        // copy byte stream
        org.apache.commons.io.IOUtils.copy(zis.getInputStream(ent), zipOutputStream);
    }
    

    BTW: why you do not just simply forward the original zip byte content?

    try (InputStream is = new ByteArrayInputStream(fileData));) {
        IOUtils.copy(is, response.getOutputStream());
    }
    

    or even better (thanks to comment by @M. Deinum)

    IOUtils.copy(fileData, response.getOutputStream());