二八佳人体似酥,腰间仗剑斩愚夫。虽然不见人头落,暗里教君骨髓枯。
一. FreeMarker 的介绍
FreeMarker 的官方网址: http://freemarker.foofun.cn/index.html
解释的很详细,直接看官方网址就可以了。
二. Java 使用FreeMarker
二.一 前期准备
创建一个 Maven 项目, 在 pom.xml 中添加 依赖
<!--添加FreeMarker的依赖 ,版本是 2.3.29-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.29</version>
</dependency>
<!--测试junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
resources 目录下的 freemark 文件夹对应的目录是: D:\learncode\Template\FreeMark\Basic\src\main\resources\freemark
二.二 模板开发
这儿不与 Web 进行关联,不采用页面展示, 采用控制台输出。
二.二.一 单个属性展示
二.二.一.一 单个属性模板 FTL
创建 hello.ftl 文件
<html>
<head>
<title>${title}</title>
</head>
<body>
Hello ${info}
</body>
</html>
有两个属性 title 和 info 进行填充。
二.二.一.二 单个属性开发
@Test
public void fillBaseTest() throws Exception{
//1. 指定配置,对应着哪一个版本
Configuration configuration=new Configuration(
Configuration.VERSION_2_3_29
);
//设置目录
configuration.setDirectoryForTemplateLoading(
new File("D:\\learncode\\Template\\FreeMark\\Basic\\src\\main\\resources\\freemark")
);
//指定编码
configuration.setDefaultEncoding("utf-8");
//指定异常处理器
configuration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
//开始创建数据
Map<String,Object> root=new HashMap<>();
root.put("title","Hello Freemark");
root.put("info","两个蝴蝶飞");
//找到要设置的,对应的模板
Template template=configuration.getTemplate("hello.ftl","utf-8");
//写出到控制台
Writer out=new OutputStreamWriter(System.out);
//进行填充 数据和信息。
template.process(root,out);
}
二.二.二 单个对象展示
二.二.二.一 单个对象模板 FTL
创建 info.ftl 文件
<html>
<head>
<title>Welcome ${web} </title>
</head>
<body>
<h1>Welcome ${user}!</h1>
<p>Our latest product:
<a href="${info.url}">${}</a>!
</body>
</html>
web, user 属性是单个属性, info.url, 可以知道, info 是个对象。
二.二.二.二 单个对象开发
@Test
public void fillInfoTest() throws Exception{
//1. 设置相应的 Configuration
Configuration configuration=new Configuration(Configuration.VERSION_2_3_29);
//2. 设置基本的目录
configuration.setDirectoryForTemplateLoading(
new File("D:\\learncode\\Template\\FreeMark\\Basic\\src\\main\\resources\\freemark")
);
//3. 设置编码
configuration.setDefaultEncoding("utf-8");
//设置错误处理器
configuration.setTemplateExceptionHandler(
TemplateExceptionHandler.RETHROW_HANDLER
);
//4. 构建数据
Map<String,Object> root=new HashMap<>();
root.put("web","百度");
root.put("user","两个蝴蝶飞");
Map<String,Object> info=new HashMap<>();
info.put("url","www.yueshushu.top");
info.put("name","百度");
root.put("info",info);
//5. 获取对应的模板
Template template=configuration.getTemplate("info.ftl");
//6.构建输出对象
Writer out=new OutputStreamWriter(System.out);
//7. 调用 process 方法,进行填充数据
template.process(root,out);
}
二.二.三 If 展示
二.二.三.一 IF模板 FTL
创建 if.ftl 文件
<html>
<head>
<title>Welcome ${web} </title>
</head>
<body>
<!--单个if展示-->
<h1>Welcome ${user}! <#if user='yjl'>,领导牛逼</#if></h1>
<p>Our latest product:
<a href="${info.url}">${}</a>!
<h2>性别是:</h2>
<!--if else 展示-->
<#if sex=='男'>
男
<#else>
女
</#if>
<h2>成绩是:</h2>
<!--if elseif else-->
<#if score >90 >
优
<#elseif score >80>
良
<#elseif score >70>
中
<#elseif score >60>
及
<#else>
差
</#if>>
</body>
</html>
二.二.三.二 IF 开发
@Test
public void ifFillTest() throws Exception{
//1. 通过版本,获取相关的配置
Configuration configuration=new Configuration(Configuration.VERSION_2_3_29);
//2. 设置扫描的包的基本路径
configuration.setDirectoryForTemplateLoading(
new File("D:\\learncode\\Template\\FreeMark\\Basic\\src\\main\\resources\\freemark")
);
//3. 设置基本路径
configuration.setDefaultEncoding("utf-8");
//4. 设置数据
Map<String,Object> root=new HashMap<>();
root.put("web","IF验证");
root.put("user","yjl2");
Map<String,Object> info=new HashMap<>();
info.put("url","www.baidu.com");
info.put("name","百度");
root.put("info",info);
root.put("sex","女");
root.put("score",75);
//5. 获取对应的模板文件
Template template=configuration.getTemplate("if.ftl");
//6. 输出到控制台
Writer out=new OutputStreamWriter(System.out);
//7. 通过 process() 方法进行填充数据和输出信息对象.
template.process(root,out);
}
二.二.四 list 循环开发
二.二.四.一 list循环FTL
创建 list.ftl 文件
<html>
<head>
<title>Welcome ${web} </title>
</head>
<body>
<h2> list 的相关展示</h2>
<ul>
<#list hobbys as hobby>
<li>${hobby}</li>
</#list>
</ul>
<h2> list展示一起,</h2>
<#list hobbys>
<ul>
<#-- 用items 表示内部的元素, items -->
<#items as hobby>
<li>${hobby}
</#items>
</ul>
</#list>
<h2>分隔符展示</h2>
<p> hobbys: <#list hobbys as hobby>${hobby}<#sep>, </#list> </p>
<h2>展示表格的数据信息</h2>
<table>
<th>
<td>id编号</td>
<td>名称</td>
<td>年龄</td>
<td>性别</td>
<td>描述</td>
</th>
<#if uers??>
<#list users as u>
<tr>
<td>${u.id}</td>
<td>${}</td>
<td>${u.age}</td>
<td><#if u.sex==1>男<#else>女</#if></td>
<td>${u.description}</td>
</tr>
</#list>
<#-- 如果为空的话, #else 表示为空的意义-->
<#else>
<tr>
没有数据
</tr>
</#if>
</table>
</body>
</html>
二.二.四.二 List循环开发
对应的 User.java 对象
package com.zk.template.freemark.pojo;
import lombok.Data;
@Data
public class User {
private Integer id;
private String name;
private Integer sex;
private Integer age;
private String description;
}
@Test
public void listFillTest2() throws Exception{
Configuration configuration=new Configuration(
Configuration.VERSION_2_3_29
);
configuration.setDirectoryForTemplateLoading(
new File(
"D:\\learncode\\Template\\FreeMark\\Basic\\src\\main\\resources\\freemark"
)
);
configuration.setDefaultEncoding("utf-8");
//4. 设置数据
Map<String,Object> root=new HashMap<>();
root.put("web","List循环");
List<String> hobbys=new ArrayList<>();
hobbys.add("看书");
hobbys.add("打游戏");
hobbys.add("编程");
root.put("hobbys",hobbys);
//获取集合对象
List<User> userList=getUserList();
root.put("users",userList);
//5. 获取模板
Template template=configuration.getTemplate("list.ftl");
//输出信息
Writer out=new OutputStreamWriter(System.out);
//7. 进行填充数据
template.process(root,out);
}
private List<User> getUserList() {
List<User> userList=new ArrayList<>();
for(int i=1;i<=10;i++){
User user=new User();
user.setId(i);
user.setName("蝴蝶"+i);
user.setAge(i*3+1);
user.setSex(i%2);
user.setDescription("一个简单的描述");
userList.add(user);
}
return userList;
}
二.二.五 include 包含文件
二.二.五.一 include 文件 FTL
创建 foot.ftl
<hr>
<i>
Copyright (c) 2000 <a href="">yueshushu_top</a>,
<br>
</i>
创建 footinclude.ftl
<html>
<head>
<title>Include page</title>
</head>
<body>
<h1>Include page</h1>
<p>
<#-- 放置进去, #include 填充进去。 #include 填充进去。-->
<#include "foot.ftl">
</body>
</html>
二.二.五.二 include 开发
@Test
public void includeFillTest() throws Exception{
//1. 通过版本,获取相关的配置
Configuration configuration=new Configuration(Configuration.VERSION_2_3_29);
//2. 设置扫描的包的基本路径
configuration.setDirectoryForTemplateLoading(
new File("D:\\learncode\\Template\\FreeMark\\Basic\\src\\main\\resources\\freemark")
);
//3. 设置基本路径
configuration.setDefaultEncoding("utf-8");
//5. 获取对应的模板文件
Template template=configuration.getTemplate("footinclude.ftl");
//6. 输出到控制台
Writer out=new OutputStreamWriter(System.out);
//7. 通过 process() 方法进行填充数据和输出信息对象.
template.process(null,out);
}
二.二.六 其他配置
二.二.六.一 其他配置FTL
创建 other.ftl
- 字符串嵌套输出
<#--字符串嵌套输出-->
<h3>字符串嵌套输出</h3>
${"hello ${name}"}
- 定义变量
<h3>定义变量输出</h3>
<#assign number1 = 10>
<#assign number2 = 5>
- 算术运算符
<h3>定义变量输出</h3>
<#assign number1 = 10>
<#assign number2 = 5>
<#-- 支持"+"、"-"、"*"、"/"、"%"运算符 -->
"+" : ${number1 + number2}
"-" : ${number1 - number2}
"*" : ${number1 * number2}
"/" : ${number1 / number2}
"%" : ${number1 % number2}
- 内建函数
<h3>内建函数</h3>
第一个字母大写: ${str?cap_first}
所有字母小写: ${str?lower_case}
所有字母大写: ${str?upper_case}
- 将数据取整
<h3>将数据取整</h3>
<#assign floatData = 12.34>
数值取整数:${floatData?int}
- 获取集合的长度
<h3>获取集合的长度:</h3>
获取集合的长度:${users?size}
- 日期进行格式化
<h3>日期进行格式化</h3>
时间格式化:${dateTime?string("yyyy-MM-dd")}
- 循环遍历 map
<#--循环遍历map-->
Map集合:
<#assign mapData={"name":"程序员", "salary":15000}>
直接通过Key获取 Value值:${mapData["name"]}
通过Key遍历Map:
<#list mapData?keys as key>
Key: ${key} - Value: ${mapData[key]}
</#list>
通过Value遍历Map:
<#list mapData?values as value>
Value: ${value}
</#list>
整体编写:
<html>
<head>
<title>这是放置freemark的其他的相关的用法</title>
</head>
<body>
<#--字符串嵌套输出-->
<h3>字符串嵌套输出</h3>
${"hello ${name}"}
<h3>定义变量输出</h3>
<#assign number1 = 10>
<#assign number2 = 5>
<#-- 支持"+"、"-"、"*"、"/"、"%"运算符 -->
"+" : ${number1 + number2}
"-" : ${number1 - number2}
"*" : ${number1 * number2}
"/" : ${number1 / number2}
"%" : ${number1 % number2}
<h3>内建函数</h3>
第一个字母大写: ${str?cap_first}
所有字母小写: ${str?lower_case}
所有字母大写: ${str?upper_case}
<h3>将数据取整</h3>
<#assign floatData = 12.34>
数值取整数:${floatData?int}
<h3>获取集合的长度:</h3>
获取集合的长度:${users?size}
<h3>日期进行格式化</h3>
时间格式化:${dateTime?string("yyyy-MM-dd")}
<#--循环遍历map-->
Map集合:
<#assign mapData={"name":"程序员", "salary":10000}>
直接通过Key获取 Value值:${mapData["name"]}
通过Key遍历Map:
<#list mapData?keys as key>
Key: ${key} - Value: ${mapData[key]}
</#list>
通过Value遍历Map:
<#list mapData?values as value>
Value: ${value}
</#list>
</body>
</html>
二.二.六.二 其他配置开发
@Test
public void otherFill() throws Exception{
//1. 创建 Configuration 对象
Configuration configuration=new Configuration(Configuration.VERSION_2_3_29);
//2. 设置基本的目录信息。
configuration.setDirectoryForTemplateLoading(new File("D:\\learncode\\Template\\FreeMark\\Basic\\src\\main\\resources\\freemark"
));
//3. 设置编码等格式
configuration.setDefaultEncoding("utf-8");
//4. 设置要添加的数据信息
Map<String,Object> root=new HashMap<>();
root.put("name","两个蝴蝶飞");
root.put("str","Two Butterfly");
List<User> userList=getUserList();
root.put("users",userList);
root.put("dateTime",new Date());
//5. 获取对应的模板
Template template=configuration.getTemplate("other.ftl","utf-8");
//6. 设置输出对象
Writer out=new OutputStreamWriter(System.out);
//7. 调用 template的 process 方法,进行填充
template.process(root,out);
}
private List<User> getUserList() {
List<User> userList=new ArrayList<>();
for(int i=1;i<=10;i++){
User user=new User();
user.setId(i);
user.setName("蝴蝶"+i);
user.setAge(i*3+1);
user.setSex(i%2);
user.setDescription("一个简单的描述");
userList.add(user);
}
return userList;
}
三. 使用 FreeMarker 配置模板文件
可以使用 FreeMarker的配置文件, 通过往模板里面填充属性,来创建特定的文件。
如生成一个基本的 Main 类
三.一 模板 FTL
package ${packageName};
/**
@author: ${author}
@Date: ${createDate?string("yyyy-MM-dd hh:mm:ss")}
@Description: ${classDescription}
*/
public class ${className}{
/**
功能描述: ${mainMethodDesc!TODO}
*/
public static void main(String []args){
System.out.println("${info}");
}
}
三.二 模板类创建
public class CodeAuto {
public static String FTLTEMPLATE="src/main/java/com/zk/template/freemark/code/";
public static String CODELOCATION="src/main/java/com/zk/template/freemark/code/";
@Test
public void codeGenerate() throws Exception{
Configuration configuration=new Configuration(Configuration.VERSION_2_3_29);
configuration.setDirectoryForTemplateLoading(new File(FTLTEMPLATE));
configuration.setDefaultEncoding("utf-8");
//填充数据
Map root=getMainMap();
//获取对应的模板
Template template=configuration.getTemplate("main.ftl","utf-8");
//获取对应的输出流
Writer out=new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(
CODELOCATION+"FreeMain.java"
)
)
);
template.process(root,out);
System.out.println(">>>>>>创建模板类成功");
}
private Map<String,Object> getMainMap() {
Map<String,Object> root=new HashMap<>();
root.put("packageName","com.zk.template.freemark.code");
root.put("author","TwoButterfly");
root.put("createDate",new Date());
root.put("classDescription","一个测试Freemark 自动生成类");
root.put("className","FreeMain");
root.put("mainMethodDesc","一个普通的测试方法");
root.put("info","Freemark 创建类生成信息");
return root;
}
}
生成的模板文件类:
本章节的代码放置在 github 上:
https:///yuejianli/springboot/tree/develop/FreeMark
谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!