Velocity是一种基于java的模板引擎,他允许任何人使用简单而强大的模板语言来引用定义在java代码中的对象。
一、基本语法
用 # 来标识velocity的脚本语句
常用的有: #set、 #if、 #else、 #end 、#foreach、 #include、 #parse、 #macro
<1> 定义变量并赋值
#set($param="xxx");
其中param的值可以是从数据源传递过来的value,一般尽量不要在vm文件中用set给变量赋值。
<2> velocity中的判断语句
#if($value)...#else...#end
<3> velocity中的循环语句
#foreach($item in $listValue)...#end
<4> 在文件中引入其他vm文件
#include("templates/xxx.vm");
#parse("templates/xxx.vm");
include和parse的区别在于,若包含的文件中有velocity脚本标签,parse将会进一步解析,而include将原样显示。
<5> 定义宏(相当于函数块)
#macros(函数名 $函数参数 $函数参数)...#end
例如定义#macros(header $title $msg)
,则调用时:#header($title $msg)
变量可以包含的字符有以下内容:
- 字母(a···z, A···Z)
- 数字(0···9)
- 连接符(“-”)
- 下划线(“_”)
$ 用来标识一个对象(或理解为变量)
如:$msg、 $list 、 $user.name()
{} 用来明确标识velocity变量
如: $field,此时field作为变量名,若要在field变量后面紧接着显示“_id”字符,则应表示为${field}_id
! 用来强制把不存在的变量系显示为空白
如: 当前页面中包含$!msg,如果msg对象有值,将显示msg的值;若不存在msg对象或者msg变量为null时,可以将即显示为空白。
当找不到msg时,$msg
返回字符串msg,而$!msg
返回空字符串”“注释
##
单行注释
#* ··· *#
多行注释单双引号
#set($var="hello")
'$var'
结果显示为$var
"$var"
结果显示为hello
二、基本使用
- 初始化模板引擎
VelocityEngine ve = new VelocityEngine( );
ve.init( ); - 获取模板文件,得到模板引用
Template t = ve.getTemplate(“xxx.vm”); - 初始化换将,并将数据放入环境
VelocityContext context = new VelocityContext( );
context.put(“param1”,value); - 将模板文件与输出部分结合
StringWriter writer = new StringWriter( );
t.merge(context,writer);
writer.flush( );
补充:可以给模板引擎设置属性
如:为防止出现乱码,可以如下设置
ve.setProperty(“input.encoding”,”utf-8”);
ve.setProperty(“output.encoding”,”utf-8”);
三、实例应用
测试类代码:
package com.lantu.test;
import java.io.StringWriter;
import java.util.Properties;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.log.CommonsLogLogChute;
public class Test {
private static String TEMPLATES_BASE_PATH = "./src/main/resources/templates/";
public static void main(String[] args) throws Exception {
VelocityEngine ve = new VelocityEngine();
Properties p = new Properties();
// p.setProperty("resource.loader", "class");
// p.setProperty("class.resource.loader.description", "VelocityClasspath Resource Loader");
// p.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
p.setProperty("runtime.log.logsystem.class", CommonsLogLogChute.class.getName());
ve.init(p);
Template template = ve.getTemplate(getVelocityFilePath("helloworld.vm"), "utf-8");
VelocityContext context = new VelocityContext();
context.put("detail", "this is my first velocity file test!");
StringWriter writer = new StringWriter();
template.merge(context, writer);
writer.flush();
System.out.println(writer.toString());
}
private static String getVelocityFilePath(String filename) {
return TEMPLATES_BASE_PATH + filename;
}
}
vm文件代码:
#set($detail2show="$detail")
$detail2show
运行结果:
this is my first velocity file test!
四、经验总结
- 需要引入的jar包(jar包版本根据实际情况而定,一下是本人测试时使用的jar包)
- velocity-1.7.jar(引入的基本包)
- commons-collections-3.2.1.jar
若缺失这个包报错:java.lang.NoClassDefFoundError: org/apache/commons/collections/ExtendedProperties,导致VelocityEngine无法初始化 - commons-lang-2.6.jar
若缺失这个包报错:java.lang.NoClassDefFoundError: org/apache/commons/lang/StringUtils,导致VelocityEngine无法初始化
原因为加载资源文件时ResourceManagerImpl.java需要用到该类
- 报错处理
Failed to initialize an instance of org.apache.velocity.runtime.log.NullLogSystem
该问题出现在为给ve设置属性时,后添加设置p.setProperty("runtime.log.logsystem.class", CommonsLogLogChute.class.getName());
成功解决。 - vm文件路径加载
“./src/main/resources/templates/helloworld.vm”,或者”/src/main/resources/templates/helloworld.vm”
其中“.”指的是资源根路径,若不从src路径开始写的话会报错找不到资源文件。其根本原因为加载vm文件时的路径获取方式,可以从ClasspathResourceLoader开始追寻源代码。