【Velocity五】Velocity模板引擎
脱离Servlet容器使用Velocity
package com.tom.velocity;
import java.io.InputStream;
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 HelloVelocity {
public static void main(String[] args) throws Exception {
//实例化并初始化Velocity模板引擎
VelocityEngine ve = new VelocityEngine();
Properties p = new Properties();
InputStream in = HelloVelocity.class.getClassLoader().getResourceAsStream("velocity.properties");
p.load(in);
ve.init(p);
//从指定目录下加载自定的vm文件
Template t = ve.getTemplate("vm/hello.vm");
//创建Velocity上下文环境,用于在vm和Java传值
VelocityContext context = new VelocityContext();
context.put("name", "tom");
context.put("job", "code-farmer");
//将模板序列化为字符串文档,进行打印
StringWriter writer = new StringWriter();
t.merge(context, writer);
//将模板引擎解析的结果打印输出
System.out.println(writer.toString());
//输出
/*
<p>name: tom</p>
<p>job: code-farmer</p>
*/
}
}
velocity.properties文件
存放在classpath根目录下,内容:
resource.loader=class
#Why ClasspathResourceLoader search the vm in the root directory of classpath
#This means, <class.resource.loader.path> doesn't take effect
class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
class.resource.loader.path=vm
hello.vm文件
存放在{classpath根目录}/vm目录下。
<p>name: $name</p>
<p>job: $job</p>
Velocity解析过程
t.merge(context, writer);
这个方法用于将模板t使用context中的key/value进行解析,然后通过writer将解析结果返回来。
在解析的时候,Template根据vm文件中的指令,变量等,切分为多个Node,每个Node根据其类型采用不同的策略进行,如下是常见的Node类型对应的Java类
上图是Node类的实现,比如ASTSetDirective用于解析#set指定,ASTText是不包含模板标记的普通文本
上图右边是SimpleNode实现类列表
问题:
在velocity.properties文件中指定了从Classpath加载vm资源,同时指定加载的目录是classpath下的vm目录(通过class.resource.loader.path=vm指定),为什么在Java代码需要指定vm/hello.vm,不是hello.vm来加载资源(Template t = ve.getTemplate("vm/hello.vm");)