当前位置:网站首页>模板引擎Velocity 基础
模板引擎Velocity 基础
2022-07-01 16:17:00 【一切总会归于平淡】
目录
1、velocity简介
Velocity是一个基于Java的模板引擎,可以通过特定的语法获取在java对象的数据 , 填充到模板中,从而实现界面和java代码的分离 !

那 Velocity 有什么应用场景呢?
- Web应用程序 : 作为为应用程序的视图, 展示数据。
- 源代码生成 : Velocity可用于基于模板生成Java源代码。
- 自动电子邮件 : 网站注册 , 认证等的电子邮件模板。
- 网页静态化 : 基于velocity模板 , 生成静态网页。
组成结构:
模块 | 描述 |
app | 主要封装了一些接口 , 暴露给使用者使用。主要有两个类,分别是Velocity(单例)和VelocityEngine。 |
Context | 主要封装了模板渲染需要的变量 |
Runtime | 整个Velocity的核心模块,Runtime模块会将加载的模板解析成语法树,Velocity调用mergeTemplate方法时会渲染整棵树,并输出最终的渲染结果。 |
RuntimeInstance | RuntimeInstance类为整个Velocity渲染提供了一个单例模式,拿到了这个实例就可以完成渲染过程了。 |
详细介绍大家可以看官网,传送门放这里了:The Apache Velocity Project
2、 快速入门
这里给大家简单演示如何使用Velocity定义html 模板,然后将动态数据填充到模板中,最后形成一个完整的html 页面。
首先我们创建一个项目,我就直接创建一个springBoot 项目了,大家可以根据自己的需求来。

创建好项目,我们引入velocity依赖。
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>我们在resources 目录下创建模板文件。

模板文件内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
hello , ${name} !
</body>
</html>模板创建好之后,我们到Test 类中,编写java 代码。

@Test
void contextLoads() throws IOException {
// 1、设置velocity资源加载器
Properties prop = new Properties();
prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
// 2、初始化velocity引擎
Velocity.init(prop);
// 3、创建Velocity容器
VelocityContext context = new VelocityContext();
context.put("name", "一切总会归于平淡");
// 4、加载Velocity模板
Template tpl = Velocity.getTemplate("vms/demo01.vm", "UTF-8");
// 5、合并数据到模板
FileWriter fw = new FileWriter("E:\\code\\Demo\\velocityDemo\\src\\main\\resources\\html\\demo01.html");
tpl.merge(context, fw);
// 6、释放资源
fw.close();
}
输出结果:

Velocity解决了如何在后台程序和网页之间传递数据的问题,后台代码和视图之间相互独立,一方的修改不影响另一方,他们之间是通过环境变量(Context)来实现的,网页制作一方和后台程序一方相互约定好对所传递变量的命名约定,比如上面程序例子中的 name变量,它们在网页上就是$name 。
只要双方约定好了变量名字,那么双方就可以独立工作了。无论页面如何变化,只要变量名不变,那么后台程序就无需改动,前台网页也可以任意由网页制作人员修改。这就是Velocity的工作原理。
3、基础语法
Velocity Template Language (VTL) , 是Velocity 中提供的一种模版语言 , 旨在提供最简单和最干净的方法来将动态内容合并到网页中。
简单来说VTL可以将程序中的动态数展示到网页中。
VTL的语句分为4大类:注释 , 非解析内容 , 引用和指令。
3.1 VTL注释
语法:
- 行注释: ## 行注释内容
- 块注释:#* 块注释内容1 块注释内容2 *#
- 文档注释:#** 文档注释内容1 文档注释内容2 *#
代码演示:

3.2 非解析内容
什么是非解析内容?
非解析内容就是不会被velocity 解析的内容,所写的内容都会原样输出出来。
那这到底有什么用呢?因为我们就算是直接在模板文件中书写内容,它也会原样直接显示出来呀。
大家直接往下看。
语法:#[[ 非解析内容1 非解析内容2 ]]#
代码演示 :

