【问题标题】:Generating Zip for Download using Zip4j使用 Zip4j 生成 Zip 以供下载
【发布时间】:2015-05-09 14:10:53
【问题描述】:

我尝试使用 Zip4j 生成 zip 文件以供下载。 但我总是得到错误:

2015-05-09 15:56:24.306 错误 11748 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet]:Servlet.service() 用于 servlet [dispatcherServlet]在路径 [] 的上下文中抛出异常 [请求处理失败;嵌套异常是 java.lang.IllegalStateException: getOutputStream() has already been called for this response] 根本原因

当调用 zout.putNextEntry(file, null);在下面的函数中

public void EmployeeEncyrptedZipFileDownload(HttpServletResponse response, @RequestParam(value = "id", required = true) int employeeId) throws IOException, ZipException
{
    //Prepare text file contents
    String fileContent = "Hallo Welt";

    response.setContentType("application/zip");
    response.setHeader("Content-Disposition", "attachment;filename=test.zip");

    final StringBuilder sb = new StringBuilder(fileContent);
    final ZipOutputStream zout = new ZipOutputStream(response.getOutputStream());

    File file = new File("mytext.txt");
    zout.putNextEntry(file, null);
    byte[] data = sb.toString().getBytes();
    zout.write(data, 0, data.length);

    zout.closeEntry();
    zout.finish();
}

这怎么可能,因为 putNextEntry 函数甚至没有得到响应,而是已经获得了流?

【问题讨论】:

    标签: java servlets web download zip4j


    【解决方案1】:

    那是因为,行

    zout.putNextEntry(file, null);
    

    因为空参数而抛出空指针。而且,由于我没有看到您的 servlet 的其余部分,我的猜测是,您的 servlet 可能正在尝试再次获取输出流以处理/抛出此异常。

    上述 putNextEntry() 调用中的第二个参数是 ZipParameters。顾名思义,此参数指定各种 zip 参数,例如 zip 是否受密码保护,或者 zip 的内容是否从文件或输入流中读取等。这是一个必需的参数。

    此调用的第一个参数是一个 File 对象。仅当您从本地文件流构建 zip 时才需要这样做。如果您正在从外部流构建 zip(例如在您的情况下),则此参数可以为空。我知道这不是一个好的设计,将在即将发布的版本中修复。

    解决方案是:

    public void EmployeeEncyrptedZipFileDownload(HttpServletResponse response, @RequestParam(value = "id", required = true) int employeeId) throws IOException, ZipException
    {
        //Prepare text file contents
        String fileContent = "Hallo Welt";
    
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment;filename=test.zip");
    
        final StringBuilder sb = new StringBuilder(fileContent);
        final ZipOutputStream zout = new ZipOutputStream(response.getOutputStream());
    
        ZipParameters zipParameters = new ZipParameters();
        zipParameters.setSourceExternalStream(true);
        zipParameters.setFileNameInZip("mytext.txt");
    
        zout.putNextEntry(null, zipParameters);
        byte[] data = sb.toString().getBytes();
        zout.write(data, 0, data.length);
    
        zout.closeEntry();
        zout.finish();
    }
    

    【讨论】:

    • 感谢现在可以使用,但是我有另一种方法,其中参数不为空,但是: ZipParameters parameters = new ZipParameters();参数.setEncryptFiles(true); parameters.setPassword("AMOS");我添加了新参数:parameters.setSourceExternalStream(true); parameters.setFileNameInZip("employee.txt");但它仍然不起作用,你猜对了吗?
    【解决方案2】:

    如果有人需要使用 Zip4j 库使用密码加密压缩文件,这里有一个代码(如提到的here):

    public void zipFileWithPassword(String fileToZipPath,String password,String zippedFilePath) throws ZipException
    {
        ZipFile zipFile=new ZipFile(zippedFilePath);
        ZipParameters parameters=new ZipParameters();
        parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
        parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
        parameters.setEncryptFiles(true);
        parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
        parameters.setPassword(password);
        File fileToZip=new File(fileToZipPath);
        log(Severity.INFO,"Creating a ZIP file: %s",fileToZipPath);
        zipFile.addFile(fileToZip,parameters);
    }
    

    希望我帮助了某人...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-19
      • 1970-01-01
      • 2021-07-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多