小胡子在 NetBeans servlet 中抛出 "File not under root" 异常
Mustache throws "File not under root" exception in NetBeans servlet
编辑:我解决了我的问题。 (见下文。)
问题
我是 NetBeans 的新手,我遇到了一个问题,涉及将资源加载到我的 servlet 应用程序,该应用程序 运行 通过 NetBeans 使用 Tomcat 作为服务器。一切都很好,直到我尝试使用 Mustache 模板库(在 Java 中)构建我的响应。此时,抛出异常:
com.github.mustachejava.MustacheException: File not under root: /opt/catalina/bin
这个异常是在我尝试编译模板文件的代码中抛出的。我将资源(模板文件)的路径提供给 MustacheFactory
的 compile
方法。我的代码如下所示:
MustacheFactory mf = new DefaultMustacheFactory();
Mustache mustache = mf.compile(getFormTemplatePath());
我的研究
我查看了 Mustache 代码,据我所知,这是正在发生的事情。 Mustache 在加载资源时会进行安全检查,以确保资源位于文件系统中应用程序的根目录下。由于 NetBeans 正在对 运行 服务器上的代码施展某种魔法,而项目的代码实际上位于文件系统的其他位置,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...]
我在以下 URL:
在线找到了 Mustache 代码
我的假设解
我猜想一定有某种方法可以在 NetBeans 中配置应用程序,当我选择和配置服务器时,可以解决这个问题。我试过的是谷歌搜索 Mustache NetBeans servlet "File not under root" exception
等的变体,但没有什么结果。我猜我什至对 NetBeans 的了解还不够,不知道应该使用哪些关键词进行搜索。甚至有可能我已经找到了解决方案,但是当我看到它时不认识它。
有人知道我可以尝试什么吗?谢谢。
模板文件放在哪里?
我自己解决了这个问题,尽管我通过对模板文件做一些更好的事情来解决它。最初,我将模板文件放在 WEB-INF
目录中,然后使用 servlet 上下文构建文件路径。这似乎不是最佳做法。
再看一下 Mustache 源代码,我意识到 Mustache 首先尝试使用类加载器来获取文件。如果您让 Mustache 以其首选方式执行此操作,则无需提供完整路径,只需提供文件名即可。但是类加载器只在某些地方查找,WEB-INF/lib
目录就是其中之一。网上有很多人建议将 Mustache 模板放在 WEB-INF/lib
目录中。
由于我的是Maven项目,我将模板文件移动到src/main/resources
目录。 (在 NetBeans 中,这是“项目”窗格中的 "Other Sources"。)在构建时,Maven 会获取其中的所有内容并将其转储到 WEB-INF/lib
中。然后我只需要更改我的源代码以使用文件名,而不是文件的真实路径(就像我一直在做的那样)。一切正常。
因此,就我而言,我的问题源于将模板文件放置在对 Mustache 来说很尴尬的位置。如果有人有更好的想法,或者有什么要补充的,我会洗耳恭听。
您可以改用其他重载 API
Mustache compile(Reader reader, String name);
就像这样,您可以更喜欢将小胡子模板文件放在任何地方
File f = new File(templateFilePath);
Mustache mustache = mf.compile(new InputStreamReader(new FileInputStream(f),Charset.forName("UTF-8")),f.getName());
编辑:我解决了我的问题。 (见下文。)
问题
我是 NetBeans 的新手,我遇到了一个问题,涉及将资源加载到我的 servlet 应用程序,该应用程序 运行 通过 NetBeans 使用 Tomcat 作为服务器。一切都很好,直到我尝试使用 Mustache 模板库(在 Java 中)构建我的响应。此时,抛出异常:
com.github.mustachejava.MustacheException: File not under root: /opt/catalina/bin
这个异常是在我尝试编译模板文件的代码中抛出的。我将资源(模板文件)的路径提供给 MustacheFactory
的 compile
方法。我的代码如下所示:
MustacheFactory mf = new DefaultMustacheFactory();
Mustache mustache = mf.compile(getFormTemplatePath());
我的研究
我查看了 Mustache 代码,据我所知,这是正在发生的事情。 Mustache 在加载资源时会进行安全检查,以确保资源位于文件系统中应用程序的根目录下。由于 NetBeans 正在对 运行 服务器上的代码施展某种魔法,而项目的代码实际上位于文件系统的其他位置,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...]
我在以下 URL:
在线找到了 Mustache 代码我的假设解
我猜想一定有某种方法可以在 NetBeans 中配置应用程序,当我选择和配置服务器时,可以解决这个问题。我试过的是谷歌搜索 Mustache NetBeans servlet "File not under root" exception
等的变体,但没有什么结果。我猜我什至对 NetBeans 的了解还不够,不知道应该使用哪些关键词进行搜索。甚至有可能我已经找到了解决方案,但是当我看到它时不认识它。
有人知道我可以尝试什么吗?谢谢。
模板文件放在哪里?
我自己解决了这个问题,尽管我通过对模板文件做一些更好的事情来解决它。最初,我将模板文件放在 WEB-INF
目录中,然后使用 servlet 上下文构建文件路径。这似乎不是最佳做法。
再看一下 Mustache 源代码,我意识到 Mustache 首先尝试使用类加载器来获取文件。如果您让 Mustache 以其首选方式执行此操作,则无需提供完整路径,只需提供文件名即可。但是类加载器只在某些地方查找,WEB-INF/lib
目录就是其中之一。网上有很多人建议将 Mustache 模板放在 WEB-INF/lib
目录中。
由于我的是Maven项目,我将模板文件移动到src/main/resources
目录。 (在 NetBeans 中,这是“项目”窗格中的 "Other Sources"。)在构建时,Maven 会获取其中的所有内容并将其转储到 WEB-INF/lib
中。然后我只需要更改我的源代码以使用文件名,而不是文件的真实路径(就像我一直在做的那样)。一切正常。
因此,就我而言,我的问题源于将模板文件放置在对 Mustache 来说很尴尬的位置。如果有人有更好的想法,或者有什么要补充的,我会洗耳恭听。
您可以改用其他重载 API
Mustache compile(Reader reader, String name);
就像这样,您可以更喜欢将小胡子模板文件放在任何地方
File f = new File(templateFilePath);
Mustache mustache = mf.compile(new InputStreamReader(new FileInputStream(f),Charset.forName("UTF-8")),f.getName());