Serve Zip of generated Zips to Client

怎甘沉沦 提交于 2019-12-13 04:08:34

问题


I'm generating a ZIP file that contains a bunch of autogenerated XML files. Recently requirements changed and now i must generate several times that ZIP (with variations on XML data) and serve them directly to client without using actual files in server. This is what im doing:

// [... servlet handling ... ]
    response.setContentType("application/zip");
    response.setHeader("Content-Disposition", "attachment;filename=cierresZ_a_tangonet" + java.time.LocalDate.now() + ".zip");
    // stream straight to client
    ServletOutputStream out = response.getOutputStream();
    ZipOutputStream zipped_out = new ZipOutputStream(out);
    for( each data block from db ){
    //CREATION AND PROCESSING OF XML FILES AS ZIP ENTRIES
       byte[] xmlBinData = xmlData.toString().getBytes();
       zipped_out.write(xmlBinData, 0, xmlBinData.length);
       zipped_out.flush();                                
     }
     zipped_out.finish();
     out.close();
}

Tried to do this but gives me errors:

// [... servlet handling ... ]
  response.setContentType("application/zip");
  response.setHeader("Content-Disposition", "attachment;filename=cierresZ_a_tangonet" + java.time.LocalDate.now() + ".zip");
  // stream straight to client
  ServletOutputStream out = response.getOutputStream();
  for( each zip needed ){
    ZipOutputStream zipped_out = new ZipOutputStream(out);
    for( each data block from db ){
    //CREATION AND PROCESSING OF XML FILES AS ZIP ENTRIES
       byte[] xmlBinData = xmlData.toString().getBytes();
       zipped_out.write(xmlBinData, 0, xmlBinData.length);
       zipped_out.flush();                                
     }
     zipped_out.finish();
   }
   out.close();
}

EDIT: Made some slight changes to it, but gives same error

// [... servlet handling ... ]
  response.setContentType("application/zip");
  response.setHeader("Content-Disposition", "attachment;filename=cierresZ_a_tangonet" + java.time.LocalDate.now() + ".zip");
  // stream straight to client
  ServletOutputStream out = response.getOutputStream();
  ZipOutputStream zipped_outs = new ZipOutputStream(out);
  for( each zip needed ){
    //creates new zip inside big one
    ZipEntry zipFile = new ZipEntry(salaActual + ".zip");
    zipped_outs.putNextEntry(zipFile);

    //opens stream for this new zip
    ZipOutputStream zipped_out = new ZipOutputStream(zipped_outs);
    for( each data block from db ){
    //CREATION AND PROCESSING OF XML FILES AS ZIP ENTRIES
       byte[] xmlBinData = xmlData.toString().getBytes();
       zipped_out.write(xmlBinData, 0, xmlBinData.length);
       zipped_out.flush();                                
     } 
    //completes zip and closes it then goes for the next one
    byte[] zipBinData = zipFile.toString().getBytes();
    zipped_outs.write(zipBinData, 0, zipBinData.length);
    zipped_outs.flush();     
   }
   //closes the big zip filled with zips and returns
   zipped_outs.finish();
   out.close();
}

回答1:


You need to finish() and flush() all the inner ZipOutputStreams and the outer ZipOutputStream.

Basically:

response.setContentType("application/zip");
response.setHeader("Content-Disposition", ...);
ZipOutputStream mainZip = new ZipOutputStream(response.getOutputStream());
for (each file to download) {
    ZipEntry zipEntry = new ZipEntry(fileName);
    mainZip.putNextEntry(zipEntry);
    if (file data available) {
        // write file data to mainZip here
    } else {
        ZipOutputStream subZip = new ZipOutputStream(mainZip);
        for (each subfile to download) {
            ZipEntry zipEntry = new ZipEntry(subFileName);
            subZip.putNextEntry(zipEntry);
            // write subfile data to subZip here
        }
        subZip.finish();
        subZip.flush(); // do not close
    }
}
mainZip.finish();
mainZip.close(); // flushes for you

Notice how both mainZip and subZip gets zip entries and both are finished. That was missing from your code.



来源:https://stackoverflow.com/questions/57911777/serve-zip-of-generated-zips-to-client

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!