我们再把java代码运行一下。


3.3 引用
引用语句就是对引擎上下文对象中的属性进行操作。语法方面分为常规语法($属性)和正规语法(${属性})。
3.3.1 变量引用
语法 | 描述 |
$变量名 | 若上下文中没有对应的变量,则输出字符串"$变量名" |
${变量名} | 若上下文中没有对应的变量,则输出字符串"${变量名}" |
$!变量名 | 若上下文中没有对应的变量,则输出空字符串"" |
$!{变量名} | 若上下文中没有对应的变量,则输出空字符串"" |
代码演示:

我们运行java 代码看看执行效果:

3.3.2 属性引用
语法 | 描述 |
$变量名.属性 | 若上下文中没有对应的变量,则输出字符串"$变量名.属性" |
${变量名.属性} | 若上下文中没有对应的变量,则输出字符串"${变量名.属性}" |
$!变量名.属性 | 若上下文中没有对应的变量,则输出字符串"" |
$!{变量名.属性} | 若上下文中没有对应的变量,则输出字符串"" |
代码演示:

我们创建一个实体类。

我们修改一下测试类代码。

我们运行一下代码,看看执行效果。

3.3.3 方法引用
方法引用实际就是指方法调用操作,关注点返回值和参数 , 方法的返回值将输出到最终结果中
语法 | 描述 |
$变量名.方法([入参1[, 入参2]*]?) | 若上下文中没有对应的变量,则输出字符串"$变量名.方法([入参1[, 入参2]*]?" |
${变量名.方法([入参1[, 入参2]*]?)} | 若上下文中没有对应的变量,则输出字符串"${变量名.方法([入参1[, 入参2]*]?)}" |
$!变量名.方法([入参1[, 入参2]*]?) | 若上下文中没有对应的变量,则输出字符串"" |
$!{变量名.方法([入参1[, 入参2]*]?)} | 若上下文中没有对应的变量,则输出字符串"" |
代码演示:
我们修改一下java代码。

然后修改 模板文件。

然后我们看看执行效果。

3.4 指令
方法引用实际就是指方法调用操作,关注点返回值和参数 , 方法的返回值将输出到最终结果中
语法 | 描述 |
$变量名.方法([入参1[, 入参2]*]?) | 若上下文中没有对应的变量,则输出字符串"$变量名.方法([入参1[, 入参2]*]?" |
${变量名.方法([入参1[, 入参2]*]?)} | 若上下文中没有对应的变量,则输出字符串"${变量名.方法([入参1[, 入参2]*]?)}" |
$!变量名.方法([入参1[, 入参2]*]?) | 若上下文中没有对应的变量,则输出字符串"" |
$!{变量名.方法([入参1[, 入参2]*]?)} | 若上下文中没有对应的变量,则输出字符串"" |
代码演示:
我们修改一下java代码。

然后修改 模板文件。

然后我们看看执行效果。

3.4 指令
指令主要用于定义重用模块、引入外部资源、流程控制。指令以 # 作为起始字符。
3.4.1 流程控制
指令 | 语法 | 描述 |
#set | #set($变量 = 值) | 在页面中声明定义变量 |
#if/#elseif/#else | 下面演示 | 进行逻辑判断 |
#foreach | 下面演示 | 遍历循环数组或者集合 |
1、#set

看看执行效果:

2、#if/#elseif/#else

我们看看执行效果。

3、#foreach

我们看看生成效果。

内置属性:
$foreach.index | 获取遍历的索引 , 从0开始 |
$foreach.count | 获取遍历的次数 , 从1开始 |
3.4.2 引入资源
指令 | 描述 |
#include | 引入外部资源 , 引入的资源不会被引擎所解析 |
#parse | 引入外部资源 , 引入的资源将被引擎所解析 |
#define | 定义重用模块(不带参数) |
evaluate | 动态计算 , 动态计算可以让我们在字符串中使用变量 |
1、#include
我们新建一个模板文件。

