Spring MVC - 在内存中创建一个ZIP文件,让用户下载

问题描述 投票:1回答:1

我有一个网络项目

  1. 从Oracle DB中提取数据
  2. 使用HashMap从该数据中创建XML文件
  3. 将其压缩在内存中
  4. 让用户下载ZIP文件。

请注意,我不会在下载之前创建物理文件。

我完成了1-3。我似乎找不到下载部分的解决方案。我正在使用纯Spring MVC(尽我所能),Hibernate,MySQL。

home controller.Java

@RequestMapping(value="/doretrieve", method=RequestMethod.POST, produces="application/zip")
    @ResponseBody
    public ZipOutputStream doRetrieve(@RequestParam(value="calcgrouplist") String selectedCalcGroups, @RequestParam(value="env") String currentEnv){

        ZipOutputStream zipCalgGroups = null;
        try {
            String[] cgs = calcGroupService.insertToArray(selectedCalcGroups);

            for(String cg:cgs){
                System.out.println("Calculation Group: " + cg);
            }

            Map startRetrieve = calcGroupService.startRetrieve(currentEnv, cgs);

            if (startRetrieve != null ){
                zipCalgGroups = calcGroupService.zipCalcGroups(currentEnv, startRetrieve);
            } else {
                return null;
            }
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
        return zipCalgGroups;

    }

CalcGroupService.java代码用于创建xml文件的zip文件

public ZipOutputStream zipCalcGroups(String database, Map startRetrieve) {

        //Sort
        //SortCalcGroupParameters sort = new SortCalcGroupParameters();
        //sort.run(new File("\\" + database));

        Map<String, byte[]> mapXmlFiles = startRetrieve;

        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ZipOutputStream zos = new ZipOutputStream(baos))

        {
            for (Map.Entry<String, byte[]> mapXmlFile:mapXmlFiles.entrySet()){
                ZipEntry entry = new ZipEntry(mapXmlFile.getKey());
                zos.putNextEntry(entry);
                zos.write(mapXmlFile.getValue());
                zos.closeEntry();
            }

            return zos;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
java mysql hibernate spring-mvc
1个回答
1
投票

我能够解决自己的问题。以下是编辑过的方法:

HomeController的:

@RequestMapping(value="/doretrieve", method=RequestMethod.POST, produces="application/zip")
@ResponseBody
public byte[] doRetrieve(HttpServletResponse response, @RequestParam(value="calcgrouplist") 
    String selectedCalcGroups, @RequestParam(value="env") String currentEnv){

    try {
        String[] cgs = calcGroupService.insertToArray(selectedCalcGroups);

        for(String cg:cgs){
            System.out.println("Calculation Group: " + cg);
        }

        //returns map of file name and xml
        Map startRetrieve = calcGroupService.startRetrieve(currentEnv, cgs);

        //set file name of the zipped calc group/s using selected environment
        response.setHeader("Content-Disposition", "attachment; filename=" + currentEnv + ".zip");

        if (startRetrieve != null ){
            byte[] zipped = calcGroupService.zipCalcGroupsFromMemory(currentEnv, startRetrieve);
            return zipped;
        } else {
            return null;
        }
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
    return null;

}

CalcGroupService:

public byte[] zipCalcGroupsFromMemory(String database, Map startRetrieve) {

    Map<String, byte[]> mapXmlFiles = startRetrieve;
    HttpServletRequest request = null;

    try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ZipOutputStream zos = new ZipOutputStream(baos)) {

        for (Map.Entry<String, byte[]> mapXmlFile : mapXmlFiles.entrySet()) {

            byte[] xml = sortCalcGroup(mapXmlFile.getKey(), mapXmlFile.getValue());

            zos.putNextEntry(new ZipEntry(mapXmlFile.getKey()));
            //zos.write(mapXmlFile.getValue());
            zos.write(xml);
            zos.closeEntry();
        }
        zos.close();
        return baos.toByteArray();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

上面的代码生成一个很好的压缩xml文件。

© www.soinside.com 2019 - 2024. All rights reserved.