Spring REST - create .zip file and send it to the client

后端 未结 4 965
借酒劲吻你
借酒劲吻你 2020-12-04 21:25

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

4条回答
  •  遥遥无期
    2020-12-04 22:01

    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.

提交回复
热议问题