Tomcat 8 Unicode 文件名 war 文件部署问题
Tomcat 8 Unicode filename war file deploy issue
在 Linux(openSUSE) 机器上,我正在尝试在 Tomcat 8 应用程序(war 文件)上部署,其中包含一个名称带有 Unicode 字符的文件。
在 war 文件中,名称如下所示:
бжк-природний-1496336830201.xml
但部署后文件如下所示:
???-?????????????-1496336830201.xml
如何告诉 Tomcat 正确部署文件名?
已更新
这是一个示例 war 文件,其中包含 Unicode 文件名:war file
这个war里面的文件的文件名有什么问题吗?
已更新
我已经按照此处的建议安装了 unzip-rcc
https://superuser.com/questions/1215670/opensuse-unzip-unicode-issue,现在 WAR 文件上的解压缩(控制台命令)工作正常,但 Tomcat 仍然部署具有相同问题的文件。
尝试将这些设置放入 Tomcat 启动脚本中:
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
根据经验,Java 会为它不知道如何编码的字符打印上下颠倒的问号。
zip 文件中的文件名确实是 UTF-8。war 文件。
try (ZipFile zipFile = new ZipFile(path, StandardCharsets.UTF_8)) {
zipFile.stream()
.forEachOrdered(entry -> System.out.printf("- %s%n", entry.getName()));
} catch (IOException e) {
e.printStackTrace();
}
但是zip没有添加编码(作为bytes[] extra
信息)。
可以想到三种解决方案:
- 一个简短的解决方案可能是 运行 TomCat 在 UTF-8 语言环境下。
- 最好是让 maven 构建一个 war 使用 UTF-8 编码。 (
<onfiguration><encoding>UTF-8</encoding></configuration>
)
- 正在通过转换修复 war。
前两个解决方案我没有经验。快速搜索没有产生任何结果("encoding" 有点普遍)。
修复代码很简单:
Path path = Paths.get(".../api.war").toAbsolutePath().normalize();
Path path2 = Paths.get(".../api2.war").toAbsolutePath().normalize();
URI uri = URI.create("jar:file://" + path.toString());
Map<String,String> env = new HashMap<String,String>();
env.put("create", "false");
env.put("encoding", "UTF-8");
URI uri2 = URI.create("jar:file://" + path2.toString());
Map<String,String> env2 = new HashMap<String,String>();
env2.put("create", "true");
env2.put("encoding", "UTF-8");
try (FileSystem zipFS = FileSystems.newFileSystem(uri, env);
FileSystem zipFS2 = FileSystems.newFileSystem(uri2, env2)) {
Files.walkFileTree(zipFS.getPath("/"), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
System.out.println("* File: " + file);
Path file2 = zipFS2.getPath(file.toString());
Files.createDirectories(file2.getParent());
Files.copy(file, file2);
return FileVisitResult.CONTINUE;
}
});
} catch(IOException e) {
e.printStackTrace();
}
在 Linux(openSUSE) 机器上,我正在尝试在 Tomcat 8 应用程序(war 文件)上部署,其中包含一个名称带有 Unicode 字符的文件。
在 war 文件中,名称如下所示:
бжк-природний-1496336830201.xml
但部署后文件如下所示:
???-?????????????-1496336830201.xml
如何告诉 Tomcat 正确部署文件名?
已更新
这是一个示例 war 文件,其中包含 Unicode 文件名:war file
这个war里面的文件的文件名有什么问题吗?
已更新
我已经按照此处的建议安装了 unzip-rcc
https://superuser.com/questions/1215670/opensuse-unzip-unicode-issue,现在 WAR 文件上的解压缩(控制台命令)工作正常,但 Tomcat 仍然部署具有相同问题的文件。
尝试将这些设置放入 Tomcat 启动脚本中:
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
根据经验,Java 会为它不知道如何编码的字符打印上下颠倒的问号。
zip 文件中的文件名确实是 UTF-8。war 文件。
try (ZipFile zipFile = new ZipFile(path, StandardCharsets.UTF_8)) {
zipFile.stream()
.forEachOrdered(entry -> System.out.printf("- %s%n", entry.getName()));
} catch (IOException e) {
e.printStackTrace();
}
但是zip没有添加编码(作为bytes[] extra
信息)。
可以想到三种解决方案:
- 一个简短的解决方案可能是 运行 TomCat 在 UTF-8 语言环境下。
- 最好是让 maven 构建一个 war 使用 UTF-8 编码。 (
<onfiguration><encoding>UTF-8</encoding></configuration>
) - 正在通过转换修复 war。
前两个解决方案我没有经验。快速搜索没有产生任何结果("encoding" 有点普遍)。
修复代码很简单:
Path path = Paths.get(".../api.war").toAbsolutePath().normalize();
Path path2 = Paths.get(".../api2.war").toAbsolutePath().normalize();
URI uri = URI.create("jar:file://" + path.toString());
Map<String,String> env = new HashMap<String,String>();
env.put("create", "false");
env.put("encoding", "UTF-8");
URI uri2 = URI.create("jar:file://" + path2.toString());
Map<String,String> env2 = new HashMap<String,String>();
env2.put("create", "true");
env2.put("encoding", "UTF-8");
try (FileSystem zipFS = FileSystems.newFileSystem(uri, env);
FileSystem zipFS2 = FileSystems.newFileSystem(uri2, env2)) {
Files.walkFileTree(zipFS.getPath("/"), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
System.out.println("* File: " + file);
Path file2 = zipFS2.getPath(file.toString());
Files.createDirectories(file2.getParent());
Files.copy(file, file2);
return FileVisitResult.CONTINUE;
}
});
} catch(IOException e) {
e.printStackTrace();
}