javarestzip4j

How to download zipped file with zip4j in rest API?


Using zip4j lib I can create a zip file from a folder which contain subfolders and files. But now I want to download it to the client by Rest API, so I use ZipOutputStream but I don't know how to get the InputStream from generated zip file.

Method to generate zip file.

public void generateBulkConfigFile(HttpServletResponse response, String root, String zippedFileName) {

    File rootFolder = FileUtil.createRootFolder(root);
    response.setStatus(HttpServletResponse.SC_OK);
    response.addHeader("Content-Disposition", "attachment; filename=\"" + "test.zip" + "\"");

    ZipParameters zipParameters = new ZipParameters();
    zipParameters.setEncryptFiles(true);
    zipParameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
    zipParameters.setPassword("1234");

    //Code to process data, write files and subfolders to root folder

    try {
        ZipFile zipFile = new ZipFile(rootFolder.getAbsolutePath() +  System.lineSeparator() + zippedFileName + ".zip");
        zipFile.addFolder(rootFolder, zipParameters);

        //Todo: get inputstream from zipped file and write to response outputstream for client

    } catch (ZipException e) {
        log.error("Error: ", e);
        throw e;
    } catch (IOException e) {
        log.error("Error: ", e);
        throw e;
    }
}

The above code successfully created the zip file in desired folder. I tried adding this lines of code to output to response.

ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream());
FileInputStream fileInputStream = new FileInputStream(zipFile.getFile());
IOUtils.copy(fileInputStream, zipOutputStream);

fileInputStream.close();
zipOutputStream.finish();
zipOutputStream.close();

But it end up with the NullPointerException in the copy method of IOUtils class.

java.lang.NullPointerException: null
at net.lingala.zip4j.io.DeflaterOutputStream.write(DeflaterOutputStream.java:89) ~[zip4j-1.3.3.jar:?]
at net.lingala.zip4j.io.ZipOutputStream.write(ZipOutputStream.java:31) ~[zip4j-1.3.3.jar:?]
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1793) ~[commons-io-2.4.jar:2.4]
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1769) ~[commons-io-2.4.jar:2.4]
at org.apache.commons.io.IOUtils.copy(IOUtils.java:1744) ~[commons-io-2.4.jar:2.4]

Can someone help me to get through this problem? Thanks a lot.


Solution

  • How about just

    try (Outpustream os = response.getOutputStream(); 
         InputStream fis = new FileInputStream(zipFile.getFile())) {
        IOUtils.copy(fis, os);
    }
    

    You don't need to wrap the output stream in ZipOutputStream because the bytes you're putting in are already zipped. It's up to the client on the other side to consume these bytes and inflate them back.