1.问题
java项目部署到ubuntu上的tomcat后zip压缩包内文件名乱码
部署在windows上的tomcat则无此问题
2.解决方法
可使用Apache的Compress库的ZipArchiveOutputStream和ZipArchiveEntry进行压缩,可自动处理文件名编码和解码。
例如:
ZipArchiveOutputStream zipOutputStream = new ZipArchiveOutputStream(new FileOutputStream(zipFile));
ZipArchiveEntry entry = new ZipArchiveEntry(file, file.getName());
zipOutputStream.putArchiveEntry(entry);
IOUtils.copy(new FileInputStream(file), zipOutputStream);
zipOutputStream.closeArchiveEntry();
添加依赖:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.18</version>
</dependency>
3.参考代码
...
response.setContentType("APPLICATION/OCTET-STREAM");
response.setHeader("Content-Disposition","attachment; filename="+ new String(zipFileName
.getBytes(),
"iso-8859-1"));
ZipArchiveOutputStream out = new ZipArchiveOutputStream(response.getOutputStream());
try {
reZipCsvFiles(url,fileNames, out);
response.flushBuffer();
} catch (Exception e) {
e.printStackTrace();
}finally{
out.close();
}
...
private void reZipCsvFiles(String pathFile, List<String> targetFilePathList,ZipArchiveOutputStream zipOutputStream) throws Exception {
FileInputStream in = null;
FileOutputStream fos = null;
try {
for (String csvFilePath: targetFilePathList) {
File file=new File(pathFile+csvFilePath);
in=new FileInputStream(file);
zipOutputStream.putArchiveEntry(new ZipArchiveEntry(file,file.getName()));
IOUtils.copy(in, zipOutputStream);
zipOutputStream.closeArchiveEntry();
in.close();
}
} finally {
if (zipOutputStream != null) {
zipOutputStream.close();
}
if (fos != null) {
fos.close();
}
if (in != null) {
in.close();
}
}
}