Velocity-快速入门
一 介绍
Apache Velocity 是一个基于 Java 的模板引擎,它允许任何人使用简单而强大的模板语言来引用对象数据,并生成基于文本的输出。Velocity 最初是作为 WebMacro 项目的一部分开发的,后来成为一个独立的开源项目,并最终加入了 Apache 软件基金会。
1 主要特点
- 简单易用:Velocity 拥有简单的语法,易于学习和使用,适合快速开发。
- 灵活性高:它可以用于多种场景,如生成 HTML 页面、电子邮件、源代码、配置文件等。
- 性能良好:Velocity 在处理大量数据和高并发请求时表现优秀。
- 强大的模板语言:支持条件判断、循环、宏定义等功能,能够满足复杂的业务逻辑需求。
- 丰富的工具集:提供了一系列的工具类,帮助开发者更高效地利用 Velocity 进行开发。
2 应用场景
- Web 开发:与 Servlet 结合,可以用来动态生成 HTML 页面。
- 邮件通知:根据用户信息定制个性化的邮件内容。
- 代码生成:可以用于自动生成代码,比如从数据库表结构生成 DAO 层代码。
- 报告生成:根据数据生成各种格式的报告文档。
- 配置文件生成:可以根据不同的环境或参数生成相应的配置文件。
3 社区和支持
作为一个成熟的开源项目,Velocity 拥有一个活跃的社区,提供了大量的文档、教程和示例。如果你遇到任何问题,可以通过官方文档、论坛或者 Stack Overflow 等平台寻求帮助。
二 SpringBoot快速入门
1 创建入门案例Demo
2 引入依赖
<!-- velocity代码生成使用模板 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
3 引入工具类
这个是velocity工厂初始化工具,我直接抽成一个类使用
package com.demo.velocitydemo.utils;import java.util.Properties;
import org.apache.velocity.app.Velocity;/*** VelocityEngine工厂* * @author ruoyi*/
public class VelocityInitializer
{/*** 初始化vm方法*/public static void initVelocity(){Properties p = new Properties();try{// 加载classpath目录下的vm文件p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");// 定义字符集p.setProperty(Velocity.INPUT_ENCODING, "UTF-8");// 初始化Velocity引擎,指定配置PropertiesVelocity.init(p);}catch (Exception e){throw new RuntimeException(e);}}
}
4 创建模板
在src/test/resources
下创建vm目录用来存放模板
创建一个简单模板(后缀名是.vm):text.html.vm
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>test</title>
</head>
<body>
<h1>${message} #*设置填充的字段*#
</h1>
</body>
</html>
5 创建测试类
package com.demo.velocitydemo;import com.demo.velocitydemo.utils.VelocityInitializer;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import java.io.FileWriter;
import java.io.IOException;@SpringBootTest
class VelocityDemoApplicationTests {@Testvoid contextLoads() throws Exception {//1 初始化模板引擎VelocityInitializer.initVelocity();//2 准备数据模型VelocityContext velocityContext=new VelocityContext();velocityContext.put("message","holle world");//设置填充的字段内容//3 读取模板Template template = Velocity.getTemplate("vm/text.html.vm", "UTF-8");//模板的位置,设置编码UTF-8//4 渲染模板 (合并输出)//设置输出流,配置输出文件的位置FileWriter fileWriter = new FileWriter("E:\\Programming files\\java\\Project_files\\Velocity-Demo\\Velocity-Demo\\text1.html");template.merge(velocityContext,fileWriter);fileWriter.close();//关闭输出流}}
一定要关闭输出流,不然页面无法显示
6 查看结果
找到text.html.vm
输出位置,发现${message}
被填充成holle world
了
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>test</title>
</head>
<body>
<h1>holle world
</h1>
</body>
</html>
浏览器打开,渲染成功
三 基本语法
1 变量
-
在模板中定义变量,
#set
开头,比如#set($name="velocity")
-
获取变量的值
$name
或者${name}
-
Velocity 支持字符串、数字和布尔值字面量。
String: "Hello" Number: 123 Boolean: $true
$name
或者${name}
举例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>test</title>
</head>
<body>
## 定义变量
#set($name="Holle")## 使用变量
${name} <br>
$name <br></body>
</html>
效果:
Holle
Holle
注意:$name
不能用于字符串拼接例如:
<body>
${name} World <br>
$nameWorld
</body>
效果:
Holle World
$nameWorld
如果变量是java对象:
User:
package com.demo.velocitydemo.pojos;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private String name;private String sex;private int age;
}
测试类:
@Testvoid contextLoads2() throws Exception {//1 初始化模板引擎VelocityInitializer.initVelocity();//2 准备数据模型VelocityContext velocityContext=new VelocityContext();//实体化对象UserUser user = new User("小明", "男", 18);//主要:第一个变量“User”要和vm模板的变量名对应。velocityContext.put("User",user);//3 读取模板Template template = Velocity.getTemplate("vm/text.html.vm", "UTF-8");//4 渲染模板 (合并输出)FileWriter fileWriter = new FileWriter("E:\\Programming_files\\Java\\Project_file\\Velocity-Demo\\text1.html");template.merge(velocityContext,fileWriter);fileWriter.close();//关闭输出流}
模板:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>test</title>
</head>
<body>
## 获取Uesr对象
$User
## 变量明.属性名
姓名:$User.name <br>
性别:$User.sex <br>
年龄:$User.age <br>
</body>
</html>
渲染效果:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>test</title>
</head>
<body>
User(name=小明, sex=男, age=18) <br>
姓名:小明 <br>
性别:男 <br>
年龄:18 <br>
</body>
</html>
2 循环
- 循环语法:
#foreach(....) #end
模板:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>test</title>
</head>
<body>
## 定义集合
#set($list=["小猫","小狗","小牛","小鱼","小猪"])#foreach($item in $list)## $foreach.count 遍历的索引,从1开始,如果想从0开始 $foreach.index 。$item是集合中的元素$foreach.count. $item <br>
#end</body>
</html>
渲染效果:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>test</title>
</head>
<body>1. 小猫 <br>2. 小狗 <br>3. 小牛 <br>4. 小鱼 <br>5. 小猪 <br>
</body>
</html>
变量对象
测试方法:
@Testvoid contextLoads3() throws Exception {//1 初始化模板引擎VelocityInitializer.initVelocity();//2 准备数据模型VelocityContext velocityContext=new VelocityContext();User user1 = new User("小明", "男", 18);User user2 = new User("小明", "男", 18);User user3= new User("小明", "男", 18);List<User> users = List.of(user1, user2, user3);velocityContext.put("Users",users);//3 读取模板Template template = Velocity.getTemplate("vm/text.html.vm", "UTF-8");//4 渲染模板 (合并输出)FileWriter fileWriter = new FileWriter("E:\\Programming_files\\Java\\Project_file\\Velocity-Demo\\text1.html");template.merge(velocityContext,fileWriter);fileWriter.close();//关闭输出流}
模板:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>test</title>
</head>
<body>#foreach($item in $Users)$item.name $item.sex $item.age <br>
#end</body>
</html>
渲染效果:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>test</title>
</head>
<body>小明 男 18 <br>小明 男 18 <br>小明 男 18 <br>
</body>
</html>
3 条件判断
- 判断语法:
#if(条件)...#elseif(条件)...#else...#end
模板:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>test</title>
</head>
<body>## 设置变量#set($age=19)#if($age>=18)成年#elseif($age<18)未成年#else未知#end
</body>
</html>
渲染效果:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>test</title>
</head>
<body>成年
</body>
</html>
如果要判断对象是否为空
不为空执行操作
#if($obj).....#end
为空执行操作
#if(!$obj).....#end
也支持||
和 &&
逻辑判断
5 注释
- 单行注释使用
##
,多行注释使用#* *#
## This is a single-line comment#*
This is a
multi-line comment
*#
注释不会被渲染
6 宏定义
- 宏(macro)可以定义可重用的代码块。
相当于函数
#macro( greeting $name )Hello, $name!
#end#set( $name = "Alice" )
#set( $name2 = "Bob" )#greeting( $name )
#greeting( $name2 )
7 字典(Map)
- 可以创建和操作字典(Map)。
#set( $map = {"name": "Alice", "age": 30} )
Name: $map.name
Age: $map["age"]