I want to create .zip file that contains my zipped files that I recieve from backend, and then send this file to the user. For 2 days I have been looking for the answer and cant find proper solution, maybe you can help me :)
For now, the code is like this: (I know I shouldnt do it all in the spring controller, but dont care about that, it is just for testing purposes, to find the way to make it works)
@RequestMapping(value = "/zip")
public byte[] zipFiles(HttpServletResponse response) throws IOException{
//setting headers
response.setContentType("application/zip");
response.setStatus(HttpServletResponse.SC_OK);
response.addHeader("Content-Disposition", "attachment; filename=\"test.zip\"");
//creating byteArray stream, make it bufforable and passing this buffor to ZipOutputStream
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(byteArrayOutputStream);
ZipOutputStream zipOutputStream = new ZipOutputStream(bufferedOutputStream);
//simple file list, just for tests
ArrayList<File> files = new ArrayList<>(2);
files.add(new File("README.md"));
//packing files
for (File file : files) {
//new zip entry and copying inputstream with file to zipOutputStream, after all closing streams
zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
FileInputStream fileInputStream = new FileInputStream(file);
IOUtils.copy(fileInputStream, zipOutputStream);
fileInputStream.close();
zipOutputStream.closeEntry();
}
if (zipOutputStream != null) {
zipOutputStream.finish();
zipOutputStream.flush();
IOUtils.closeQuietly(zipOutputStream);
}
IOUtils.closeQuietly(bufferedOutputStream);
IOUtils.closeQuietly(byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
}
But the problem is, that using the code, when I enter URL: localhost:8080/zip I get file: test.zip.html instead of .zip file
When I remove .html extension and leave just test.zip it opens correctly how to avoid returning this .html extension? why is it added?
I have no idea what else can I do. I was also trying replace ByteArrayOuputStream with something like:
OutputStream outputStream = response.getOutputStream();
and set the method to be void so it returns nothing, but It created .zip file which was.. damaged?
On my macbook after unpacking the test.zip I was getting test.zip.cpgz which was again giving me test.zip file and so on..
On windows the .zip file was damaged as I said and couldn't even open it.
I also suppose, that removing .html extension automatically will be the best option, but how? Hope it is no as hard as It seems to be :) thanks
seems to be solved. I replaced:
with:
And now I get clear, beautiful .zip file :)
If any of you have either better or faster proposition, or just want to give some advice, then go ahead, I am curious.
I am using
REST Web Service
ofSpring Boot
and I have designed the endpoints to always returnResponseEntity
whether it isJSON
orPDF
orZIP
and I came up with the following solution which is partially inspired bydenov's answer
in this question as well as another question where I learned how to convertZipOutputStream
intobyte[]
in order to feed it toResponseEntity
as output of the endpoint.Anyway, I created a simple utility class with two methods for
pdf
andzip
file downloadAnd now the endpoint can easily return
ResponseEntity<?>
as shown below using thebyte[]
data and custom headers that is specifically tailored forpdf
orzip
.The
BinaryOutputWrapper
is a simple immutablePOJO
class I created withprivate byte[] data;
andorg.springframework.http.HttpHeaders headers;
as fields in order to return bothdata
andheaders
from utility method.