Edit: Я решил свою проблему. (Смотри ниже.)
Проблема
Я новичок в NetBeans, и у меня возникла проблема, связанная с загрузкой ресурса в мое приложение сервлета, которое выполняется через NetBeans с использованием Tomcat в качестве сервера. Все нормально, пока я не попытаюсь построить свой ответ с помощью библиотеки шаблонов Mustache (на Java). В этот момент возникает исключение:
com.github.mustachejava.MustacheException: File not under root: /opt/catalina/bin
Это исключение выбрасывается прямо в точке моего кода, где я пытаюсь скомпилировать файл шаблона. Я передаю путь к ресурсу (файл шаблона) в метод compile
MustacheFactory
. Мой код выглядит так:
MustacheFactory mf = new DefaultMustacheFactory();
Mustache mustache = mf.compile(getFormTemplatePath());
Мое исследование
Я взглянул на код Усы, и, насколько я могу судить, вот что происходит. Усы выполняет проверку безопасности при загрузке ресурса, пытаясь убедиться, что ресурс находится под корнем приложения в файловой системе. Поскольку NetBeans работает с какой-то магией для запуска кода на сервере Tomcat, а код проекта фактически находится где-то в файловой системе, Усач думает, что происходит что-то подозрительное.
Другими словами, он может найти файл; ему просто не нравится, где он ее находит. Кажется, что 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...]
Я нашел код Усы в Интернете по следующему URL-адресу:
Мое гипотетическое решение
Я предполагаю, что должен быть какой-то способ настроить приложение в NetBeans, когда я выбираю и настраиваю сервер, чтобы согласовать эту проблему. То, что я пробовал, - это варианты googling для Mustache NetBeans servlet "File not under root" exception
и т.д., И ничего особенного не возникает. Я предполагаю, что я даже не знаю достаточно о NetBeans, чтобы узнать, какие ключевые слова я должен искать. Возможно даже, что я нашел решение, но не узнаю его, когда вижу его.
Кто-нибудь знает, что я могу попробовать? Благодарю.
Где разместить файл шаблона?
Я решил это самостоятельно, хотя я решил это, сделав что-то лучше с файлом шаблона. Первоначально я помещал файл шаблона в каталог WEB-INF
а затем создавал путь к файлу, используя контекст сервлета. Это не похоже на лучшую практику.
Еще раз взглянув на исходный код Mustache, я понял, что Mustache сначала пытается использовать загрузчик классов для получения файла. Если вы позволите Усачи сделать это по-своему, вам не нужно указывать полный путь, а только имя файла. Но classloader работает только в определенных местах, а WEB-INF/lib
- один. Некоторые люди в Интернете рекомендуют помещать шаблон Mustache в каталог WEB-INF/lib
.
Поскольку мой проект Maven, я переместил файл шаблона в каталог src/main/resources
. (В NetBeans это "Другие источники" на панели "Проекты".) При сборке Maven берет что-то там и выгружает его в WEB-INF/lib
. Затем мне пришлось изменить исходный код, чтобы использовать имя файла, а не реальный путь к файлу (как я это делал). Все работает.
Итак, насколько я могу судить, моя проблема связана с тем, что файл шаблона оказался неудобным для Усы. Если у кого-то есть лучшая идея или что-то еще, чтобы добавить, я все уши.
вы можете использовать другой 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());
WEB-INF
и контекст сервлета, поскольку он позволяет мне интегрироваться с моими существующими файловыми каталогами. Но, может быть, вы могли бы дать больше информации о том, почему подход с сервлетным контекстом не является лучшей практикой? Вы имеете в виду , что в качестве общего правила , либо только в отношенииMustache
библиотеки файлов?