Невозможно найти ресурсы шаблона скорости
Просто простое приложение скорости, основанное на структуре maven. Вот фрагмент кода, написанный на Scala для рендеринга шаблона. helloworld.vm
в ${basedir}/src/main/resources
папка:
com.ggd543.velocitydemo
import org.apache.velocity.app.VelocityEngine
import org.apache.velocity.VelocityContext
import java.io.StringWriter
/**
* @author ${user.name}
*/
object App {
def main(args: Array[String]) {
//First , get and initialize an engine
val ve = new VelocityEngine();
ve.init();
//Second, get the template
val resUrl = getClass.getResource("/helloworld.vm")
val t = ve.getTemplate("helloworld.vm"); // not work
// val t = ve.getTemplate("/helloworld.vm"); // not work
// val t = ve.getTemplate(resUrl.toString); // not work yet
//Third, create a context and add data
val context = new VelocityContext();
context.put("name", "Archer")
context.put("site", "http://www.baidu.com")
//Finally , render the template into a StringWriter
val sw = new StringWriter
t.merge(context, sw)
println(sw.toString);
}
}
Когда для компиляции и запуска программы я получил следующую ошибку:
2012-1-29 14:03:59 org.apache.velocity.runtime.log.JdkLogChute log
严重: ResourceManager : unable to find resource '/helloworld.vm' in any resource loader.
Exception in thread "main" org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource '/helloworld.vm'
at org.apache.velocity.runtime.resource.ResourceManagerImpl.loadResource(ResourceManagerImpl.java:474)
at org.apache.velocity.runtime.resource.ResourceManagerImpl.getResource(ResourceManagerImpl.java:352)
at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1533)
at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1514)
at org.apache.velocity.app.VelocityEngine.getTemplate(VelocityEngine.java:373)
at com.ggd543.velocitydemo.App$.main(App.scala:20)
at com.ggd543.velocitydemo.App.main(App.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Process finished with exit code 1
14 ответов
Отличный вопрос - я решил свою проблему сегодня, используя Ecilpse:
Поместите шаблон в ту же иерархию папок, что и исходный код (а не в отдельную иерархию папок, даже если вы включили его в путь сборки), как показано ниже:
В вашем коде просто используйте следующие строки кода (при условии, что вы просто хотите, чтобы дата передавалась как данные):
VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); ve.init(); VelocityContext context = new VelocityContext(); context.put("date", getMyTimestampFunction()); Template t = ve.getTemplate( "templates/email_html_new.vm" ); StringWriter writer = new StringWriter(); t.merge( context, writer );
Посмотрите, как сначала мы говорим VelocityEngine искать в пути к классам. Без этого он не знал бы, где искать.
Я положил свой.vm под src/main/resources/templates
тогда код такой:
Properties p = new Properties();
p.setProperty("resource.loader", "class");
p.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
Velocity.init( p );
VelocityContext context = new VelocityContext();
Template template = Velocity.getTemplate("templates/my.vm");
это работает в веб-проекте.
В eclipse Velocity.getTemplate("my.vm") работает, так как скорость будет искать файл.vm в src / main / resources / или src / main / resources / templates, но в веб-проекте мы должны использовать Velocity.getTemplate ("шаблоны /my.vm");
Вы можете просто использовать это так:
Template t = ve.getTemplate("./src/main/resources/templates/email_html_new.vm");
Оно работает.
Я сталкивался с подобной проблемой с интеллигентами IDEA. Вы можете использовать это
VelocityEngine ve = new VelocityEngine();
Properties props = new Properties();
props.put("file.resource.loader.path", "/Users/Projects/Comparator/src/main/resources/");
ve.init(props);
Template t = ve.getTemplate("helloworld.vm");
VelocityContext context = new VelocityContext();
Я поместил этот рабочий фрагмент кода для будущих ссылок. Пример кода был написан для Apache speed version 1.7 со встроенной Jetty.
Путь к шаблону Velocity находится в подпапке ресурса email_templates.
Фрагмент кода в Java (фрагменты кода работают как на затмении, так и внутри Jar-файла)
...
templateName = "/email_templates/byoa.tpl.vm"
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
Template t = ve.getTemplate(this.templateName);
VelocityContext velocityContext = new VelocityContext();
velocityContext.put("","") // put your template values here
StringWriter writer = new StringWriter();
t.merge(this.velocityContext, writer);
System.out.println(writer.toString()); // print the updated template as string
Для OSGI вставляем фрагменты кода.
final String TEMPLATE = "resources/template.vm // located in the resource folder
Thread current = Thread.currentThread();
ClassLoader oldLoader = current.getContextClassLoader();
try {
current.setContextClassLoader(TemplateHelper.class.getClassLoader()); // TemplateHelper is a class inside your jar file
Properties p = new Properties();
p.setProperty("resource.loader", "class");
p.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
Velocity.init( p );
VelocityEngine ve = new VelocityEngine();
Template template = Velocity.getTemplate( TEMPLATE );
VelocityContext context = new VelocityContext();
context.put("tc", obj);
StringWriter writer = new StringWriter();
template.merge( context, writer );
return writer.toString() ;
} catch(Exception e){
e.printStackTrace();
} finally {
current.setContextClassLoader(oldLoader);
}
Убедитесь, что у вас правильно настроен загрузчик ресурсов. См. Документацию Velocity для получения справки по выбору и настройке загрузчика ресурсов: http://velocity.apache.org/engine/releases/velocity-1.7/developer-guide.html.
VelocityEngine velocityEngin = new VelocityEngine();
velocityEngin.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
velocityEngin.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
velocityEngin.init();
Template template = velocityEngin.getTemplate("nameOfTheTemplateFile.vtl");
Вы можете использовать приведенный выше код, чтобы установить свойства для шаблона скорости. Затем вы можете указать имя файла tempalte при инициализации шаблона, и он найдет, существует ли он в пути к классам.
Все вышеперечисленные классы взяты из пакета org.apache.velocity*
Вы можете попробовать добавить этот код:
VelocityEngine ve = new VelocityEngine();
String vmPath = request.getSession().getServletContext().getRealPath("${your dir}");
Properties p = new Properties();
p.setProperty("file.resource.loader.path", vmPath+"//");
ve.init(p);
Я делаю это и пас!
Используя сообщество IntelIJ Idea 2021.3, вам просто нужно запустить свой проект с этой конфигурацией:
VelocityEngine engine = new VelocityEngine();
Properties props = new Properties();
final String path = "src/main/resources/templates/";
props.put("file.resource.loader.path", path);
engine.init(props);
Вы можете указать любой путь, который хотите, но помните, что он будет начинаться с project_root, определенного в идее.
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ Это решение может НЕ работать вне среды IDE.
Следующий код помог мне решить проблему. Путь к шаблону должен быть указан как часть пути file.resource.loader. По умолчанию это "." . Поэтому потребуется явная установка свойства.
Распечатать
getClass().getClassLoader().getResource("resources")
или же
getClass().getClassLoader().getResource("")
чтобы увидеть, откуда приходит ваш шаблон, и на основе этого установить его в механизме шаблонов скорости.
URL url = getClass().getClassLoader().getResource("resources");
//URL url = getClass().getClassLoader().getResource("");
File folder= new File(url.getFile());
VelocityEngine ve = new VelocityEngine();
ve.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, folder.getAbsolutePath());
ve.init();
Template template = ve.getTemplate( "MyTemplate.vm" );
Вы также можете поместить папку с шаблонами в src/main/resources вместо src/main/java. Работает для меня, и это предпочтительное место, так как шаблоны не являются источником Java.
При использовании встроенного джета свойство webapp.resource.loader.path должно начинаться с косой черты:
webapp.resource.loader.path=/templates
в противном случае шаблоны не будут найдены в../webapp/templates
Я столкнулся с подобной проблемой. Я копировал почтовые шаблоны скоростного движка в неправильную папку. Поскольку JavaMailSender и VelocityEngine объявлены как ресурсы в MailService, необходимо добавить шаблоны в папку ресурсов, объявленную для проекта.
Я внес изменения, и это сработало. Поместите шаблоны как
src/main/resources/templates/<package>/sampleMail.vm
Просто простое приложение скорости, основанное на структуре maven. Вот фрагмент кода, написанный на Scala для визуализации шаблона helloworld.vm в
${basedir}/src/main/resources folder: