Velocity模板引擎的使用
相信在日常开发中或多或少都听过或者使用过模板引擎
,比如熟知的freemarker
, thymeleaf
等。而模板引擎就是为了实现View和Data分离而产生的。
今天我们就来看下几种常见的模板引擎,其中以Velocity
进行demo演示。
1. 常见的模板引擎
是一款用于渲染XML/XHTML/HTML5内容的模板引擎。它也可以 轻易的与Spring MVC等Web框架进行集成作为Web应用的模板引擎。也是springboot推荐的静态资源渲染的引擎。
功能与Velocity差不多,但是语法更加强大,使用方便。是非常主流的模板引擎。
Enjoy Template Engine 采用独创的 DKFF (Dynamic Key Feature Forward)词法分析算法以及独创的DLRD (Double Layer Recursive Descent)语法分析算法,极大减少了代码量,降低了学习成本,并提升了用户体验
不仅可以用于界面展示(HTML, XML等)还可以生成输入java代码,SQL语句等文本格式。我们公司就是使用Velocity来做代码的自动生成工具。
本文主要是以Velocity进行介绍。
2. Velocity 的语法
关键字以 # 开头,变量以 $ 开头
2.1 定义变量
使用 #set 关键字
#set($name = "zhangsan")
#set(${h} = "hello $name") ##这里的name变量加不加 {} 都可以
#set($n = "${name}_new") ##这里的name变量就必须要加上{}了
#set($m = $n) ##重新赋值,如果有其他操作,需要向上面一样加上 ""
#set($p = {}) ##定义对象,Java中的Map
#set($a = []) ##定义数组,Java中的List
#set($v = $person.age) ##属性引用。 person是一个Java对象。
#set($v = $person.getName()) ##方法引用。
#set($v = $person.getName($type)) ##方法引用(带参数)。
2.2 变量的使用
以 $ 者 ${} 使用变量
#set($name = "zhangsan") ##定义变量
$name ##使用变量
${name} ##使用变量
${name}_abc ##必须加 {}
abc_$name ##可以不用加 {}
by the way:
${} 输出表达式的计算结果,并进行过滤,比如:过滤变量中的HTML标签。
$!{} 原样输出表达式的计算结果,不进行任何过滤,通常用于输出HTML片段
2.3 循环
使用 #foreach .... #end 使用循环
#set($list = ["北京", "上海", "深圳", "杭州"]) ##定义一个集合
#foreach($item in $list)
热门城市 ---> $item, 排名:[$foreach.count] #$foreach.index 是从0开始
#end
2.4 if判断
使用 #if(condition) ... #elseif(condition) ... #else ... #end 进行条件判断
#set($value = 1) ##定义一个变量
#if($value == 0)
value的结果是: $!value
#elseif($value == 1)
value的结果是: $!value
#else
value的结果大于1
#end
常用判断条件:
//对象obj不为空才会执行里面的逻辑
#if($obj) ..... #end
//对象obj为空才会执行里面的逻辑
#if(!$obj) ..... #end
#等于字符串"abc" 才会执行里面的逻辑
if($obj == 'abc') ...... #end
2.5 关系操作符
可以使用 &&(与), ||(或), !(非) 来进行复杂的条件判断
#set($name = "")
#if(!$name) ##用于判空,如果是空,则为false, 取反后为true
$!name 的年龄是: 13
#end
#set($key = "velocity")
#set($flag = true)
#set($list = ["北京", "上海"])
#if($key && $key.contains("v") && $flag && $list.size() > 1) ## key 不为空并且包含v, flag 为true, list 元素数量大于1
条件成立......
#end
3.Velocity的使用
3.1 导入依赖
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
3.2 定义模板
文件名以 .vm 结尾 (例如:hello.vm)
#if($c == 15)
-----> hello: $!name
#end
#foreach($item in $list)
集合中的元素:${item} , 索引:【$foreach.index】
#end
$person.name 的 生日是 $person.birthday,年龄是 $person.getAge()
3.3 定义引擎并解析模板
public class VelocityTest {
public static void main(String[] args) throws IOException {
//1.定义一个模板引擎
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
//2.指定一个模板
Template t = ve.getTemplate("hello.vm");
VelocityContext ctx = new VelocityContext();
//设置字符串
ctx.put("c", 15);
ctx.put("name", "velocity");
//设置集合
List<String> temp = new ArrayList<>();
temp.add("北京");
temp.add("杭州");
temp.add("海南");
ctx.put( "list", temp);
//设置对象
ctx.put("person", new Person("秋官", 30, LocalDate.now()));
//合并到模板中, 可以是文件中
//FileWriter fw = new FileWriter("demo.html");
//t.merge(ctx, fw);
//fw.close();
StringWriter sw = new StringWriter();
t.merge(ctx, sw);
System.out.println(sw);
}
@AllArgsConstructor
@Data
public static class Person {
private String name;
private int age;
private LocalDate birthday;
}
}
运行结果:
除此以外,Velocity还提供了 Velocity-Tools工具包,他是Veloctiy下的一个子模块,参考gitee,Veloctiy-Tools主要包含2个部分:GenericTools
和VelocityView
,前者提供了一些常用的工具类,比如DateTool, MathTool等等,后者主要是应用于web环境。
像我们公司,使用velocity就是用来生成代码,所以导入 velocity-engine-core
就足够了,也没有导入springboot集成的velocity starter。
简单看下 GenericTools
工具的使用吧。
4. Velocity Generic Tools工具的使用
4.1 导入依赖
<dependency>
<groupId>org.apache.velocity.tools</groupId>
<artifactId>velocity-tools-generic</artifactId>
<version>3.1</version>
</dependency>
4.2 配置tools配置文件
<?xml version="1.0" encoding="UTF-8"?>
<tools>
<toolbox scope="application">
<!-- 分别导入时间,集合,数学工具包,可以点进去看下这些类有哪些方法,属性,根据类别名就可以调用了 -->
<tool class="org.apache.velocity.tools.generic.DateTool"/>
<tool class="org.apache.velocity.tools.generic.MathTool"/>
</toolbox>
<toolbox scope="application">
<!--如果不配置stringsDelimiter, 那么默认也是按照逗号分割 -->
<tool class="org.apache.velocity.tools.generic.CollectionTool" stringsDelimiter=","/>
</toolbox>
</tools>
4.3 定义模板
======================日期Tool===================
$date
$date.getDate()
$date.long
$date.getSystemTime()
$date.format("yyyy-MM-dd")
======================数学Tool===================
$math.max($a, $b)
$math.div($a, $b)
$math.add($a, $b)
$math.floor($math.div($a, $b))
=====================集合Tool===================
原始元素排序:
#foreach($item in $persons)
----> $item
#end
Collection tool 排序后:
#set($ps = $collection.sort($persons))
#foreach($it in $ps)
----> $it
#end
按照年龄升序排序后:
#set($users = $collection.sort($persons, "age:asc"))
#foreach($u in $users)
----> $u
#end
按照年龄升序,count降序排序后:
#set($users = $collection.sort($persons, ["age:asc", "count:desc"]))
#foreach($u in $users)
----> $u
#end
字符串分割:
#set($str = "hello veloctiy, good good study, day day up!")
#foreach($x in $collection.split($str))
----> $x
#end
4.4 定义引擎并解析模板
/**
* @author qiuguan
* @date 2023/06/20 23:49:14 星期二
*/
public class VelocityGenericToolsTest {
public static void main(String[] args) throws Exception {
//1.定义一个模板引擎
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
//2.配置tools
ToolManager toolManager = new ToolManager();
toolManager.configure("configtools.xml");
//3.指定一个模板
Template t = ve.getTemplate("hello2.vm");
//4.用toolManager创建上下文
ToolContext ctx = toolManager.createContext();
//5.设置对象集合
List<Person> personList = new ArrayList<>();
personList.add(new Person("秋官", 30, 3));
personList.add(new Person("李白", 45, 300));
personList.add(new Person("王维", 26, 120));
ctx.put("persons", personList);
//合并到模板中, 可以是文件中
// FileWriter fw = new FileWriter("demo.html");
// t.merge(ctx, fw);
// fw.close();
StringWriter sw = new StringWriter();
t.merge(ctx, sw);
System.out.println(sw);
}
@AllArgsConstructor
@Data
public static class Person {
private String name;
private int age;
private int count;
}
}
BTW: 由于现在开发基本上都是基于springboot的,所以如果想使用velocity的view功能,可以导入 spring-boot-starter-velocity 启动器,不过现在官方已经不维护了,最近一次发布的版本还是2017年,因为官方推荐使用thymeleaf(freemarker)。如果只是测试玩玩还是可以的,也比较简单,我这里就不演示了。
好了,关于Velocity模板引擎就记录到这里吧,后续有新的内容在补充,欢迎大家指正。
转载自:https://juejin.cn/post/7246777406386929721