How do I create zip file in Servlet for download?

The example below is a servlet that shows you how to create a zip file and send the generated zip file for user to download. The compressing process is done by the zipFiles method of this class.

For a servlet to work you need to configure it in the web.xml file of your web application which can be found after the code snippet below.

package org.kodejava.servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@WebServlet(urlPatterns = "/zipservlet")
public class ZipDownloadServlet extends HttpServlet {
    public static final String FILE_SEPARATOR = System.getProperty("file.separator");

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            // The path below is the root directory of data to be
            // compressed.
            String path = getServletContext().getRealPath("data");

            File directory = new File(path);
            String[] files = directory.list();

            // Checks to see if the directory contains some files.
            if (files != null && files.length > 0) {

                // Call the zipFiles method for creating a zip stream.
                byte[] zip = zipFiles(directory, files);

                // Sends the response back to the user / browser. The
                // content for zip file type is "application/zip". We
                // also set the content disposition as attachment for
                // the browser to show a dialog that will let user 
                // choose what action will he do to the content.
                ServletOutputStream sos = response.getOutputStream();
                response.setContentType("application/zip");
                response.setHeader("Content-Disposition", "attachment; filename=\"DATA.ZIP\"");

                sos.write(zip);
                sos.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Compress the given directory with all its files.
     */
    private byte[] zipFiles(File directory, String[] files) throws IOException {
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             ZipOutputStream zos = new ZipOutputStream(baos)) {
            byte[] bytes = new byte[2048];

            for (String fileName : files) {
                String path = directory.getPath() +
                        ZipDownloadServlet.FILE_SEPARATOR + fileName;
                try (FileInputStream fis = new FileInputStream(path);
                     BufferedInputStream bis = new BufferedInputStream(fis)) {

                    zos.putNextEntry(new ZipEntry(fileName));

                    int bytesRead;
                    while ((bytesRead = bis.read(bytes)) != -1) {
                        zos.write(bytes, 0, bytesRead);
                    }
                    zos.closeEntry();
                }
            }

            zos.close();
            return baos.toByteArray();
        }
    }
}

Maven dependencies

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

Maven Central

How do I read a zip file checksum value?

package org.kodejava.util.zip;

import java.io.*;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.CheckedInputStream;
import java.util.zip.Adler32;

public class UnzipWithChecksum {
    public static void main(String[] args) throws Exception {
        String zipName = "data-1.zip";

        try (FileInputStream fis = new FileInputStream(zipName);
             // Creating input stream that also maintains the checksum of 
             // the data which later can be used to validate data 
             // integrity.
             CheckedInputStream checksum =
                     new CheckedInputStream(fis, new Adler32());
             ZipInputStream zis =
                     new ZipInputStream(new BufferedInputStream(checksum))) {

            ZipEntry entry;

            // Read each entry from the ZipInputStream until no more entry
            // found indicated by a null return value of the getNextEntry()
            // method.
            while ((entry = zis.getNextEntry()) != null) {
                System.out.println("Unzipping: " + entry.getName());

                int size;
                byte[] buffer = new byte[1048];

                try (FileOutputStream fos =
                             new FileOutputStream(entry.getName());
                     BufferedOutputStream bos =
                             new BufferedOutputStream(fos, buffer.length)) {

                    while ((size = zis.read(buffer, 0, buffer.length)) != -1) {
                        bos.write(buffer, 0, size);
                    }
                    bos.flush();
                }
            }

            // Print out the checksum value
            long value = checksum.getChecksum().getValue();
            System.out.println("Checksum = " + value);
        }
    }
}

How do I create checksum for a zip file?

This example demonstrate how to use CheckedOutputStream for creating a checksum of a zip file. Checksum can be used to detect whether a data was corrupted during a transmission process to a remote machine.

package org.kodejava.util.zip;

import java.io.*;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import java.util.zip.CheckedOutputStream;
import java.util.zip.Adler32;

public class ZipWithChecksum {
    public static void main(String[] args) throws Exception {
        String target = "data-1.zip";

        try (FileOutputStream fos = new FileOutputStream(target);
             // An output stream that also maintains a checksum of the data
             // being written. The checksum can then be used to verify the
             // integrity of the output data.
             CheckedOutputStream checksum =
                     new CheckedOutputStream(fos, new Adler32())) {
            try (ZipOutputStream zos =
                         new ZipOutputStream(new BufferedOutputStream(checksum))) {

                int size;
                byte[] buffer = new byte[1024];

                // Get all text files on the working folder.
                File dir = new File(".");
                String[] files = dir.list((directory, name) -> name.endsWith(".txt"));

                for (String file : Objects.requireNonNull(files)) {
                    System.out.println("Compressing: " + file);

                    try (FileInputStream fis = new FileInputStream(file);
                         BufferedInputStream bis =
                                 new BufferedInputStream(fis, buffer.length)) {

                        // put a new ZipEntry in the ZipOutputStream
                        ZipEntry zipEntry = new ZipEntry(file);
                        zos.putNextEntry(zipEntry);

                        // read data to the end of the source file and write it
                        // to the zip output stream.
                        while ((size = bis.read(buffer, 0, buffer.length)) > 0) {
                            zos.write(buffer, 0, size);
                        }

                        zos.closeEntry();
                    }
                }
            }

            // Print out checksum value
            long value = checksum.getChecksum().getValue();
            System.out.println("Checksum   : " + value);
        }
    }
}

How do I decompress a zip file using ZipFile class?

In this example we use the java.util.zip.ZipFile class to decompress and extract a zip file.

package org.kodejava.util.zip;

import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.util.Enumeration;
import java.io.*;

public class ZipFileUnzipDemo {
    public static void main(String[] args) throws Exception {
        String zipName = "data.zip";

        ZipFile zip = new ZipFile(zipName);
        Enumeration<? extends ZipEntry> enumeration = zip.entries();

        while (enumeration.hasMoreElements()) {
            ZipEntry zipEntry = enumeration.nextElement();
            System.out.println("Unzipping: " + zipEntry.getName());

            int size;
            byte[] buffer = new byte[2048];

            try (BufferedInputStream bis =
                         new BufferedInputStream(zip.getInputStream(zipEntry));
                 FileOutputStream fos =
                         new FileOutputStream(zipEntry.getName());
                 BufferedOutputStream bos =
                         new BufferedOutputStream(fos, buffer.length)) {

                while ((size = bis.read(buffer, 0, buffer.length)) != -1) {
                    bos.write(buffer, 0, size);
                }
                bos.flush();
            }
        }
    }
}

How do I decompress a zip file using ZipInputStream?

The code below shows how to decompress and extract files from a zip archive. In the example we use the java.util.zip.ZipInputStream class.

package org.kodejava.util.zip;

import java.io.*;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipEntry;

public class UnzipDemo {
    public static void main(String[] args) {
        String zipName = "data.zip";

        try (FileInputStream fis = new FileInputStream(zipName);
             ZipInputStream zis =
                 new ZipInputStream(new BufferedInputStream(fis))) {

            ZipEntry entry;

            // Read each entry from the ZipInputStream until no
            // more entry found indicated by a null return value
            // of the getNextEntry() method.
            while ((entry = zis.getNextEntry()) != null) {
                System.out.println("Unzipping: " + entry.getName());

                int size;
                byte[] buffer = new byte[2048];

                try (FileOutputStream fos =
                         new FileOutputStream(entry.getName());
                     BufferedOutputStream bos =
                         new BufferedOutputStream(fos, buffer.length)) {

                    while ((size = zis.read(buffer, 0, buffer.length)) != -1) {
                        bos.write(buffer, 0, size);
                    }
                    bos.flush();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}