Serving a zip file generated in server and stored in memory

拈花ヽ惹草 提交于 2020-01-30 11:01:05

问题


I need to generate a bunch of xml files with data from my java based web system, that represent a whole export of another system based in XML. Such system will accept this import later.

My approach is to create all files in memory, then save each one as entries it to a zip also in memory, wich later is served to the client.

The data flow is working perfectly, but somehow the output is a blank file. I think i got wrong the outpustream structure

This is the part that i might be getting wrong: ...

 //ZIP creation in server memory
                ByteArrayOutputStream datosEnMemoria = new ByteArrayOutputStream();
                ZipOutputStream zipped_out = new ZipOutputStream(datosEnMemoria)

...

                    //close and zip entry
                    xmlData.append(Tangonet.terminarCargaRegistros());
                    byte[] xmlBinData = xmlData.toString().getBytes();
                    zipped_out.write(xmlBinData, 0, xmlBinData.length);
                    zipped_out.closeEntry();
                }
                byte[] zipped_out_size = zipped_out.toString().getBytes();

                response.setContentType("application/octet-stream");
                response.setHeader("Content-Disposition", "attachment;filename=cierresZ_a_tangonet" + java.time.LocalDate.now() + ".zip");
                response.setHeader("Content-length", "" + zipped_out_size.length);
                response.setHeader("Content-Type", "application/zip");
                response.setHeader("Content-Type", "application/octet-stream");
                response.setHeader("Content-Transfer-Encoding", " binary");
                //closing zip and send it to client
                zipped_out.flush();
                zipped_out.close();
//                out.flush();
//                out.close();

This is the full code:

@RequestMapping(value = "/cierreZ/exportar", method = RequestMethod.GET)
    public void cierreZExportar(@ModelAttribute InformesFinancierosForm informesFinancierosForm, HttpServletRequest request, HttpServletResponse response) throws IOException {
        HttpSession session = request.getSession(true);
        String fechaInicio = null;
        String fechaFin = null;

        if (session.getAttribute("mesActual") != null) {
            informesFinancierosForm.setFechaInicio("01-" + informesFinancierosForm.getMes());
            informesFinancierosForm.setFechaFin(new SimpleDateFormat("dd-MM-yyyy").format(DateUtil.getUltimoDiaDelMes(DateUtil.traduceDateDate((String) session.getAttribute("fechaIni")))));
            fechaInicio = informesFinancierosForm.getFechaInicio();
            fechaFin = informesFinancierosForm.getFechaFin();
        } else {
            fechaInicio = (String) session.getAttribute("fechaIni");
            fechaFin = (String) session.getAttribute("fechaFin");
        }

        if (informeService.isRangoFechaValido(informesFinancierosForm.getSalasSeleccionadas(), fechaInicio)) {
            if (!(fechaInicio.compareTo("") == 0) || (fechaFin.compareTo("") == 0)
                    || informesFinancierosForm.getSalasSeleccionadas().length == 0) {

//                ServletOutputStream out = response.getOutputStream();
                List<InformeCierreZItemForm> listadoInfCierreZ = cierreZService.getCierres(informesFinancierosForm.getSalasSeleccionadas(), fechaInicio, fechaFin);

                //ZIP creation in server memory
                ByteArrayOutputStream datosEnMemoria = new ByteArrayOutputStream();
                ZipOutputStream zipped_out = new ZipOutputStream(datosEnMemoria);

                //filling zip with static xml files
                for (int i = 0; i < Tangonet.documentos_estaticos_tangonet.length; i++) {
                    ZipEntry xmlFile = new ZipEntry(Tangonet.documentos_estaticos_tangonet[i][0] + ".xml");
                    zipped_out.putNextEntry(xmlFile);

                    StringBuilder xmlData = new StringBuilder();
                    xmlData.append(Tangonet.documentos_estaticos_tangonet[i][1]);

                    byte[] xmlBinData = xmlData.toString().getBytes();
                    zipped_out.write(xmlBinData, 0, xmlBinData.length);
                    zipped_out.closeEntry();
                }

                //filling zip with dynamic xml files
                for (int i = 0; i < Tangonet.documentos_dinamicos_tangonet.length; i++) {

                    //dynamic xml creation
                    ZipEntry xmlFile = new ZipEntry(Tangonet.documentos_dinamicos_tangonet[i][0] + ".xml");
                    zipped_out.putNextEntry(xmlFile);

                    //xml schema
                    StringBuilder xmlData = new StringBuilder();
                    xmlData.append(Tangonet.documentos_dinamicos_tangonet[i][1]);

                    //xml data rows
                    for (InformeCierreZItemForm informeCierreZActual : listadoInfCierreZ) {
                        Sala salaActual = informeCierreZActual.getSala();
                        CierrezList CierresZ = cierreZService.getCierresZ(salaActual, fechaInicio, fechaFin);

                        //fiscal data in rows
                        Tangonet datosFiscalesCierrezActual = tangonetDatos.getDatosFiscales(salaActual);

                        for (Cierrez cierreActual : CierresZ) {
                            if (Tangonet.documentos_dinamicos_tangonet[i][0].equals("Comp_de_Facturación_para_Cobranza_Centralizada___GVA12")) {
                                xmlData.append(datosFiscalesCierrezActual.crearRegistroGVA12(cierreActual));
                            } else {
                                xmlData.append(datosFiscalesCierrezActual.crearRegistroGVA42(cierreActual));
                            }
                        }
                    }
                    //close and zip entry
                    xmlData.append(Tangonet.terminarCargaRegistros());
                    byte[] xmlBinData = xmlData.toString().getBytes();
                    zipped_out.write(xmlBinData, 0, xmlBinData.length);
                    zipped_out.closeEntry();
                }
                byte[] zipped_out_size = zipped_out.toString().getBytes();

                response.setContentType("application/octet-stream");
                response.setHeader("Content-Disposition", "attachment;filename=cierresZ_a_tangonet" + java.time.LocalDate.now() + ".zip");
                response.setHeader("Content-length", "" + zipped_out_size.length);
                response.setHeader("Content-Type", "application/zip");
                response.setHeader("Content-Type", "application/octet-stream");
                response.setHeader("Content-Transfer-Encoding", " binary");
                //closing zip and send it to client
                zipped_out.flush();
                zipped_out.close();
//                out.flush();
//                out.close();
            }
        }
    }

回答1:


Zip file can be big, so don't generate it in memory. Write it straight to client.

Also:

  • Don't set Content-Type three times. It can only have one value.

  • Don't specify Content-Transfer-Encoding. It's an email header, not an HTTP header.

  • Since you'll be streaming, don't specify Content-length.

// headers must be set before streaming
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment;filename=cierresZ_a_tangonet" + java.time.LocalDate.now() + ".zip");

// stream straight to client
ZipOutputStream zipped_out = new ZipOutputStream(response.getOutputStream());

// Add zip entries and data here:
// Loop:
//    zipped_out.putNextEntry(...)
//    Generate XML, writing it straight to zipped_out
//      Remember to flush any streams/writers wrapped around zipped_out
//      Do not close zipped_out or wrappers of it
//        If that cannot be prevented, use a CloseShieldOutputStream (from Commons IO)
//    No need to call zipped_out.closeEntry()

// make sure to finish the zip stream
zipped_out.finish();


来源:https://stackoverflow.com/questions/57731216/serving-a-zip-file-generated-in-server-and-stored-in-memory

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