Generated zip file is always corrupted after download on Mac

440 views Asked by At

Lets say that I have a collection of objects which I would like to wrap with zip. My zip conversion class looks like:

public class ZipFile {

    public byte[] createZipByteArray(String fileName, byte[] content) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try (byteArrayOutputStream; ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) {
            zipOutputStream.setLevel(Deflater.NO_COMPRESSION);
            ZipEntry zipEntry = new ZipEntry(fileName);
            zipOutputStream.putNextEntry(zipEntry);
            zipOutputStream.write(content);
            zipOutputStream.closeEntry();
            zipOutputStream.flush();
        }
        return byteArrayOutputStream.toByteArray();
    }

}

My controller looks like:

    @GetMapping(value = "objectWithDetails/zip", produces = "application/zip")
    @RolesAllowed("QUERY_DATA")
    public ResponseEntity<byte[]> getObjectWithDetails(String limit, HttpServletResponse response) throws IOException {
        response.setContentType("application/zip");

        List<ObjectSpecification> objectRepresentation = recipeService.getObjectRepresentation(limit);

        byte[] objectsBytes = objectMapper.writeValueAsBytes(objectRepresentation);

        ZipFile zipFile = new ZipFile();

        return ResponseEntity
                .ok()
                .contentType(MediaType.valueOf("application/zip"))
                .header("Content-Encoding", "UTF-8")
                .header("Content-Disposition", String.format("attachment; filename=\"details_%s.zip\"", dateTimeProvider.nowDate()))
                .body(zipFile.createZipByteArray(String.format("details_%s.zip", dateTimeProvider.nowDate()), objectsBytes));

    }

In swagger, I have a download option for the generated zip files. After all, when I try to open the downloaded file I receive the following:

Unable to expand filename.zip. It is in an unsupported format.

I tried closing ZipOutputStream and ByteArrayOutputStream in a different configuration. Applied a different option for the content type in the controller but still, I cannot find out why all zip files are corrupted. I will be grateful for suggestions on what I miss. Cheers!

1

There are 1 answers

1
Martin On BEST ANSWER

I managed to find out the root cause with @k314159 , namely, I had a zip file wrapped with a zip file. New version which works as expected.

    public static byte[] createZipByteArray(String fileName, byte[] content) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try (byteArrayOutputStream; ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) {
            zipOutputStream.setLevel(Deflater.DEFLATED);
            ZipEntry zipEntry = new ZipEntry(fileName);
            zipOutputStream.putNextEntry(zipEntry);
            zipOutputStream.write(content);
            zipOutputStream.closeEntry();
            zipOutputStream.flush();
        }
        return byteArrayOutputStream.toByteArray();
    }

and controller

    @GetMapping(value = "objectWithDetails", produces = "application/zip")
    @RolesAllowed("QUERY_DATA")
    public ResponseEntity<byte[]> getObjectWithDetails(String limit, HttpServletResponse response) throws IOException {
        response.setContentType("application/zip");
        List<ObjectSpecification > objectRepresentation = objectService.getObjectRepresentation(limit);

        byte[] objectsBytes = objectMapper.writeValueAsBytes(objectRepresentation);

        return ResponseEntity
                .ok()
                .contentType(MediaType.valueOf("application/zip"))
                .header("Content-Encoding", "UTF-8")
                .header("Content-Disposition", getObjectFileName("attachment; filename=objects_"))
                .body(createZipByteArray(getObjectFileName("objects_"), objectsBytes));
    }