Я имею дело с некоторым кодом 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.
Документ Velocity в 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.java
package 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>