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

时间:2017-01-18 06:53:06

标签: java mysql hibernate spring-mvc

我有一个

的网络项目
  1. 从Oracle DB中提取数据
  2. 使用HashMap
  3. 从该数据中创建XML文件
  4. 将其存储在内存中
  5. 让用户下载ZIP文件。
  6. 请注意,我不会在下载之前创建物理文件。

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

    HomeController.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文件的压缩文件的代码

    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;
    

1 个答案:

答案 0 :(得分: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文件。