Velocity模板引擎
# Velocity模板引擎
Apache Velocity 是一个灵活且功能强大的模板引擎,广泛应用于生成动态内容的场景。通过简单的模板语言和丰富的配置选项,Velocity 能够有效地将代码和表现层分离,帮助开发人员更好地管理和生成动态内容。掌握 Apache Velocity 之后,您可以在多个应用场景中使用它,如生成动态网页、邮件模板、配置文件等。以下是对 Velocity 技术的完整总结,涵盖了其使用方法、配置、语法细节及应用场景。
# 1. Velocity 基本概念
Velocity 是一种基于模板的引擎,它的核心理念是通过模板语言(VTL, Velocity Template Language)将静态和动态内容分离。这种设计使得开发者可以在模板中嵌入逻辑,而不用在 Java 代码中混合使用 HTML 或其他格式的字符串。
# 1.1 主要组件
- VelocityEngine:Velocity 的核心类,用于初始化引擎、加载和渲染模板。
- 模板 (Template):包含静态文本和动态占位符的文件,通常以
.vm为后缀。 - 上下文 (Context):类似于一个 Map,用于存储模板中使用的变量和数据。在渲染过程中,模板中的变量会被替换为上下文中的实际值。
- VTL (Velocity Template Language):Velocity 使用的模板语言,用于定义变量、控制逻辑、循环等。
# 2. Velocity 使用步骤
# 2.1 Maven 依赖
首先,在 Maven 项目中添加 Velocity 依赖:
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
2
3
4
5
# 2.2 创建模板文件
创建一个简单的模板文件 hello.vm,内容如下:
Hello, $name! Welcome to $city.
$name和$city是变量,使用$符号表示。- 在渲染时,这些变量会被上下文中的实际值替换。
# 2.3 初始化 Velocity 引擎
import org.apache.velocity.app.VelocityEngine;
import java.util.Properties;
public class VelocityInitializer {
public static VelocityEngine initVelocity() {
// 创建并配置 Velocity 引擎
Properties props = new Properties();
props.setProperty("file.resource.loader.path", "src/main/resources"); // 设置模板路径
props.setProperty("input.encoding", "UTF-8"); // 设置输入文件的编码
props.setProperty("output.encoding", "UTF-8"); // 设置输出文件的编码
VelocityEngine velocityEngine = new VelocityEngine(props);
velocityEngine.init();
return velocityEngine;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 2.4 加载和渲染模板
接下来,我们使用 VelocityEngine 加载模板并渲染输出:
import org.apache.velocity.VelocityContext;
import org.apache.velocity.Template;
import java.io.StringWriter;
public class VelocityExample {
public static void main(String[] args) {
// 初始化 Velocity 引擎
VelocityEngine velocityEngine = VelocityInitializer.initVelocity();
// 加载模板文件
Template template = velocityEngine.getTemplate("hello.vm");
// 创建上下文并添加数据
VelocityContext context = new VelocityContext();
context.put("name", "Alice");
context.put("city", "Wonderland");
// 渲染模板
StringWriter writer = new StringWriter();
template.merge(context, writer);
// 输出渲染结果
System.out.println(writer.toString());
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
输出结果:
Hello, Alice! Welcome to Wonderland.
# 3. Velocity Template Language (VTL) 语法详解
VTL 是一种轻量级的模板语言,专为 Velocity 设计。它提供了变量处理、条件语句、循环、宏等功能,使模板语言具有很强的灵活性。
# 3.1 变量处理
在 VTL 中,变量使用 $ 符号引用,例如 $name。上下文中的变量名必须与模板中的变量名一致,才能正确渲染。
##设置变量
#set($变量=值)
2
# 3.2 条件语句
Velocity 支持 #if, #elseif, #else, #end 语法,用于实现条件逻辑:
#if($age > 18)
You are an adult.
#else
You are a minor.
#end
2
3
4
5
# 3.3 循环语句
#foreach 用于遍历集合或数组:
#foreach($item in $items)
- $item
#end
2
3
假设上下文中 items 是一个包含 ["apple", "banana", "cherry"] 的列表,渲染结果将是:
- apple
- banana
- cherry
2
3
# 3.4 宏定义
/**
* #define用于定义重用模块,不可携带参数。定义后可使用 $模块名称 来引用
*/
#define($模块名称)
.....模块内容.....
#end
------------------------------------------------------------------------
/**
* #macro用于定义重用模块,可以携带参数,也可不带。定义后可以使用 #宏名称(实数) 指令进行调用
*/
#macro(宏名称 [可选参数])
.....模块内容.....
#end
2
3
4
5
6
7
8
9
10
11
12
13
宏是 VTL 中的可重用代码块,可以携带参数,可以在模板中定义并调用:
#macro(greet $name)
Hello, $name!
#end
#greet("Alice")
2
3
4
5
渲染结果:
Hello, Alice!
# 3.5 注释
- 单行注释:##this is single
- 多行注释:#* .........#
- 文档格式:#**.............#
## This is a comment
注释不会出现在输出结果中,只用于模板中的说明。
# 3.6 $include和#parse
#include和#parse的作用都是引入本地文件,为了安全,被进入的文件只能在Template_root目录下。
这两个引入区别:
1)#include可以引入多个文件。例如:#include("one.gif","two.txt","three.html")
#parse只能引入指定的单个对象。例如:#parse("layout/index.vm")
2)#include引入的文件内容不会被velocity模板引擎解析。
#parse引入的文件内容,将解析其中的velocity并交给模板,相当于把引入的文件内容copy到文件中。
3)#parse是可以递归调用的
# 4. Velocity 高级特性
# 4.1 自定义工具类
Velocity 允许你将 Java 对象作为工具类添加到上下文中,在模板中调用其方法:
public class MyTool {
public String shout(String text) {
return text.toUpperCase();
}
}
// 使用工具类
VelocityContext context = new VelocityContext();
context.put("tool", new MyTool());
2
3
4
5
6
7
8
9
在模板中:
$tool.shout("hello")
渲染结果:
HELLO
# 4.2 事件处理器
Velocity 支持事件处理器接口,用于拦截并处理特定的事件,如变量解析、错误处理等。
# 4.2.1 示例:自定义变量未找到处理器
import org.apache.velocity.app.event.ReferenceInsertionEventHandler;
public class CustomReferenceHandler implements ReferenceInsertionEventHandler {
@Override
public Object referenceInsert(String reference, Object value) {
if (value == null) {
return "[undefined]";
}
return value;
}
}
// 配置 Velocity 引擎使用自定义处理器
velocityEngine.setProperty("eventhandler.referenceinsertion.class", "com.example.CustomReferenceHandler");
2
3
4
5
6
7
8
9
10
11
12
13
14
# 4.3 多语言支持
Velocity 支持国际化,可以根据不同的语言环境生成不同语言的模板输出。你可以在上下文中引入资源文件来处理多语言文本。
import java.util.Locale;
import java.util.ResourceBundle;
VelocityContext context = new VelocityContext();
ResourceBundle bundle = ResourceBundle.getBundle("messages", Locale.FRANCE);
context.put("messages", bundle);
2
3
4
5
6
在模板中:
$messages.getString("welcome")
# 5. Velocity 常见应用场景
- 生成动态网页:Velocity 常用于 MVC 架构中的视图层,生成动态 HTML 内容。通过上下文数据与模板的结合,能动态生成用户界面。
- 邮件模板:在邮件发送系统中,Velocity 常用于定义邮件内容的模板。可以根据用户信息生成个性化的邮件。
- 生成配置文件:Velocity 也常用于生成各种格式的配置文件,如 XML、YAML 等。通过模板化的配置文件,可以减少重复工作并确保一致性。
# 6. Velocity 与其他模板引擎的比较
Velocity 和其他常见的 Java 模板引擎(如 FreeMarker、Thymeleaf)相比有以下特点:
- 简单易用:Velocity 的语法相对简单,没有过多复杂的特性,易于上手。
- 轻量级:Velocity 非常轻量,不会为项目引入过多依赖,适合小型项目或需要极简配置的场景。
- 灵活性强:Velocity 提供了丰富的 API 和事件处理机制,方便开发者根据需求进行扩展。
# 7. Velocity 的常见配置
Velocity 支持通过 Properties 文件或在 Java 代码中直接配置。以下是一些常见的配置项:
file.resource.loader.path:指定模板文件所在的目录。input.encoding和output.encoding:指定模板和输出文件的编码方式。resource.manager.logwhenfound:设置是否在找到资源时记录日志。
示例配置:
Properties props = new Properties();
props.setProperty("file.resource.loader.path", "src/main/resources/templates");
props.setProperty("input.encoding", "UTF-8");
props.setProperty("output.encoding", "UTF-8");
props.setProperty("resource.manager.logwhenfound", "false");
VelocityEngine velocityEngine = new VelocityEngine(props);
velocityEngine.init();
2
3
4
5
6
7
8
# 8. 总结
Apache Velocity 是一个灵活且功能强大的模板引擎,它通过简单的模板语言和强大的 Java 集成,帮助开发人员轻松生成动态内容。无论是用于生成网页、配置文件还是其他格式的文本内容,Velocity 都能够提供有效的解决方案。掌握 Velocity 的基本使用方法、VTL 语法以及高级特性,可以让你在项目中高效地生成动态内容。