Как #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.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>

Ответы на вопрос(1)

Ваш ответ на вопрос