无法找到速度模板资源

时间:2012-01-29 06:31:25

标签: java scala velocity

基于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

12 个答案:

答案 0 :(得分:95)

很棒的问题 - 我今天使用Ecilpse解决了我的问题:

  1. 将模板放在与源代码相同的文件夹层次结构中(即使将其包含在构建路径中,也不在单独的文件夹层次结构中),如下所示: Where to put your template file

  2. 在您的代码中,只需使用以下代码行(假设您只想将日期作为数据传递):

    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 );
    
  3. 首先我们告诉VelocityEngine如何查看类路径。没有它,它就不知道在哪里看。

答案 1 :(得分:22)

我将.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");

这适用于web项目。

在eclipse中,Velocity.getTemplate(“my.vm”)有效,因为velocity会在src / main / resources /或src / main / resources / templates中查找.vm文件,但在web项目中,我们必须使用Velocity.getTemplate( “模板/ my.vm”);

答案 2 :(得分:6)

您可以像这样使用它:

Template t = ve.getTemplate("./src/main/resources/templates/email_html_new.vm");

有效。

答案 3 :(得分:3)

确保您拥有正确配置的资源加载器。有关选择和配置资源加载器的帮助,请参阅Velocity文档:http://velocity.apache.org/engine/releases/velocity-1.7/developer-guide.html#resourceloaders

答案 4 :(得分:2)

您可以尝试添加以下代码:

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);

我这样做,并通过!

答案 5 :(得分:2)

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 *

答案 6 :(得分:0)

使用嵌入式jetty时,属性webapp.resource.loader.path应以斜杠开头:

webapp.resource.loader.path=/templates

否则将无法在../ webapp / templates

中找到模板

答案 7 :(得分:0)

您也可以将模板文件夹放在src / main / resources下,而不是src / main / java。适用于我,它是一个更好的位置,因为模板不是java源。

答案 8 :(得分:0)

我遇到了类似的问题。我正在将错误文件夹中的速度引擎邮件模板复制。由于 JavaMailSender VelocityEngine MailService 下被声明为资源,因此需要在为项目声明的资源文件夹下添加模板。

我做了改动而且工作正常。将模板设为

src/main/resources/templates/<package>/sampleMail.vm

答案 9 :(得分:0)

我已将此工作代码段用作以后的参考。该代码示例是使用带有嵌入式Jetty的Apache Velocity 1.7版编写的。

速度模板路径位于资源文件夹email_templates子文件夹中。

enter image description here

Java中的代码段(这些代码段既可以在Eclipse上运行,也可以在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);
       }

答案 10 :(得分:0)

以下代码帮助我解决了问题。 模板路径需要作为 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" );

答案 11 :(得分:-1)

基于maven结构的简单速度独立应用。以下是用Scala编写的代码片段,用于在

中呈现模板helloworld.vm
${basedir}/src/main/resources folder: