Как #include файл из шаблона Velocity с помощью ClasspathResourceLoader
Я имею дело с некоторым кодом Java, где Velocity 1.7 настроен на получение шаблонов через ClasspathResourceLoader. Ниже приведен урезанный пример кода. Это из веб-приложения Tapestry, запущенного на сервере Jetty.
Класс Java, шаблоны и включаемый файл находятся в одной папке «testpackage», поэтому в результирующем JAR они все находятся в одном пакете «testpackage».
Проблема в том, что если шаблон содержит
#include("MyInclude.vm")
Директива, Velocity не может найти «MyInclude.vm», и она выдает ResourceNotFoundException.
Поскольку в аргументе getTemplate я должен добавить имя пакета к имени шаблона, я также попытался сделать то же самое в #include внутри шаблона:
#include("testpackage/MyInclude.vm")
но единственное отличие состоит в том, что последний работает, если я запускаю веб-приложение из Eclipse, тогда как первый не работает даже из Eclipse. Если я создаю, развертываю JAR-файлы и запускаю веб-приложение из развертывания, оба синтаксиса дают сбой с одним и тем же ResourceNotFoundException.
Документ о скорости вhttp://velocity.apache.org/engine/releases/velocity-1.7/user-guide.html#Include говорит:
«Из соображений безопасности файл, который будет включен, может быть только под TEMPLATE_ROOT»
Это определенно может быть причиной моей проблемы, но я не смог найти дополнительную информацию о том, что на самом деле представляет собой TEMPLATE_ROOT.
Это звучит очень похоже на переменную окружения, но я не знаю, как мне ее установить, так как я использую ClasspathResourceLoader, и включаемый файл - это не фактический файл, расположенный в папке, он внутри JAR содержащий шаблоны и класс Java (и все в одном пакете).
Я обнаружил, что TEMPLATE_ROOT упоминается в другом вопросе,Где мне разместить файлы шаблонов Velocity для утилиты командной строки, созданной с помощью Maven? , но это связано с использованием FileResourceLoader. Мне нужно продолжать использовать ClasspathResourceLoader, и мне нужно, чтобы все файлы были в JAR, а не вне его, как обычные файлы в какой-то папке.
TestVelocity.javapackage testpackage;
import java.io.StringWriter;
import java.util.Properties;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
public class TestVelocity
{
public static String getText()
{
String text = "";
Properties properties = new Properties();
properties.setProperty("resource.loader", "class");
properties.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
VelocityEngine engine = new VelocityEngine();
VelocityContext context = new VelocityContext();
StringWriter writer = new StringWriter();
try
{
engine.init(properties);
// This works because the template doesn't contain any #include
Template template = engine.getTemplate("testpackage/TemplateWithoutInclude.vm");
// This causes ResourceNotFoundException: Unable to find resource 'TemplateWithInclude.vm'
// Template template = engine.getTemplate("testpackage/TemplateWithInclude.vm");
template.merge(context, writer);
text = writer.toString();
}
catch (Exception e)
{
e.printStackTrace();
}
return text;
}
}
TemplateWithoutInclude.vm<!DOCTYPE html>
<html>
<head></head>
<body>
<p>Hello</p>
</body>
</html>
TemplateWithInclude.vm<!DOCTYPE html>
<html>
<head></head>
<body>
#include("MyInclude.vm")
</body>
</html>
MyInclude.vm<p>
Hello
</p>