Velocity 是一个基于 Java 的模板引擎,它允许你使用简单的模板语言来引用由 Java 代码定义的对象,它被广泛用于生成源代码、报告、XML、电子邮件等。

下面我将分步介绍,从环境搭建到核心概念,再到完整的代码示例。
核心概念
在开始之前,理解 Velocity 的三个核心组件非常重要:
- 模板: 一个文本文件,通常以
.vm(Velocity Macro) 为后缀,它混合了静态文本和 Velocity 指令(如#if,#foreach, ),这是你要生成内容的“蓝图”。 - 上下文: 一个 Java 对象,通常是
org.apache.velocity.context.Context的实例(最常用的是它的子类VelocityContext),它充当 Java 代码和模板之间的“数据桥梁”,你将需要在 Java 程序中生成的数据(如字符串、数字、List、Map 等)作为键值对存入这个上下文。 - 引擎:
org.apache.velocity.app.VelocityEngine的实例,它是 Velocity 的核心,负责解析模板、合并上下文数据,并最终生成输出。
整个流程可以概括为:
Java 代码 -> 准备数据 -> 存入 Context -> VelocityEngine 加载模板 -> 合并 Context 和模板 -> 生成 输出 (可以是字符串、文件等)
(图片来源网络,侵删)
环境搭建
你需要在你的 Java 项目中添加 Velocity 的依赖。
使用 Maven (推荐)
在你的 pom.xml 文件中添加以下依赖:
<dependencies>
<!-- Velocity 核心库 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version> <!-- 建议使用较新版本 -->
</dependency>
</dependencies>
使用 Gradle
在你的 build.gradle 文件中添加:
dependencies {
implementation 'org.apache.velocity:velocity-engine-core:2.3'
}
完整调用示例
下面我们通过一个完整的例子来演示如何从 Java 代码调用 Velocity 模板。

第 1 步:创建模板文件
在你的项目 src/main/resources 目录下创建一个名为 hello.vm 的文件。
src/main/resources/hello.vm
#**
这是一个 Velocity 模板文件
*#
## 这是一个注释,不会出现在输出中
## 使用 $ 引用变量
欢迎您, ${name}!
## 使用 #if 进行条件判断
#if ($age >= 18)
您已成年,年龄是 ${age} 岁。
#else
您还未成年,年龄是 ${age} 岁。
#end
## 使用 #foreach 遍历集合
<h3>您的爱好列表:</h3>
<ul>
#foreach ($hobby in $hobbies)
<li>$hobby</li>
#end
</ul>
## 使用 #set 设置变量
#set ($greeting = "Velocity is fun!")
<p>$greeting</p>
第 2 步:编写 Java 代码
创建一个 Java 类来加载模板、填充数据并生成输出。
HelloVelocity.java
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
public class HelloVelocity {
public static void main(String[] args) {
// 1. 初始化 VelocityEngine (引擎)
VelocityEngine velocityEngine = new VelocityEngine();
// 配置引擎:从 classpath 加载模板文件
velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
velocityEngine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
// 初始化引擎
velocityEngine.init();
// 2. 创建 VelocityContext (上下文) 并填充数据
VelocityContext context = new VelocityContext();
context.put("name", "张三");
context.put("age", 25);
List<String> hobbies = new ArrayList<>();
hobbies.add("编程");
hobbies.add("阅读");
hobbies.add("旅行");
context.put("hobbies", hobbies);
// 3. 加载模板
Template template = velocityEngine.getTemplate("hello.vm");
// 4. 合并模板和上下文,生成输出
StringWriter writer = new StringWriter();
template.merge(context, writer);
// 5. 输出结果
System.out.println("--- Velocity 生成的输出 ---");
System.out.println(writer.toString());
}
}
第 3 步:运行和查看结果
运行 HelloVelocity 的 main 方法,你将在控制台看到以下输出:
--- Velocity 生成的输出 ---
欢迎您, 张三!
您已成年,年龄是 25 岁。
<h3>您的爱好列表:</h3>
<ul>
<li>编程</li>
<li>阅读</li>
<li>旅行</li>
</ul>
<p>Velocity is fun!</p>
关键代码解析
-
VelocityEngine初始化与配置:new VelocityEngine(): 创建引擎实例。setProperty(...): 设置引擎属性,这里最关键的是配置资源加载器。RuntimeConstants.RESOURCE_LOADER, "classpath": 指定使用classpath资源加载器。"classpath.resource.loader.class", ClasspathResourceLoader.class.getName(): 指定classpath加载器的具体实现类,这样 Velocity 就知道去src/main/resources等类路径下寻找模板文件。init(): 执行初始化,应用所有配置。
-
VelocityContext数据填充:new VelocityContext(): 创建一个空的上下文。context.put("key", value): 向上下文中添加数据,模板中通过$key来访问这些数据。value可以是任何 Java 对象(String, Integer, List, Map, 自定义 POJO 等)。
-
加载与合并:
velocityEngine.getTemplate("hello.vm"): 根据模板名称从类路径加载模板,如果模板不存在,会抛出异常。new StringWriter(): 创建一个StringWriter,它就像一个内存中的文本写入器,用于接收模板合并后的结果。template.merge(context, writer): 这是核心步骤,它将上下文中的数据注入模板,并将最终生成的文本写入StringWriter。
进阶用法:将输出写入文件
如果你不想将结果输出到控制台,而是写入到一个文件中,可以使用 FileWriter。
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Properties;
public class VelocityToFile {
public static void main(String[] args) {
// 1. 初始化引擎
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
// 2. 准备上下文数据
VelocityContext context = new VelocityContext();
context.put("title", "用户报告");
context.put("user", new User("李四", 30)); // 也可以传入自定义对象
// 3. 加载模板
Template t = ve.getTemplate("report.vm"); // 假设有一个 report.vm 模板
// 4. 创建文件写入器并合并
Writer writer = null;
try {
// 指定输出文件的路径
writer = new FileWriter("output/report.html");
t.merge(context, writer);
System.out.println("报告已成功生成到 output/report.html");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
// 一个简单的 POJO
class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
// Velocity 会通过反射调用 getter 方法,所以必须有标准的 getter
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
report.vm 示例:
<html>
<head>$title</title>
</head>
<body>
<h1>用户详情</h1>
<p>姓名: $user.name</p>
<p>年龄: $user.age</p>
</body>
</html>
调用 Velocity 的流程非常清晰:
- 引入依赖: 在
pom.xml或build.gradle中添加velocity-engine-core。 - 准备模板: 在
resources目录下创建.vm文件,使用 Velocity 语法编写内容。 - 初始化引擎: 创建
VelocityEngine实例并配置资源加载器(通常是ClasspathResourceLoader)。 - 填充数据: 创建
VelocityContext,将你的 Java 数据(变量、集合、对象)放入其中。 - 加载与合并: 使用引擎加载模板,然后调用
template.merge(context, writer)生成最终结果。 - 处理输出: 将结果输出到控制台、文件、网络响应等任何地方。

