什么是模板引擎?
“模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。”这是百度百科的介绍,简单说就做动态页面的渲染,避免了一个页面写一份代码的尴尬场面。
听起来和后端开发关系不大,但是其实在某些场景,我们可以用模板引擎来生成java代码、sql脚本等,做一些省时省力的事情。
常用的模板引擎有jsp、freemarker、velocity、themleaf等等。
Velocity是一个基于Java的Web页面模版引擎,够帮我们实现页面静态化,同时它将Java代码与网页分开,并为Java Server Pages(JSP)提供了可行的替代方案。
我为什么用velocity?
使用模板引擎是因为在实际开发中遇到了这样的场景,当时客户方有几十个接口文档需要转成特定的Java类,而各个接口的业务字段又有几十几百个,为了节省开发时间,决定使用模板引擎来生成代码。
当然我选择velocity不单纯是看中velocity的优点,主要还是苍穹有velocity依赖,而客户环境没有接入公网,
不方便引入其他的模板引擎。
velocity如何使用?
velocity通过预先定义好的模板文件(vm)来生成我们需要的代码,所以只需定义好模板文件,即可在Java中使用。
模板语法
基本符号
1、“#”
使用“#”用来标识Velocity的脚本语句,比如:#set、#if 、#else、#end、#foreach...
2、$
Velocity变量使用$,比如:$cosmic。
3、!
变量名称前加上!,比如:$!cosmic,如果cosmic有值,将显示cosmic的值,如果不存在就会显示为空白,一般会推荐使用。
声明变量
#set(${cosmic}=”kingdee”)
条件和逻辑
#if($age > 10 && $age <20)
...
#elseif($age > 30 || $age <10)
...
#else
...
#end
循环
#foreach($column in $columnList)
${column.name}
#end
#parse 与 #include
#parse 会将引用的内容当成类似于源码文件,会将内容在引入的地方进行解析;
#include 是将引入文件当成资源文件,会将引入内容原封不动地以文本输出。
#macro
用于定义一个VTL模板的重复代码块脚本函数(宏),不推荐在界面模板中大量使用。
定义:
#macro(宏的名称 $参数1 $参数2 .....)
语句体(即函数体)
#end
调用
#宏的名称 ($参数1 $参数2 .....)
定义举例:
#macro(myFunc $type)
#if ($name.equals($type))
dosomething...
#end
#end
调用举例:
#myFunc("kingdee")
模板使用
maven
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
gradle
implementation group: 'org.apache.velocity', name: 'velocity', version: '1.7'
模板文件
在resource下新增xxx.vm文件,以下是生成自定义java类的模板参考:
package xxx.model.tx.${packageName}; #if($isInnerModel == false) import xxx.model.tx.Tx$(packageName}Base; #end import javax.xml.bind.annotation.*; /** * 类注释 */ public class Tx${className) #if($isInnerModel == false) extends Tx${packageName}Base #end{ #if($packageName== "request") /** * 构造函数注释 */ public Tx${className)() { this.sysTxCode = "${sysTxCode}"; this.sysTxVersion = "${sysTxVersion)"; } #end ...... }
Java代码
/** * Velocity使用示例 * @param args */ public static void main(String[] args) { // 准备替换的参数 Map paramMap = new HashMap(); paramMap.put("packageName", "mytest"); paramMap.put("isInnerModel", true); paramMap.put("className", "TestCls"); paramMap.put("sysTxCode", "cosmic"); paramMap.put("sysTxVersion", "5.0"); // 指定加载classpath目录下的vm文件, file.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader Properties properties = new Properties(); properties.setProperty("file.resource.loader.class",ClasspathResourceLoader.class.getName()); // 初始化Velocity,指定配置 Velocity.init (properties); // 定义字符集 Velocity.setProperty("input.encoding", "UTF-8"); velocity.setProperty("output.encoding","UTF-8"); // 实例化上下文 VelocityContext context = new VelocityContext(paramMap); // 文件输出目录 String filePath=”D:\cosmic\bos-dev-tool\debug-service\node-debug-mservice\src\main\java\kd\bos\debug\mservice\XXX.java” // 输出到指定文件 try (FileWriter writer = new FileWriter(filePath)) { Template tpl = Velocity. getTemplate("xxx.vm", "UTF-8"); tpl.merge(context, writer); writer.flush(); } catch (Exception e) { // log // dosomethig } }
推荐阅读