【问题标题】:Mustache throws "File not under root" exception in NetBeans servletMustache 在 NetBeans servlet 中引发“文件不在根目录下”异常
【发布时间】:2015-04-06 02:43:29
【问题描述】:

编辑:我解决了我的问题。 (见下文。)

问题

我是 NetBeans 新手,遇到一个问题,涉及将资源加载到我的 servlet 应用程序,该应用程序使用 Tomcat 作为服务器通过 NetBeans 运行。一切都很好,直到我尝试使用 Mustache 模板库(在 Java 中)构建我的响应。此时会抛出异常:

com.github.mustachejava.MustacheException: File not under root: /opt/catalina/bin

这个异常是在我尝试编译模板文件的代码中引发的。我将资源(模板文件)的路径提供给MustacheFactorycompile 方法。我的代码如下所示:

MustacheFactory mf = new DefaultMustacheFactory();
Mustache mustache = mf.compile(getFormTemplatePath()); 

我的研究

我查看了 Mustache 代码,据我所知,这就是正在发生的事情。 Mustache 在加载资源时会进行安全检查,以确保资源位于文件系统中应用程序的根目录下。因为 NetBeans 正在使用某种魔法在 Tomcat 服务器上运行代码,而项目的代码实际上位于文件系统的其他位置,Mustache 认为发生了一些可疑的事情。

也就是说,它可以找到文件;它只是不喜欢它在哪里找到它。似乎 Mustache 将 /opt/catalina/bin 作为应用程序的根,而模板文件实际上位于更像:~/NetBeansProjects/MyProject/WEB-INF/template_file.mst 的路径。

Mustache 代码如下所示(您可以检查我的推理):

try {
    // Check to make sure that the file is under the file root or current directory.
    // Without this check you might accidentally open a security whole when exposing
    // mustache templates to end users.
    File checkRoot = fileRoot == null ? new File("").getCanonicalFile() : fileRoot.getCanonicalFile();
    File parent = file.getCanonicalFile();
    while ((parent = parent.getParentFile()) != null) {
        if (parent.equals(checkRoot)) break;
    }
    if (parent == null) {
        throw new MustacheException("File not under root: " + checkRoot.getAbsolutePath());
    }
    // [Try-catch block continues...]

我在以下网址在线找到了 Mustache 代码:

https://github.com/spullara/mustache.java/blob/00bd13145f30156cd39aaad7ab046b46b1315275/compiler/src/main/java/com/github/mustachejava/resolver/FileSystemResolver.java#L50

我的假设解决方案

我猜在我选择和配置服务器时,一定有某种方法可以在 NetBeans 中配置应用程序,以解决这个问题。我尝试过使用谷歌搜索Mustache NetBeans servlet "File not under root" exception 的变体等等,但没有任何结果。我猜我对 NetBeans 的了解还不够,不知道应该使用哪些关键词进行搜索。甚至有可能我已经找到了解决方案,但是当我看到它时却认不出来。

有人知道我可以尝试什么吗?谢谢。

【问题讨论】:

    标签: java tomcat servlets netbeans mustache


    【解决方案1】:

    您可以改用其他重载 API

     Mustache compile(Reader reader, String name);
    

    就像这样,您可以更喜欢将 mustache 模板文件放在任何地方

    File f = new File(templateFilePath);
    Mustache mustache = mf.compile(new InputStreamReader(new FileInputStream(f),Charset.forName("UTF-8")),f.getName());
    

    【讨论】:

      【解决方案2】:

      模板文件放在哪里?

      我自己解决了这个问题,尽管我通过对模板文件做一些更好的事情来解决这个问题。最初,我将模板文件放在 WEB-INF 目录中,然后使用 servlet 上下文构建文件的路径。这似乎不是最佳做法。

      再看一下 Mustache 源代码,我意识到 Mustache 首先尝试使用类加载器来获取文件。如果您让 Mustache 以它喜欢的方式执行此操作,则无需提供完整路径,只需提供文件名即可。但是类加载器只在某些地方查找,WEB-INF/lib 目录就是其中之一。网络上的许多人建议将 Mustache 模板放在 WEB-INF/lib 目录中。

      由于我的项目是 Maven 项目,我将模板文件移至 src/main/resources 目录。 (在 NetBeans 中,这是 Projects 窗格中的“Other Sources”。)在构建时,Maven 将其中的任何内容转储到WEB-INF/lib 中。然后我只需要更改我的源代码以使用文件名,而不是文件的真实路径(就像我一直在做的那样)。一切正常。

      所以,就我而言,我的问题源于将模板文件放置在对 Mustache 来说很尴尬的位置。如果有人有更好的想法,或者有什么要补充的,我会全力以赴。

      【讨论】:

      • 我仍然更喜欢 WEB-INF 和 servlet 上下文方法,因为它允许我与现有文件目录集成。但也许您可以提供更多关于为什么 servlet 上下文方法不是最佳实践的意见?您的意思是作为一般规则还是仅针对 Mustache 库文件?
      • 我的意思只是关于胡子。我已经将 WEB-INF 目录用于许多其他事情。关于“最佳实践”,从我当时所做的研究来看,这似乎是大多数人正在做的事情。此外,这样做符合 Mustache 的期望,我倾向于按照设计工作的方式使用事物,特别是如果这意味着不必跳过箍。如果“最佳实践”似乎过于强烈,我不会争论这一点。在我看来,这种方式可以说是主观的..
      • 有效参数。我并没有针对“最佳实践”的任何严格定义。谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多