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
I am using REST Web Service
of Spring Boot
and I have designed the endpoints to always return ResponseEntity
whether it is JSON
or PDF
or ZIP
and I came up with the following solution which is partially inspired by denov's answer
in this question as well as another question where I learned how to convert ZipOutputStream
into byte[]
in order to feed it to ResponseEntity
as output of the endpoint.
Anyway, I created a simple utility class with two methods for pdf
and zip
file download
@Component
public class FileUtil {
public BinaryOutputWrapper prepDownloadAsPDF(String filename) throws IOException {
Path fileLocation = Paths.get(filename);
byte[] data = Files.readAllBytes(fileLocation);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/pdf"));
String outputFilename = "output.pdf";
headers.setContentDispositionFormData(outputFilename, outputFilename);
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
return new BinaryOutputWrapper(data, headers);
}
public BinaryOutputWrapper prepDownloadAsZIP(List filenames) throws IOException {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/zip"));
String outputFilename = "output.zip";
headers.setContentDispositionFormData(outputFilename, outputFilename);
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
ZipOutputStream zipOutputStream = new ZipOutputStream(byteOutputStream);
for(String filename: filenames) {
File file = new File(filename);
zipOutputStream.putNextEntry(new ZipEntry(filename));
FileInputStream fileInputStream = new FileInputStream(file);
IOUtils.copy(fileInputStream, zipOutputStream);
fileInputStream.close();
zipOutputStream.closeEntry();
}
zipOutputStream.close();
return new BinaryOutputWrapper(byteOutputStream.toByteArray(), headers);
}
}
And now the endpoint can easily return ResponseEntity>
as shown below using the byte[]
data and custom headers that is specifically tailored for pdf
or zip
.
@GetMapping("/somepath/pdf")
public ResponseEntity> generatePDF() {
BinaryOutputWrapper output = new BinaryOutputWrapper();
try {
String inputFile = "sample.pdf";
output = fileUtil.prepDownloadAsPDF(inputFile);
//or invoke prepDownloadAsZIP(...) with a list of filenames
} catch (IOException e) {
e.printStackTrace();
//Do something when exception is thrown
}
return new ResponseEntity<>(output.getData(), output.getHeaders(), HttpStatus.OK);
}
The BinaryOutputWrapper
is a simple immutable POJO
class I created with private byte[] data;
and org.springframework.http.HttpHeaders headers;
as fields in order to return both data
and headers
from utility method.