velocity快速入门

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

velocity快速⼊门
1.velocity简介
velocity是⼀个基于Java的模板引擎,可以通过特定的语法获取在Java对象的数据,填充到模板中,从⽽实现界⾯和Java代码的分离。

这意味着可以使⽤velocity替代jsp的开发模式了,这使得前端开发⼈员可以和 Java 程序开发⼈员同步开发⼀个遵循 MVC 架构的 web 站点,在实际应⽤中,velocity还可以应⽤于很多其他的场景。

2.应⽤场景
web应⽤程序:作为应⽤程序的视图,展⽰数据。

源代码⽣成:velocity可⽤于基于模板⽣成Java源代码。

⾃动电⼦邮件:⽹站注册,认证等的电⼦邮件模板。

⽹页静态化:基于velocity模板,⽣成静态⽹页。

3.velocity组成结构
velocity主要分为app、context、runtime和⼀些辅助util⼏个部分
app模块:主要封装了⼀些接⼝,暴露给使⽤者使⽤,主要有两个类,分别是Velocity(单例)和VelocityEngine
context模块:主要封装了模板渲染需要的变量
runtime模块:整个velocity的核⼼模块,runtime模块会将加载的模块解析成语法树,velocity调⽤mergeTemplate⽅法时会渲染整棵树,并输出最终的渲染结果
runtimeInstance类为整个velocity渲染提供了⼀个单例模式,拿到了这个实例就可以完成渲染过程了
4.快速⼊门
4.1 需求分析
使⽤velocity定义HTML模板,将动态数据填充到模板中,形成⼀个完整的HTML页⾯
4.2 步骤分析
(1)创建项⽬
(2)引⼊依赖
(3)定义模板
(4)输出html
4.3 velocity⼊门程序
创建maven项⽬,然后引⼊如下依赖
<!--velocity-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
在templates⽬录下新建⼀个模板⽂件 demo1.vm,内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
hello,${name}!
</body>
</html>
编写测试类,使⽤velocity⽣成html⽂件
@Test
public void test1() throws IOException {
// 1.设置velocity的资源加载器
Properties properties=new Properties();
properties.put("file.resource.loader.class","org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
// 2.初始化velocity引擎
Velocity.init(properties);
// 3.创建velocity容器
VelocityContext context=new VelocityContext();
context.put("name","张三");
// 4.加载模板⽂件
Template template = Velocity.getTemplate("templates\\demo1.vm", "utf-8");
// 5.合并数据到模板
FileWriter fw=new FileWriter("D:\\idea_code\\cat-movie-main\\cat-movie-main\\movie-server\\src\\main\\resources\\static\\demo1.html");
template.merge(context,fw);
// 6.释放资源
fw.close();
}
执⾏单元测试,就可以看到static⽬录下⽣成了demo1.html,并且数据显⽰
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
hello,张三!
</body>
</html>
5.基础语法
5.1 VTL介绍
Velocity Template Language(VTL),是velocity中提供的⼀种模板语⾔,旨在提供最简单和最⼲净的⽅法来将动态内容合并到⽹页中,简单来说VTL可以将程序的动态数展⽰到⽹页中。

VTL语法分为四⼤类:注释、⾮解析内容、引⽤和指令
5.2 注释
注释的内容不会被输出
1.单⾏注释
## ⾏注释内容
2.多⾏注释
#*
*多⾏注释1
*多⾏注释2
*#
3.⽂档注释
#**
*⽂档注释
*
*#
5.3 ⾮解析内容
⾮解析内容会原样输出
#[[
⾮解析内容${name}
]]#
5.4 引⽤
5.4.1 变量引⼊
引⽤语法就是对引擎上下⽂对象中的属性进⾏操作,语法⽅⾯分为常规语法($属性)和正规语法(${属性})$变量名,若上下⽂中没有对应的变量,则输出字符串$变量名
${变量名},若上下⽂中没有对应的变量,则输出字符串${变量名}
$!变量名,若上下⽂中没有对应的变量,则输出空字符串""
$!{变量名},若上下⽂中没有对应的变量,则输出空字符串""
5.4.2 属性引⽤
$变量名.属性,若上下⽂中没有对应的变量,则输出字符串$变量名.属性
${变量名.属性},若上下⽂中没有对应的变量,则输出字符串${变量名.属性}
$!变量名.属性,若上下⽂中没有对应的变量,则输出空字符串""
$!{变量名.属性},若上下⽂中没有对应的变量,则输出空字符串""
5.4.3 ⽅法引⽤
$变量名.⽅法([⼊参1[,⼊参2]*]?),常规写法
${变量名.⽅法([⼊参1[,⼊参2]*]?)},正规写法
$!变量名.⽅法([⼊参1[,⼊参2]*]?),常规写法
$!{变量名.⽅法([⼊参1[,⼊参2]*]?)},正规写法
5.5 指令
#set
作⽤:在页⾯中声明变量
语法:#set($变量=值)
#set($number=10)
#set($str="hello world $number")
${str}
#if/#elseif/#else
作⽤:进⾏逻辑判断
语法:
#if(判断条件)
……
#elseif(判断条件)
……
#else
……
#end
具体实例
#set($language="java")
#if($language.equals("java"))
java开发⼯程师
#elseif($language.equals("php"))
php开发⼯程师
#else
开发⼯程师
#end
#foreach($item in items)
作⽤:遍历循环数组或者集合
#foreach($item in $items)
……
[break]
#end
$items:需要遍历的对象或者集合,如果items的类型为map集合,那么遍历的是map的value $item:变量名称,代表遍历的每⼀项
#break:退出循环
内置属性:$foreach.index:获取遍历的索引,从0开始,$foreach.count:获取遍历的次数,从1开始#foreach($item in $hobbies)
$item
#break
#end
#evaluate
作⽤:动态计算,动态计算可以让我们在字符串中使⽤变量
语法:#evaluate("计算语句")
可以将服务端的代码直接解析
#include
作⽤:引⼊外部资源,引⼊的资源不会被引擎解析
语法:#include(resources)
resources可以为单引号或者双引号的字符串,也可以为$变量,内容为外部资源路径
注意:路径如果为相对路径,则以引擎配置的⽂件加载器加载路径作为参考
#parse
作⽤:引⼊外部资源,引⼊的资源将会被引擎解析
语法:#parse(resources)
注意:路径如果为相对路径,则以引擎配置的⽂件加载器加载路径作为参考
#define
作⽤:定义重⽤模块
语法:
#define($模块名称)
模块内容
#end
使⽤的时候直接 $模块名称
宏指令
作⽤:定义重⽤模块(可带参数)
语法:
定义语法:
#macro(宏名 [$arg]?)
……
#end
调⽤语法:
#宏名([$arg]?)
实例:
#macro(table $hobbies)
#foreach($item in $hobbies)
$item
#end
#end
#table($hobbies)
6.⽣成代码
6.1 定义模板
创建controller模板 Controller.java.vm
package ${package}.controller;
import ${package}.entity.${className};
import ${package}.entity.ResultData;
import ${package}.service.${className}Service;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@RestController
@RequestMapping("/${classname}")
public class ${className}Controller {
@Resource
private ${className}Service ${classname}Service;
/**
* 查询列表
*
* @param name
* @param addr
* @return
*/
@GetMapping("/list")
public ResultData getList(String name, String addr, Integer page, Integer limit, HttpServletRequest r ) { return ${classname}Service.getList(name, addr, page, limit);
}
/**
* 根据电影名称查询影院信息
*
* @param name
* @return
*/
@GetMapping("/index")
public ResultData getIndexList(String name) {
List<${className}> list = ${classname}Service.getIndexList(name);
return new ResultData(true, "查询成功", list);
}
/**
* 修改信息
*
* @param ${classname}
* @return
*/
@PostMapping("/edit")
public ResultData updateInfo(@RequestBody ${className} ${classname}) {
int count = ${classname}Service.updateInfo(${classname});
if (count == 0) {
return new ResultData(false, "操作失败");
} else {
return new ResultData(true, "操作成功");
}
}
/**
* 添加信息
*
* @param pojo
* @return
*/
@PostMapping("/add")
public ResultData addInfo(@RequestBody ${className} ${classname}) {
int count = ${classname}Service.addInfo(${classname});
if (count == 0) {
return new ResultData(false, "操作失败");
} else {
return new ResultData(true, "操作成功");
}
}
/**
* 根据id删除信息
*
* @return
*/
@PostMapping("/del")
public ResultData deleteById(@RequestParam("ids") List<Integer> ids) {
${classname}Service.deleteById(ids);
return new ResultData(true, "操作成功");
}
}
View Code
创建service模板 Service.java.vm
package ${package}.service;
import ${package}.entity.${className};
import ${package}.entity.ResultData;
import java.util.List;
public interface ${className}Service {
ResultData getList(String name, String addr, Integer page, Integer limit);
int updateInfo(${className} ${classname});
int addInfo(${className} ${classname});
void deleteById(List<Integer> ids);
List<${className}> getIndexList(String name);
}
View Code
创建serviceImpl模板 ServiceImpl.java.vm
package ${package}.service.impl;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import ${package}.dao.${className}Dao;
import ${package}.entity.${className};
import ${package}.entity.ResultData;
import ${package}.service.${className}Service;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import javax.annotation.Resource;
import java.util.List;
@Service
public class ${className}ServiceImpl implements ${className}Service {
@Resource
private ${className}Dao ${classname}Dao;
@Override
public ResultData getList(String name, String addr, Integer page, Integer limit) {
if (page != null && limit != null) {
PageHelper.startPage(page, limit);
}
Example example = new Example(${className}.class);
Example.Criteria criteria = example.createCriteria();
if (StrUtil.isNotBlank(name)) {
criteria.andLike("name", "%" + name + "%");
}
if (StrUtil.isNotBlank(addr)) {
criteria.andLike("addr", "%" + addr + "%");
}
List<${className}> list = ${classname}Dao.selectByExample(example);
// 是否分页查询
if (page != null && limit != null) {
PageInfo<${className}> pageInfo = new PageInfo(list);
return new ResultData(true, "查询成功", pageInfo.getList(), pageInfo.getTotal()); } else {
return new ResultData(true, "查询成功", list);
}
}
public int updateInfo(${className} ${classname}) {
return ${classname}Dao.updateByPrimaryKeySelective(${classname});
}
@Override
public int addInfo(${className} ${classname}) {
return ${classname}Dao.insertSelective(${classname});
}
@Override
public void deleteById(List<Integer> ids) {
if (ids != null && ids.size() > 0) {
ids.stream().forEach(item -> ${classname}Dao.deleteByPrimaryKey(item));
}
}
@Override
public List<${className}> getIndexList(String name) {
return ${classname}Dao.getIndexList(name);
}
}
View Code
创建dao模板 Dao.java.vm
package ${package}.dao;
import ${package}.entity.${className};
import mon.Mapper;
import java.util.List;
public interface ${className}Dao extends Mapper<${className}> {
List<${className}> getIndexList(String name);
}
View Code
6.2 编写⼯具类
编写⽣成Java⽂件⼯具类
package com.zxh.movieserver.util;
import mons.io.IOUtils;
import ng3.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* @Author Eric
* @Date 5/26/2021 5:12 PM
*/
public class GenUtils {
/**
* ⽣成Java代码
* @param data ⽣成到模板中的数据
* @param templates 模板名称
* @param
*/
public static void generatorCode(Map<String,Object> data, List<String> templates, File file){
// 1.设置velocity的资源加载器
Properties properties=new Properties();
properties.put("file.resource.loader.class","org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
// 2.初始化velocity引擎
Velocity.init(properties);
// 3.创建velocity容器
VelocityContext context=new VelocityContext(data);
// 4.加载模板⽂件
//遍历模板列表,获取每⼀个模板
for (String template : templates) {
Template tpl = Velocity.getTemplate(template, "utf-8");
// StringWriter sw=new StringWriter();
//// 5.合并数据到模板
// tpl.merge(context,sw);
String fileName = genFileName(template, data.get("className").toString(), data.get("package").toString());
try {
FileWriter fileWriter=new FileWriter(file+File.separator+fileName);
tpl.merge(context,fileWriter);
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
// try {
// zip.putNextEntry(new ZipEntry(fileName));
// IOUtils.write(sw.toString(),zip,"UTF-8");
// IOUtils.closeQuietly(sw);
// zip.flush();
// zip.closeEntry();
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}
/**
* 根据模板名称,类名称,包名称拼接⼀个完整的⽂件路径和名称
* @param template 模板名称
* @param className 类名称
* @param packageName 包名称
* @return
*/
public static String genFileName(String template,String className,String packageName){
String packagePath="main"+ File.separator+"java"+File.separator;
if(StringUtils.isNotEmpty(packageName)){
packagePath+=packageName.replace(".",File.separator)+File.separator;
}
if(template.contains("Controller.java.vm")){
return packagePath+"controller"+File.separator+className+"Controller.java";
}
if(template.contains("Service.java.vm")){
return packagePath+"service"+File.separator+className+"Service.java";
}
if(template.contains("ServiceImpl.java.vm")){
return packagePath+"service"+File.separator+"impl"+File.separator+className+"ServiceImpl.java";
}
if(template.contains("Dao.java.vm")){
return packagePath+"dao"+File.separator+className+"Dao.java";
}
return null;
}
}
View Code
6.3 单元测试
运⾏测试类就可以⽣成相关代码
package com.zxh.movieserver;
import com.zxh.movieserver.util.GenUtils;
import org.junit.jupiter.api.Test;
import java.awt.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipOutputStream;
/**
* @Author Eric
* @Date 5/26/2021 5:52 PM
*/
public class Test4 {
@Test
public void test1() throws FileNotFoundException {
Map<String,Object> map=new HashMap<>();
map.put("package","com.zxh.movieserver");
map.put("className","Account");
map.put("classname","account");
//构建模板列表
List<String> list=new ArrayList<>();
list.add("templates/Controller.java.vm");
list.add("templates/Service.java.vm");
list.add("templates/ServiceImpl.java.vm");
list.add("templates/Dao.java.vm");
File file=new File("D:\\idea_code\\cat-movie-main\\cat-movie-main\\movie-server\\src\\"); // FileOutputStream fileOutputStream=new FileOutputStream(file);
// ZipOutputStream zipOutputStream=new ZipOutputStream(fileOutputStream);
GenUtils.generatorCode(map,list,file);
}
}
View Code。

相关文档
最新文档