使用Zip4j生成Zip下载

问题描述:

我尝试使用Zip4j生成zip文件进行下载。 但我总是得到错误:调用zout.putNextEntry(文件,NULL)时使用Zip4j生成Zip下载

2015-05-09 15:56:24.306 ERROR 11748 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: getOutputStream() has already been called for this response] with root cause

;下面

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功能,即使没有得到回应,但媒体链接获得的流?

那是因为,线

zout.putNextEntry(file, null); 

是投掷因为空参数的空指针。而且,由于我没有看到你的servlet的其余部分,我的猜测是,你的servlet可能试图再次获取输出流来处理/抛出这个异常。

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

该调用的第一个参数是一个File对象。这仅在您从本地文件流构建压缩文件时才需要。如果您从外部流(例如您的情况)构建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(); 
} 
+0

感谢,现在的作品, 但我有另一种方法,其中参数不为null,但: ZipParam eters parameters = new ZipParameters(); parameters.setEncryptFiles(true); parameters.setPassword(“AMOS”); 我已经添加了新参数: parameters.setSourceExternalStream(true); parameters.setFileNameInZip(“employee.txt”); 但它仍然无法正常工作,对此有何猜测? – Matombo

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

希望我” ve帮了别人...