ByteArrayOutputStream - 错误地生成了带有特殊字符的条目

ByteArrayOutputStream - entries generated with special characters wrongly

我正在使用 ByteArrayOutputStream 和 ZipOutputStream 生成一个 zip 文件。 ZipEntry 中的文件名是正确的,具有正确的编码。 当调用“ByteArrayOutputStream.toByteArray()”并且正确创建 zip 文件但 zipEntries 生成在“cp866”时,问题就来了。在控制器中,return 类型是 ResponseEntity.

下面是部分代码

    byteArrayOutputStream = new ByteArrayOutputStream();
    zipOutputStream = new ZipOutputStream(byteArrayOutputStream);
    zipOutputStream.putNextEntry(new ZipEntry("ação.pdf")); //Here it is all OK
    zipOutputStream.write(inputStream.readAllBytes());
    zipOutputStream.closeEntry();

而 return 到 RestController 的代码类似于:

    HttpHeaders headers = new HttpHeaders();
    contentDisposition =
        ContentDisposition.builder("attachment").filename("download.zip").build();

    headers.setContentDisposition(contentDisposition);
    headers.setContentLength(byteArrayOutputStream.size());
    headers.setContentType(MediaType.parseMediaType("application/zip; charset-utf-8"));
    return ResponseEntity.ok().headers(headers).body(byteArrayOutputStream.toByteArray());

在这种情况下,一个名为“ação.pdf”的文件被生成为“a├з├гo.pdf”,如果我在 ZipEntry 指定字符集 ISO8859-1,它会生成作为“aчуo.pdf”。

我尝试过的:

所有可能性都没有成功

解决方案:使用正确的 ZipOutputStream 构造函数,即采用 OutputStream 编码的构造函数。

旁注:你打错了。这个:

headers.setContentType(MediaType.parseMediaType("application/zip; charset-utf-8"));

不正确。是 charset=utf-8。注意等号。然而,这也不正确。 ZIP 文件没有 字符集编码。是二进制数据。 JPG 文件也没有,同理。正确的 MIME 类型只是 application/zip,仅此而已。

完整解释

不能使用 mime headers 传送 zip 文件 中 条目的字符集编码。它编码在 zip 文件本身中。

因此,在 zip 文件本身中对其进行编码。很容易做到!

new ZipOutputStream(byteArrayOutputStream, StandardCharsets.UTF_8);

这是您唯一需要进行的更新。