、
然后我们在 demo01.vm 中引入。

我们来看看执行效果

我们可以看到 ${now }并未被解析,这是大家要注意的。
2、#parse

我们看看执行的效果。

我们可以看到解析了。
3、#define

效果:

4、#evaluate

效果:

3.4.3 宏指令
作用 : 定义重用模块(可带参数)
定义语法:
#macro(宏名 [$arg]?)
.....
#end调用语法:
#宏名([$arg]?)演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
#set($userList = [
{"name":"一切总会归于平淡","sex":"男","age":"22"}
])
<h1>定义宏</h1> #macro(table $list)
<table border="1px">
<tr>
<td>编号</td>
<td>用户名</td>
<td>密码</td>
<td>邮箱</td>
<td>年龄</td>
<td>操作</td>
</tr>
#foreach($item in $list)
<tr>
<td>${foreach.count}</td>
<td>${item.name}</td>
<td>${item.sex}</td>
<td>${item.age}</td>
</tr>
#end
</table>
#end
<h1>调用宏</h1>
#table($userList)
</body>
</html>效果:

边栏推荐
- [daily news]what happened to the corresponding author of latex
- 揭秘慕思“智商税”:狂砸40亿搞营销,发明专利仅7项
- vim用户自动命令示例
- 2022 Moonriver global hacker song winning project list
- 接口测试框架中的鉴权处理
- Microservice tracking SQL (support Gorm query tracking under isto control)
- 【观察】数字化时代的咨询往何处走?软通咨询的思与行
- 实现数字永生还有多久?元宇宙全息真人分身#8i
- 红队第8篇:盲猜包体对上传漏洞的艰难利用过程
- 周少剑,很少见
猜你喜欢

2023 spring recruitment Internship - personal interview process and face-to-face experience sharing

动作捕捉系统用于苹果采摘机器人

Nuxt. JS data prefetching

VMware 虚拟机启动时出现故障:VMware Workstation 与 Hyper-v 不兼容...
![[nodemon] app crashed - waiting for file changes before starting...解决方法](/img/ee/9830afd86e092851a2a906cb994949.png)
[nodemon] app crashed - waiting for file changes before starting...解决方法

Talking from mlperf: how to lead the next wave of AI accelerator

How does win11 set user permissions? Win11 method of setting user permissions

【Hot100】20. 有效的括号

毕业季 | 华为专家亲授面试秘诀:如何拿到大厂高薪offer?

process. env. NODE_ ENV
随机推荐
How to use phpipam to manage IP addresses and subnets
Huawei issued hcsp-solution-5g security talent certification to help build 5g security talent ecosystem
红队第8篇:盲猜包体对上传漏洞的艰难利用过程
复杂度相关OJ题(LeetCode、C语言、复杂度、消失的数字、旋转数组)
vscode 查找 替换 一个文件夹下所有文件的数据
Learn selenium to simulate mouse operation, and you can be lazy a little bit
普通二本,去过阿里外包,到现在年薪40W+的高级测试工程师,我的两年转行心酸经历...
Principle of motion capture system
Uncover the "intelligence tax" of mousse: spend 4billion on marketing, and only 7 invention patents
嗨 FUN 一夏,与 StarRocks 一起玩转 SQL Planner!
周少剑,很少见
IM即时通讯开发万人群聊消息投递方案
What is the digital transformation of manufacturing industry
Which MySQL functions are currently supported by tablestore in table storage?
China's intelligent transportation construction from the perspective of "one hour life circle" in Dawan District
How to use MySQL language for row and column devices?
UML旅游管理系统「建议收藏」
动作捕捉系统用于苹果采摘机器人
[JetsonNano] [教程] [入门系列] [三] 搭建TensorFlow环境
Talking from mlperf: how to lead the next wave of AI accelerator