使用 Zip4j 生成用于下载的 Zip
Generating Zip for Download using Zip4j
我尝试使用 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
调用时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 函数甚至没有得到响应,而是已经获得的流?
那是因为,这条线
zout.putNextEntry(file, null);
由于参数为空而抛出一个空指针。而且,由于我没有看到您的 servlet 的其余部分,我的猜测是,您的 servlet 可能正在尝试再次获取输出流以 handle/throw 此异常。
上述 putNextEntry() 调用中的第二个参数是 ZipParameters。顾名思义,此参数指定各种 zip 参数,例如 zip 是否受密码保护,或者 zip 的内容是否从文件或输入流中读取等。这是必需的参数。
这个调用的第一个参数是一个文件对象。仅当您从本地文件流构建 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();
}
如果有人需要使用 Zip4j 库使用密码加密 Zip 文件,这里有一个代码(如 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);
}
希望我帮助了某人...
我尝试使用 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
调用时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 函数甚至没有得到响应,而是已经获得的流?
那是因为,这条线
zout.putNextEntry(file, null);
由于参数为空而抛出一个空指针。而且,由于我没有看到您的 servlet 的其余部分,我的猜测是,您的 servlet 可能正在尝试再次获取输出流以 handle/throw 此异常。
上述 putNextEntry() 调用中的第二个参数是 ZipParameters。顾名思义,此参数指定各种 zip 参数,例如 zip 是否受密码保护,或者 zip 的内容是否从文件或输入流中读取等。这是必需的参数。
这个调用的第一个参数是一个文件对象。仅当您从本地文件流构建 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();
}
如果有人需要使用 Zip4j 库使用密码加密 Zip 文件,这里有一个代码(如 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);
}
希望我帮助了某人...