-1

My files does not have a path because it is stored in the database. I retrieve it from blob to bytes. Whenever i download the .zip file, the file is invalid and empty even though the size of the .zip file is not 0kb.

@RequestMapping(value = "/downloadMultipleFilesAsZip", method = RequestMethod.POST)
        public void downloadMultiAsZip(@RequestParam("selectedFile[]") int[] selectedFiles,
                HttpServletRequest request, HttpServletResponse response) throws FileNotFoundException, IOException {
    
                List<FileUpload> fileToDownload = new ArrayList<FileUpload>();
                System.out.println("==================================================");
                for (int i = 0; i<selectedFiles.length; i++) {
                    System.out.println("Value of multipleFile["+i+"] is " + selectedFiles[i]);
                    FileUpload fu = new FileUpload();
                    fu.setFile_id(selectedFiles[i]);
                    fileToDownload.add(fu);
                    System.out.println("fileToDownload file_id is " + fileToDownload.get(i).getFile_id());
                }
                // store details of downloads into fileToDownload
                fileToDownload = fuMapper.downloadMultipleAsZip(fileToDownload);
                
                //Do download
                OutputStream os = null;
                
                try {                  
                    response.setContentType("application/zip");
                    response.setHeader("Content-Disposition", "attachment; filename=download.zip");
                    
                    os = response.getOutputStream();
                    
                    ZipOutputStream zos = new ZipOutputStream(os);
                    System.out.println("================== Starting zip ==================");
                    for(FileUpload fu : fileToDownload) {
                        System.out.println("Zipping " + fu.getFile_name() + ".....");
                        ZipEntry zipEntry = new ZipEntry(fu.getFile_name());
                        
                        os.write(fu.getFile_data());
                        zos.finish();
                        zos.putNextEntry(zipEntry);
                        zos.closeEntry();
                        
                        } 
                    System.out.println("================== Finish zipping. ==================");
                    
                    os.flush();
                    zos.close();
                    os.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                        
        }

whenever i open the zip file, i have this error

enter image description here

Luffyyy
  • 17
  • 3
  • 1
    You are doing very random stuff in your loop. Why is there a `zos.finish();` in there? Why do you write the file data to `os`, not `zos`? The order in the loop needs to be `putNextEntry`, `write`, `closeEntry`, all performed on the `ZipOutputStream`. – f1sh Sep 30 '22 at 08:38
  • tbh idk what im doing. i tried using zos.write but is not writing any data. – Luffyyy Sep 30 '22 at 08:41

1 Answers1

1

The flow in the loop is:

  1. putNextEntry,
  2. write (to zos, not os!)
  3. closeEntry.

After the loop you need to call either close or finish on zos. If not, the ZIP file won't be properly ended. Since its underlying stream is not yours (the container owns it), I'd use finish:

ZipOutputStream zos = new ZipOutputStream(os);
System.out.println("================== Starting zip ==================");
for(FileUpload fu : fileToDownload) {
    System.out.println("Zipping " + fu.getFile_name() + ".....");
    ZipEntry zipEntry = new ZipEntry(fu.getFile_name());

    zos.putNextEntry(zipEntry);
    zos.write(fu.getFile_data());
    zos.closeEntry();
}
zos.finish();

System.out.println("================== Finish zipping. ==================");

// Don't close zos or os; flushing shouldn't be necessary but won't hurt                    
Rob Spoor
  • 6,186
  • 1
  • 19
  • 20