3

I don't understand why this is so hard and everybody has it's own implementation...

So in my server, I generate a .zip file which I want the user to be able to download upon click.

So I set up the request, which the server successfully receives and now, i'm struggling with writing the byte array to the output.

Here's my code for the response:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        System.out.println("Downloading clusters.zip");

        /* Generate the directory on the server, then zip it. */
        clustersToFiles();
        zipClusters();
        /* Now the zip is saved on zipFullPath */

        System.out.println("Done generating the .zip");

        String parent_dir = System.getProperty("catalina.base");
        String filename = "clusters.zip";
        String zipFullPath = parent_dir + "/" + filename;

        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
        OutputStream out = response.getOutputStream();

        FileInputStream fis = new FileInputStream(zipFullPath);
        int bytes;
        while ((bytes = fis.read()) != -1) {
            System.out.println(bytes);
            out.write(bytes);
        }
        fis.close();
        response.flushBuffer();

        System.out.println(".zip file downloaded at client successfully");
}
Jack
  • 722
  • 3
  • 8
  • 24
  • 2
    Possible duplicate of http://stackoverflow.com/a/23645826/1495050 – Daniel Bickler Apr 05 '17 at 13:42
  • @pandaadb if you think `frameworks` might help me here, by all means... – Jack Apr 05 '17 at 13:47
  • Actually, i think your issue is not the servlet part, but the copy part. I can post a jersey example for a download if you like. As for frameworks, copying any file into an output stream can be achieved with e.g. google commons: `Files.copy(new File("path/to/zip/file"), output);` Also, if this works for a normal file, are you sure your produced zip file isn't just empty? It should not make a difference what file you are trying to copy – pandaadb Apr 05 '17 at 14:00

1 Answers1

4

The fact that the downloaded file is a ZIP isn't relevant (except for the content type), you just want to download a binary file.

PrintWriter isn't good at that, this writer is used to write text output, and the write(int) method you are using :

Writes a single character.

Just use a low level plain OutputStream, its write(int) method :

Writes the specified byte to this output stream.

So just go :

OutputStream out = response.getOutputStream();

You may find some more ways of doing it in this question : Implementing a simple file download servlet

Community
  • 1
  • 1
Arnaud
  • 17,229
  • 3
  • 31
  • 44
  • Thank you for your time. I've updated the code. The `bytes` are printed, so I'm guessing, it's working. But the download never commences. Do you think that this has to do anything with the call to the `servlet` being done by an `AJAX` request? – Jack Apr 05 '17 at 14:20
  • @Jack : I really couldn't tell (Edit ; the link below should), but try without ajax first, to at least make sure that the servlet works as intended. Oh and see this question which may answer your Ajax doubt : http://stackoverflow.com/questions/3502267/download-a-file-from-servlet-using-ajax – Arnaud Apr 05 '17 at 14:21