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> <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> <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

View Code

创建service模板 Service.java.vm

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);         }     }     @Override     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);     } }

复制代码

创建dao模板 Dao.java.vm

View Code

6.2 编写工具类

编写生成Java文件工具类

复制代码

package com.zxh.movieserver.util; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.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;     } }

复制代码

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);     } }

复制代码

 

转自:https://www.cnblogs.com/fqh2020/p/14812817.html