Create and serve a Zip archive from within DropWizard
Do you want your DropWizard app to create and serve a zip archive to users? If you’ve got a lot of data then you should periodically create an archive and store it on a CDN for people to download. But if you’ve got a small amount of data, then here’s some code to do it.
@GET @Path("/download") @Produces(MediaType.APPLICATION_OCTET_STREAM) public Response download() { StreamingOutput stream = new StreamingOutput() { @Override public void write(OutputStream output) throws IOException, WebApplicationException { ZipOutputStream zos = new ZipOutputStream(output); ZipEntry ze = new ZipEntry("file.txt"); zos.putNextEntry(ze); zos.write("file.txt".getBytes()); zos.closeEntry(); ze = new ZipEntry("item/item1.txt"); zos.putNextEntry(ze); zos.write("item/item1.txt".getBytes()); zos.closeEntry(); zos.flush(); zos.close(); } }; return Response .ok(stream) .header("Content-Disposition", "attachment; filename=download.zip") .header("Content-Transfer-Encoding", "binary") .build(); } |
ZipEntry ze = new ZipEntry("file.txt");
zos.putNextEntry(ze);
zos.write("file.txt".getBytes());
zos.closeEntry();
ze = new ZipEntry("item/item1.txt");
zos.putNextEntry(ze);
zos.write("item/item1.txt".getBytes());
zos.closeEntry();
zos.flush();
zos.close();
}
};
return Response
.ok(stream)
.header("Content-Disposition", "attachment; filename=download.zip")
.header("Content-Transfer-Encoding", "binary")
.build();
}
You’ll need to ensure you don’t write the same filename to the zip more than once to avoid a ZipException.
And if you’re using an ObjectMapper to write JSON objects into the archive stream, you’ll need to stop it closing the stream after writing:-
ObjectMapper om = new ObjectMapper(); om.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false); |