Velocity是一个基于java的模板引擎,它允许任何人仅仅使用简单的模板语言来引用由java代码定义的对象。
Velocity模板引擎, 作为一款成熟的基于java的模板引擎,能够帮我们实现页面静态化,同时它将Java代码与网页分开,将模板和填入数据整合,生成我们需要的页面.
Velocity模板中的关键字, 都是以#开头表示的
Velocity模板中的变量, 都是以$开头表示的
如: $user用户 $password 用户密码
{}变量
对于明确的Velocity变量, 可以使用{}包括起来, 可以在页面上展示如下效果:
u s e r N a m e , 此 时 页 面 上 可 以 表 示 为 {user}Name, 此时页面上可以表示为 userName,此时页面上可以表示为someoneName的效果.
!变量
如上述内容,Velocity模板中如果变量不存在, 在页面会显示 u s e r , 这 种 形 式 影 响 展 示 的 效 果 . 可 以 使 用 user, 这种形式影响展示的效果. 可以使用 user,这种形式影响展示的效果.可以使用!user表示.
$!user表示, 存在则展示,不存在则为空白
## 定义一个user变量为李白, password变量为123456
#set{$user = "李白"}
#set{$password = "123456"}
## 变量引用
#set{$student.name = "李白"}
## 数字
#set{$student.age = 22}
## 字符串
#set{$student.class = "大班"}
## 属性引用
#set($student.address = $address.info)
Velocity模板中转义字符是 \
#set{$user = "李白"}
## 输入 结果
$user 李白
\$user $user
\\$user \李白
\\\$user \$user
&& 且
|| 或
! 取反
Velocity模板中list集合循环语法
循环遍历,可以得到每个元素,每个元素的序号,以及总的集合长度
#foreach ( $element in $list)
## 集合中每个元素
$element
## 集合的序号 从1开始
${velocityCount}
## 集合的长度
${list.size()}
#end
map集合循环语法
#foreach ($entry in $map.entrySet())
## map的key map的value值
$entry.key => $entry.value
#end
Velocity模板中条件语法if-ifelse-else结构
#if (condition1)
// 执行业务
#elseif (condition2)
// 执行业务
#else
// 执行业务
#end
常用的条件语句是if-else结构
#if (condition1)
// 执行业务
#else
// 执行业务
#end
#break
表示跳出循环
#if (condition1)
## 条件符合跳过
#if($user == "李白")
#break;
#end
#else
// 执行业务
#end
#stop
表示终止指令,终止模板解析
#if (condition1)
## 条件符合直接终止
#if($user == "李白")
#stop
#end
#else
// 执行业务
#end
单行注释 ##
## 定义一个user变量为李白
#set{$user = "李白"}
多行注释 #* *#
#*
定义一个user变量
将user变量赋值为 李白
*#
#set{$user = "李白"}
文档注释 #** *#
#**
@version 1.1
@author 李白
*#
#set{$user = "李白"}
#include
表示引入外部资源,引入的资源不被引擎所解析
#include( "one.gif","two.txt","three.htm" )
#parse
用于导入脚本, 引入的资源会被引擎所解析
## a.vm文件
#set($user = "李白")
## b.vm文件
#parse("a.vm")
## 变量 值
$user 李白
Velocity常用的案例和工具类
public class VelocityUtils {
public static void main(String[] args) {
// 模板路径
String templatePath = "D:\\work";
// 模板名称
String templateName = "index.html.vm";
// 生成文件路径
String outFilePath = "D:\\index.html";
// 模板中所需参数
Map<String, Object> params = new HashMap<>();
params.put("name", "world");
List<String> list = new ArrayList<>();
list.add("李白");
list.add("杜甫");
list.add("陆游");
params.put("list", list);
getFile(templatePath,templateName,outFilePath,params);
}
/**
* 读取本地模板,生成文件
* @param templatePath 模板路径
* @param templateName 模板名称
* @param outFilePath 生成文件路径
* @param params 模板中填充参数
*/
public static void getFile(String templatePath, String templateName, String outFilePath,
Map<String, Object> params) {
try {
// 创建属性
loadTemplateFileByTwo(templatePath);
// 封装填充参数
VelocityContext context = new VelocityContext(params);
// 获取模板
Template tpl = Velocity.getTemplate(templateName, "UTF-8");
// 创建输出流
Writer writer = new PrintWriter(new FileOutputStream(new File(outFilePath)));
// 模板与数据填充
tpl.merge(context, writer);
// 刷新数据
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 送请求, 将生成的模板文件使用zip压缩包返回
* @param response 响应对象
* @param params 模板封装参数
* @throws IOException
*/
public static void createFile(HttpServletResponse response, Map<String, Object> params)
throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
ZipOutputStream outZip = new ZipOutputStream(output);
// 设置velocity资源加载器
loadTemplateFileByOne();
// 封装模板数据
VelocityContext context = new VelocityContext(params);
//获取模板列表
List<String> templates = getTemplates();
for (String template : templates) {
// 渲染模板
StringWriter sw = new StringWriter();
Template tpl = Velocity.getTemplate(template, "UTF-8");
tpl.merge(context, sw);
// 添加数据
outZip.putNextEntry(new ZipEntry(getFileName(template)));
IOUtils.write(sw.toString(), outZip, "UTF-8");
IOUtils.closeQuietly(sw);
}
IOUtils.closeQuietly(outZip);
byte[] data = output.toByteArray();
// 生成zip压缩包响应
response.setHeader("Content-Disposition", "attachment; filename=\"template-file.zip\"");
response.addHeader("Content-Length", String.valueOf(data.length));
response.setContentType("application/octet-stream; charset=UTF-8");
IOUtils.write(data, response.getOutputStream());
}
/**
* 获取文件名
*/
/**
* @param template 模板名 如index.html.vm
*/
private static String getFileName(String template) {
return template.replace(".vm", "");
}
/**
* 获取模板
*/
private static List<String> getTemplates() {
List<String> templates = Lists.newArrayList();
// 后端相关模板
templates.add("index.html.vm");
return templates;
}
/**
* 加载配置文件方法一 加载classpath目录下的vm文件
*/
public static void loadTemplateFileByOne() {
Properties p = new Properties();
p.put("file.resource.loader.class",
"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
Velocity.init(p);
}
/**
* 加载配置文件方法二 加载绝对路径目录下的加载vm文件
*
* @param templatePath 模板路径
*/
public static void loadTemplateFileByTwo(String templatePath) {
Properties p = new Properties();
// 设置模板加载路径 为D盘 work文件夹
p.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, templatePath);
Velocity.init(p);
}
/**
* 加载配置文件方法三 使用配置文件
*
* @param propertiesPath ,如:/velocity.properties
*/
public static void loadTemplateFileByThree(String propertiesPath) throws IOException {
Properties p = new Properties();
p.load(VelocityUtils.class.getClass().getResourceAsStream(propertiesPath));
Velocity.init(p);
}
}
其中index.html.vm模板文件在D:盘work文件夹中
<table cellspacing="0" cellpadding="5" width="20%" >
<tr>
<td bgcolor="#eeeeee" align="center">
Names:${name}
td>
tr>
#foreach($name in $list)
<tr>
<td>
第${velocityCount}个, 名字为 $name , 总共 ${list.size()} 个
td>
tr>
#end
table>
生成的index.html文件
<table cellspacing="0" cellpadding="5" width="20%" >
<tr>
<td bgcolor="#eeeeee" align="center">
Names:world
td>
tr>
<tr>
<td>
第1个, 名字为 李白 , 总共 3 个
td>
tr>
<tr>
<td>
第2个, 名字为 杜甫 , 总共 3 个
td>
tr>
<tr>
<td>
第3个, 名字为 陆游 , 总共 3 个
td>
tr>
table>
从上面测试的案例,可知,name参数有了, list集合参数有. 对于一些日常常规的循环条件判断等, Velocity模板引擎非常好用.
参考资料:
http://www.51gjie.com/javaweb/896.html
https://yanglinwei.blog.csdn.net/article/details/119185550