本文基于 Velocity 1.7 版本撰写。
概述
什么是Velocity?
Velocity是一个基于java的模板引擎(template engine)。它允许任何人仅仅简单的使用模板语言(template language)来引用由java代码定义的对象。
当Velocity应用于web开发时,界面设计人员可以和java程序开发人员同步开发一个遵循MVC架构的web站点,也就是说,页面设计人员可以只 关注页面的显示效果,而由java程序开发人员关注业务逻辑编码。Velocity将java代码从web页面中分离出来,这样为web站点的长期维护提 供了便利,同时也为我们在JSP和PHP之外又提供了一种可选的方案。
Velocity的能力远不止web站点开发这个领域,例如,它可以从模板(template)产生SQL和PostScript、XML,它也可以被当作一个独立工具来产生源代码和报告,或者作为其他系统的集成组件使用。Velocity也可以为Turbine web开发架构提供模板服务(template service)。Velocity+Turbine提供一个模板服务的方式允许一个web应用以一个真正的MVC模型进行开发。
安装
如果你的项目是 maven 项目,添加依赖到 pom.xml 中即可。
org.apache.velocity
velocity
1.7
非maven项目,可以去官网下载 jar 包:官网下载地址
Velocity 编程模型
HelloWorld 示例
先展示一个最简单的HelloWorld示例。
VelocityHelloWorld.java
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import java.io.StringWriter;
/**
* Velocity 的 HelloWorld 示例
*
* @author Victor Zhang
* @date 2016/12/22.
*/
public class VelocityHelloWorld {
public static void main(String args[]) {
/* 1.初始化 Velocity */
VelocityEngine velocityEngine = new VelocityEngine();
velocityEngine.setProperty(VelocityEngine.RESOURCE_LOADER, "file");
velocityEngine.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, "D:/01_Workspace/Project/zp/javaparty/src/toolbox/template/src/main/resources");
velocityEngine.init();
/* 2.创建一个上下文对象 */
VelocityContext context = new VelocityContext();
/* 3.添加你的数据对象到上下文 */
context.put("name", "Victor Zhang");
context.put("project", "Velocity");
/* 4.选择一个模板 */
Template template = velocityEngine.getTemplate("template/hello.vm");
/* 5.将你的数据与模板合并,产生输出内容 */
StringWriter sw = new StringWriter();
template.merge(context, sw);
System.out.println("final output:\n" + sw);
}
}
hello.vm
在你的 resources (一般路径为src/main/resources
) 目录下创建 template/helloVelocity.vm
文件。
文件内容如下:
Hello World! The first velocity demo.
Name is $name.
Project is $project
输出
final output:
Hello World! The first velocity demo.
Name is Victor Zhang.
Project is Velocity
编程模型
通过HelloWorld示例,不难总结出Velocity的编程模型,大致如下:
- 初始化 Velocity 。
- 创建一个上下文对象。
- 添加你的数据对象到上下文。
- 选择一个模板。
- 将你的数据与模板合并,产生输出内容。
使用Properties定制Velocity
properties 文件
在HelloWorld示例中,第一步初始化过程中,设值了两个 java.util.Properties
参数。
VelocityEngine velocityEngine = new VelocityEngine();
velocityEngine.setProperty(VelocityEngine.RESOURCE_LOADER, "file");
velocityEngine.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, "D:/01_Workspace/Project/zp/javaparty/src/toolbox/template/src/main/resources");
velocityEngine.init();
这两个参数是用来在初始化 Velocity 模板引擎时,对它进行定制。
显然,如果每次都要逐一设值定制参数是很麻烦的。所以,可以将 java.util.Properties
参数统一置于properties 文件中,然后加载进来。
这样做的好处有两点:
- 减少大量配置代码
- 配置文件可以被多个引擎模板复用
velocity.properties
在你的 resources (一般路径为src/main/resources
) 目录下创建 template/velocity.properties
文件。
resource.loader = file
file.resource.loader.path = D:/01_Workspace/Project/zp/javaparty/src/toolbox/template/src/main/resources
初始化部分的代码替换如下:
Properties p = new Properties();
try {
p.load(VelocityDemo.class.getResourceAsStream("/template/velocity.properties"));
} catch (IOException e) {
e.printStackTrace();
}
VelocityEngine velocityEngine = new VelocityEngine();
velocityEngine.init(p);
输出
效果与HelloWorld的示例是一样的。
Velocity 定制参数
Velocity 常见的定制参数可以在 org.apache.velocity.runtime.RuntimeConstants
中找到。你可以设值日志、事务句柄、宏、加载资源方式等等重要配置。
更多详情见:Velocity 官方开发者指南
Velocity 语法
注释
单行注释
以 ##
开头。
## This is a single line comment.
多行注释
以 #*
开头,以 *#
结尾。
#*
Thus begins a multi-line comment. Online visitors won't
see this text because the Velocity Templating Engine will
ignore it.
*#
引用
在 Velocity 中有三种类型的引用:变量,属性和函数。
变量(Variables)
和我们所熟知的其他编程语言一样,Velocity 也可以在模板文件中有变量的概念。
变量以 $
开头,首字母必须是英文字母。变量允许的字符为以下几种类型:
字母(a .. z, A .. Z)
数字(0 .. 9)
连字符("-")
下划线("_")
有效范例:
$foo
$mudSlinger
$mud-slinger
$mud_slinger
$mudSlinger1
变量定义
可以使用 #set
来为变量定义。
#set( $foo = "bar" )
属性(Properties)
属性以 $
开头,标识符间以 .
分隔。
有效范例:
$customer.Address
$purchase.Total
函数(Methods)
有效范例:
## 无参数
$customer.getAddress()
$purchase.getTotal()
## 单个参数
$page.setTitle( "My Home Page" )
## 参数列表
$person.setAttributes( ["Strange", "Weird", "Excited"] )
Velocity 1.6 开始支持重载函数。
$sun.setPlanets('Earth', 'Mars', 'Neptune')
$sun.setPlanets('Mercury')
$sun.setPlanets()
条件语句
条件语句必须以 #if
开始,以 #end
结尾。
用法与Java中的条件语句极其相似,看看例子就能懂。
#if( $foo )
Velocity!
#end
注意:Velocity中的 ==
的语义与Java略有不同,其中 ==
只能用于测试对象的相等性。在Velocity中,等效运算符可以用于直接比较数字,字符串或对象。当对象具有不同的类时,通过为每个对象调用 toString() 然后比较来获得字符串表示。
#set ($foo = "north")
#set ($bar = "north")
#if( $foo == $bar )
**Go North**
#elseif( $foo == "east" )
**Go East**
#elseif( $bar == "south" )
**Go South**
#else
**Go West**
#end
Velocity 中的条件语句也可以使用与、或、非。
#if( $foo && $bar )
**This AND That**
#end
#if( $foo || $bar )
**This OR That**
#end
#if( !$foo )
**NOT that**
#end
循环
#foreach
用来控制一个循环语句。
#foreach
支持遍历一个 Vector、Hashtable 或 Array 对象。
#foreach( $key in $allProducts.keySet() )
- Key: $key -> Value: $allProducts.get($key)
#end
可以使用 #break
跳出循环。$foreach.count
表示循环次数。
## list first 5 customers only
#foreach( $customer in $customerList )
#if( $foreach.count > 5 )
#break
#end
$customer.Name
#end
五、宏
Velocity 中的宏可以理解为函数定义。定义的语法如下:
#macro(macroName arg1 arg2 …)
...
#end
调用这个宏的语法是:
#macroName(arg1 arg2 …)
这里的参数之间使用空格隔开,下面是定义和使用 Velocity 宏的例子:
#macro(sayHello $name)
hello $name
#end
#sayHello(“velocity”)
输出的结果为 hello velocity
六、#parse 和 #include
#parse 和 #include 指令的功能都是在外部引用文件,而两者的区别是,#parse 会将引用的内容当成类似于源码文件,会将内容在引入的地方进行解析,#include 是将引入文件当成资源文件,会将引入内容原封不动地以文本输出。分别看以下例子:
foo.vm 文件:
#set($name =“velocity”)
parse.vm:
#parse(“foo.vm”)
输出结果为:velocity
include.vm:
#include(“foo.vm”)
输出结果为:#set($name =“velocity”)
以上内容包含了部分 Velocity 的语法,详细的语法内容可以参考 Velocity 的官方文档。
参考
Velocity 官网
- velocity 官方开发者指南
- velocity 官方用户指南
范例
范例源码