Tomcat 8 Unicode 文件名战争文件部署问题

Posted

技术标签:

【中文标题】Tomcat 8 Unicode 文件名战争文件部署问题【英文标题】:Tomcat 8 Unicode filename war file deploy issue 【发布时间】:2017-06-03 11:39:07 【问题描述】:

在 Linux(openSUSE) 机器上,我尝试在 Tomcat 8 应用程序(war 文件)上部署,该应用程序包含一个名称为 Unicode 字符的文件。

war 文件内部的名称如下所示:

бжк-природний-1496336830201.xml

但部署后文件看起来像:

???-?????????????-1496336830201.xml

如何告诉 Tomcat 正确部署文件名?

更新

这是一个带有 Unicode 文件名的示例 war 文件:war file

这场战争里面文件的文件名有什么问题?

更新

我已经安装了unzip-rcc,正如这里所建议的https://superuser.com/questions/1215670/opensuse-unzip-unicode-issue,现在WAR文件上的解压缩(控制台命令)工作正常,但Tomcat仍然部署文件时遇到同样的问题。

【问题讨论】:

如果把war解压到一个目录下,有特殊字符的文件名会保留吗?要尝试的另一件事是确保 JAVA 具有正确的编码。 是的.. unzip 会杀死文件名 这表明操作系统没有处理这种编码的字体或字符集。所以这不是 Java 的错 :) 是的,但我不知道有什么问题。我的 Jenkins/Maven 构建是否也有可能破坏文件名?如果压缩/解压缩从 Git 下载的原始文件 - 一切正常......只有 Jenkins/Maven 生成的 war 文件中的文件不能正常工作。 我已经按照superuser.com/questions/1215670/opensuse-unzip-unicode-issue 的建议安装了 unzip-rcc,现在 WAR 文件上的 unzip(console command) 工作正常,但 Tomcat 仍然部署具有相同问题的文件。如何配置 Tomcat 8 以正确部署文件? 【参考方案1】:

尝试将这些设置放在 Tomcat 启动脚本中:

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8

根据经验,Java 会为它不知道如何编码的字符打印上下颠倒的问号。

【讨论】:

非常感谢!我在这个问题上苦苦挣扎了几天,现在在您的帮助下解决了!我已将这些属性添加到我的 tomcat.conf 文件中【参考方案2】:

zip .war 文件中的文件名确实是 UTF-8。

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信息)。

可以想象三种解决方案:

一个简短的解决方案可能是在 UTF-8 语言环境下运行 TomCat。 最好是让 maven 与 UTF-8 编码建立战争。 (<onfiguration><encoding>UTF-8</encoding></configuration>) 通过转换来修复战争。

对于前两个解决方案,我没有经验。快速搜索没有产生任何结果(“编码”有点普遍)。

修复代码很简单:

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

【讨论】:

以上是关于Tomcat 8 Unicode 文件名战争文件部署问题的主要内容,如果未能解决你的问题,请参考以下文章

在 docker 中与 tomcat 运行战争

当角靴和弹簧靴捆绑在一次战争中并部署在tomcat上时,是否需要proxy.conf.json文件

如何在 Tomcat7 中部署 Grails 3.0.1 战争文件?

在没有 Tomcat 管理器的情况下从 jenkins 自动部署战争文件

使用 Jenkins 将战争文件部署到 Tomcat 的推荐方法?

如何在外部 tomcat 中部署 Spring-boot REST API