2015-02-06 84 views
1

编辑:我解决了我的问题。 (见下文)。小胡子在NetBeans servlet中抛出“File under root”异常

问题

我是新来的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在加载资源时执行安全检查,试图确保资源位于文件系统中应用程序的根目录下。由于NetBeans在Tomcat服务器上运行代码有点神奇,而项目的代码实际上是在文件系统上的其他位置,所以Mustache认为有些可疑的事情正在发生。

换句话说,它可以找到文件;它只是不喜欢它在哪里找到它。看起来好像Mustache需要/opt/catalina/bin作为应用程序的根,而模板文件实际上处于更类似于如下路径:~/NetBeansProjects/MyProject/WEB-INF/template_file.mst

胡子代码如下所示(只是让你可以检查我的推理):

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...] 

我找到了胡子码在线在以下网址:

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知道我应该搜索哪些关键词。我甚至有可能找到了解决方案,但是当我看到它时却不认识它。

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

回答

2

何处放置模板文件?

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

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

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

所以,就我而言,我的问题源于把模板文件放在胡须的尴尬位置。如果任何人有更好的主意,或其他任何补充,我都耳朵。

+0

我还是比较喜欢'WEB-INF'和servlet上下文方法,因为它允许我与我现有的文件目录集成。但是,也许你可以提供一些关于为什么Servlet上下文方法不是最佳实践的更多意见?你的意思是说,作为一般规则还是仅仅关于'Mustache'库文件? – 2017-06-08 07:07:23

+0

我的意思只是关于胡子。我已经使用WEB-INF目录来了解其他许多事情。关于我在当时正在做的研究中的“最佳实践”,似乎这是大多数人正在做的事情。此外,这样做符合了胡须的期望,我倾向于按照他们设计的方式使用事物,特别是如果这意味着不需要跳过这些环节。如果“最佳实践”似乎太强大的描述,我不会争辩这一点。这似乎对我来说,可以说,是主观的.. – Mario 2017-06-09 14:16:23

+0

有效的论据。我不是针对“最佳实践”的严格定义。谢谢。 – 2017-06-09 14:32:36

2

可以使用其他重载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());