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.example.servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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 sent content.
                ServletOutputStream sos = response.getOutputStream();
                response.setHeader("Content-Disposition", "attachment; filename="DATA.ZIP"");

        catch (Exception e) {

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

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

            zos.putNextEntry(new ZipEntry(fileName));

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

        return baos.toByteArray();

The web.xml configuration:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="" 
         id="WebApp_ID" version="2.5">



  1. Nice post, done exactly the same with my servlet.

    The files I need to ZIP are stored as BLOB and add them as byte[]. When I add them as a ZIPEntry everything works fine, but when I review the exported files, they don’t have a content type individually and marked as invalid content, any recommendations?

  2. Hi there,

    I used your code, it works great!, well I haven’t tested it with real data but it seems to be working fine, one question, where is the “data” folder in your example?

    Thank you!

    • Hi Miguel,

      In this case the data directory should be under you webapp root directory. For example if your web application root directory is webapp then the data should be webapp/data. I hope that helps you.

  3. I tried running the code in jsp, then I can get a getOutputStream() has already been called for this response. any idea for this?

  4. This solution won’t work for large files as there is a byte[] zip = zipFiles(directory, files); in it. The resulting file has to fit into memory. Prefer using directly the Servlet outputStream by wrapping it into the ZipOutputStream. ZipOutputStream zos = new ZipOutputStream(response.getOutputStream()); That way, you will consume less memory.


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.