Создание Zip для загрузки с помощью Zip4j

Я пытаюсь использовать Zip4j для создания zip-файла для загрузки. Но я всегда получаю ошибку:

2015-05-09 15:56:24.306 ОШИБКА 11748 --- [nio-8080-exec-4] oaccC[.[.[/].[dispatcherServlet] : Servlet.service() для сервлета [dispatcherServlet] в контексте с путь [] вызвал исключение [Ошибка обработки запроса; вложенным исключением является 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 получает даже не ответ, а уже полученный поток?


person Matombo    schedule 09.05.2015    source источник


Ответы (2)


Это потому, что линия

zout.putNextEntry(file, null);

выдает нулевой указатель из-за нулевого аргумента. И, поскольку я не вижу остальную часть вашего сервлета, я предполагаю, что ваш сервлет может пытаться снова получить выходной поток, чтобы обработать/сгенерировать это исключение.

Вторым параметром в приведенном выше вызове 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();
}
person Srikanth Reddy Lingala    schedule 17.05.2015
comment
спасибо, теперь работает, но у меня есть другой метод, в котором параметры не нулевые, а: параметры ZipParameters = new ZipParameters(); параметры .setEncryptFiles (истина); параметры.setPassword(AMOS); Я добавил новые параметры: parameters.setSourceExternalStream(true); параметры.setFileNameInZip(employee.txt); но это все еще не работает, есть предположения по этому поводу? - person Matombo; 19.05.2015

Если кому-то нужно заархивировать файлы с шифрованием паролей с помощью библиотеки Zip4j, вот код (как уже упоминалось здесь):

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

Надеюсь, я помог кому-то...

person Woody    schedule 17.11.2015