使用Zip4j生成Zip以供下载

时间:2015-05-09 14:10:53

标签: java servlets web download zip4j

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

  

2015-05-09 15:56:24.306 ERROR 11748 --- [nio-8080-exec-4] oaccC [。[。[/]。[dispatcherServlet]:servlet的[Servlet.service()[dispatcherServlet]在path []的上下文中抛出异常[请求处理失败;嵌套异常是java.lang.IllegalStateException:已经根据原因为此响应调用了getOutputStream()

调用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函数甚至没有获得响应但是已经获得了所有的流?

2 个答案:

答案 0 :(得分:2)

那是因为,行

zout.putNextEntry(file, null);
由于null参数,

抛出空指针。而且,由于我没有看到你的servlet的其余内容,我的猜测是,你的servlet可能会尝试再次获取输出流以处理/抛出此异常。

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

此调用的第一个参数是File对象。只有在从本地文件流构建zip时才需要这样做。如果要从外部流构建zip(例如在您的情况下),则此参数可以为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());

    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();
}

答案 1 :(得分:1)

如果有人需要使用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);
}

希望我帮助过某人......