Jacky's blog
首页
  • Android
  • Web
  • Server
  • Python
  • iOS
  • Java
  • Vue
  • 计算机基础
  • AI
  • 全部工具
  • CLI 工具
  • 编辑器
  • 开发工具
  • 构建工具
  • 版本控制
  • 调试工具
  • 网络工具
  • 个人成长
  • 博客
  • 分类
  • 标签
  • 归档
收藏
GitHub (opens new window)

Jack Yang

编程; 随笔
首页
  • Android
  • Web
  • Server
  • Python
  • iOS
  • Java
  • Vue
  • 计算机基础
  • AI
  • 全部工具
  • CLI 工具
  • 编辑器
  • 开发工具
  • 构建工具
  • 版本控制
  • 调试工具
  • 网络工具
  • 个人成长
  • 博客
  • 分类
  • 标签
  • 归档
收藏
GitHub (opens new window)
  • java base
  • 模板引擎

    • Velocity 模板引擎入门
      • Velocity 是什么
      • 从数据到输出
      • VTL 语法速查
      • 阅读模板时的排查顺序
      • 官方文档入口
  • Java 面试高频问题指南
  • 其他

  • throwable
  • thread
  • weakreference
  • UnSafe
  • collections
  • Class
  • classloader
  • java
  • template_engines
Jacky
2026-10-21
目录

Velocity 模板引擎入门

# Velocity 是什么

Apache Velocity 是基于 Java 的模板引擎,使用的模板语言叫 VTL(Velocity Template Language),模板文件常用 .vm 后缀。它将数据填入模板,生成文本;输出可以是 HTML、邮件、配置文件或源代码,不限定为网页。概念与基础语法见 官方用户指南 (opens new window)。

普通字符串替换主要负责填占位符;Velocity 还支持条件、循环和宏,适合根据数据生成重复结构。例如,按字段列表生成 Java 属性,或者按收件人的信息生成不同邮件内容。

# 从数据到输出

渲染流程中有三个角色:

角色 职责
Java 程序 查询、计算并准备数据
Context(上下文) 保存模板可访问的变量和对象
VTL 模板 描述文本结构,通过引用和指令生成内容

下面用 JSON 表示待传入的数据结构,仅用于说明;实际 Java 集成需要把值放进 Context,Velocity 不会自动把一段 JSON 文本变成模板变量。

{
  "name": "Alice",
  "skills": ["Java", "Python"]
}
1
2
3
4

模板 greeting.vm:

你好,${name}!
你的技能:
#foreach($skill in $skills)
- $skill
#end
1
2
3
4
5

核心输出如下,空白行处理可能受渲染配置影响:

你好,Alice!
你的技能:
- Java
- Python
1
2
3
4

Java 中的最小渲染示例

项目需已有 org.apache.velocity:velocity-engine-core 依赖,版本按项目选定。下面直接渲染字符串,便于观察 Context 与模板的关系,不涉及文件资源加载器配置:

import java.io.StringWriter;
import java.util.Arrays;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;

public class VelocityExample {
    public static void main(String[] args) {
        VelocityEngine engine = new VelocityEngine();
        engine.init();

        VelocityContext context = new VelocityContext();
        context.put("name", "Alice");
        context.put("skills", Arrays.asList("Java", "Python"));

        String template = "你好,${name}!\n你的技能:\n"
                + "#foreach($skill in $skills)- $skill\n#end";
        StringWriter output = new StringWriter();
        engine.evaluate(context, output, "greeting", template);
        System.out.print(output.toString());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

evaluate 处理传入的模板字符串;使用独立 .vm 文件时,可配置资源加载器,通过 getTemplate 读取,再调用 template.merge(context, writer)。Context 和集成方式参见 官方开发指南 (opens new window)。

# VTL 语法速查

功能 示例 说明
变量引用 $name、${name} 花括号明确变量边界
属性访问 $user.name 可映射到 Java Bean getter 或 Map 取值等查找规则
方法调用 $user.getName() 调用上下文中对象可访问的方法
赋值 #set($count = 3) 在模板中设置变量
条件分支 #if($enabled)启用#else关闭#end 按条件选择输出
遍历 #foreach($item in $items)$item#end 为集合元素生成重复内容
单行注释 ## 这里是注释 不输出到结果
多行注释 #* 多行注释 *# 注释可以跨行
静默引用 $!optionalValue 在通常的非严格配置下,未定义或空引用不显示原引用文本
原样包含文件 #include("footer.txt") 读取文件内容,不执行其中的 VTL
渲染子模板 #parse("footer.vm") 解析并渲染另一个模板
定义宏 #macro(greet $who)你好,$who!#end 定义可复用模板片段,用 #greet("Alice") 调用

语法定义见 官方 VTL Reference (opens new window)。静默引用不等于解决数据缺失;严格模式下的行为应结合项目配置检查。

条件和循环放在哪里

模板适合决定“是否显示某段文本”“重复输出哪些条目”。数据查询、权限判断和复杂业务计算应先在 Java 侧完成,再把结果交给模板,避免渲染过程承担业务流程。

# 阅读模板时的排查顺序

现象 优先检查
输出里出现 $name 原文 Context 是否传入该变量、名字及大小写是否一致;是否启用了严格模式
$user.name 没有得到预期值 对象类型、getter/Map 键及属性查找规则
循环没有输出 集合是否存在、是否为空;是否进入了外层条件
子模板中的指令原样显示 是否误用了 #include,需要渲染时应检查 #parse
生成文件的空白与预期不同 模板自身空格、换行及引擎的空白处理配置

模板运行在宿主引擎中;其他产品即使使用 VTL,也可能只提供部分语法或额外变量。排查时同时核对宿主提供的 Context 和实际引擎版本,不只看 .vm 扩展名。

# 官方文档入口

本文示例参考 Velocity Engine 2.3 文档;接入已有项目时优先阅读相同版本的资料。

目标 官方入口
从概念和例子入门 User Guide (opens new window)
快速查指令与引用语法 VTL Reference (opens new window)
Java 集成、Context、资源加载与空白处理 Developer Guide (opens new window)
查看引擎项目和其他版本入口 Apache Velocity Engine (opens new window)
#Java#guide
上次更新: 2026/10/21, 21:57:28
java base
Java 面试高频问题指南

← java base Java 面试高频问题指南→

最近更新
01
macOS log 日志查询与系统故障排查指南
10-20
02
Codex 使用与会话管理指南
10-17
03
Tailscale 入门:让自己的设备跨网络互联
10-15
更多文章>
Theme by Vdoing | Copyright © 2019-2026 Jacky | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式