FreeMarker速查手册
一、开始
原理图
引入FreeMarker依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
二、入门实例
模板文件:hello.ftl,放到d://tmp/freemark/templates目录下
package ${classPath};
public class ${className} {
public static void main(String[] args) {
System.out.println("${helloWorld}");
}
}
FreemarkerDemo.java
public class FreemarkerDemo {
// 模板路径
private static final String TEMPLATE_PATH = "d://tmp/freemark/templates";
// 生成文件路径
private static final String OUTPUT_PATH = "d://tmp/freemark/output";
public static void main(String[] args) {
// step1 创建freeMarker配置实例
Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);
Writer out = null;
try {
// step2 获取模版路径
configuration.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH));
// step3 创建数据模型
Map<String, Object> dataMap = new HashMap<String, Object>();
dataMap.put("classPath", "com.freemark.hello");
dataMap.put("className", "AutoCodeDemo");
dataMap.put("helloWorld", "通过简单的 <代码自动生产程序> 演示 FreeMarker的HelloWorld!");
// step4 加载模版文件
Template template = configuration.getTemplate("hello.ftl");
// step5 生成数据
File docFile = new File(OUTPUT_PATH + "\\" + "AutoCodeDemo.java");
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
// step6 输出文件
template.process(dataMap, out);
System.out.println("^^^^^^^^^^^^^^^^^^^^^^^^AutoCodeDemo.java 文件创建成功 !");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != out) {
out.flush();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
执行上面的代码,在d://tmp/freemark/output目录下会生成AutoCodeDemo.java,如下图所示:
三、语法
3.1 数据类型
数据类型
和java不同,FreeMarker不需要定义变量的类型,直接赋值即可。
字符串: value = "xxxx" 。如果有特殊字符 string = r"xxxx" 。单引号和双引号是一样的。
数值:value = 1.2。数值可以直接等于,但是不能用科学计数法。
布尔值:true or false。
List集合:list = [1,2,3] ; list=[1..100] 表示 1 到 100 的集合,反之亦然。
Map集合:map = {"key" : "value" , "key2" : "value2"},key 必须是字符串哦!
实体类:和EL表达式差不多,直接点出来。
3.2 字符串操作
字符串操作:
字符串连接:可以直接嵌套${"hello , ${name}"} ; 也可以用加号${"hello , " + name}
字符串截取:string[index]。index 可以是一个值,也可以是形如 0..2 表示下标从0开始,到下标为2结束。一共是三个数。
-----------------------code
字符串输出:
${"Hello ${name} !"} / ${"Hello " + name + " !"}
<#assign cname=r"特殊字符完成输出(http:\www.baidu.com)">
${cname}
字符串截取 :
通过下标直接获取下标对应的字母: ${name[2]}
起点下标..结尾下标截取字符串:${name[0..5]}
3.3 算术运算符
算数运算:
<#-- 支持"+"、"-"、"*"、"/"、"%"运算符 -->
<#assign number1 = 10>
<#assign number2 = 5>
"+" : ${number1 + number2}
"-" : ${number1 - number2}
"*" : ${number1 * number2}
"/" : ${number1 / number2}
"%" : ${number1 % number2}
3.4 比较运算符
比较运算符:
== (等于),!= (不等于),gt(大于),gte(大于或者等于),lt(小于),lte(小于或者等于)。不建议用 >,< 可能会报错!
一般和 if 配合使用
------------------------------
<#if number1 + number2 gte 12 || number1 - number2 lt 6>
"*" : ${number1 * number2}
<#else>
"/" : ${number1 / number2}
</#if>
3.5 内建函数
内建函数:
FreeMarker 提供了一些内建函数来转换输出,其结构:变量?内建函数,这样就可以通过内建函数来转换输出变量。
html: 对字符串进行HTML编码;
cap_first: 使字符串第一个字母大写;
lower_case: 将字符串转成小写;
upper_case: 将字符串转成大写;
size: 获得集合中元素的个数;
int: 取得数字的整数部分。
--------------------------------
<#assign data = "abcd1234">
第一个字母大写:${data?cap_first}
所有字母小写:${data?lower_case}
所有字母大写:${data?upper_case}
<#assign floatData = 12.34>
数值取整数:${floatData?int}
获取集合的长度:${users?size}
时间格式化:${now?string("yyyy-MM-dd")}
3.6 空判断
变量空判断
! 指定缺失变量的默认值;一般配置变量输出使用
?? 判断变量是否存在。一般配合if使用 <#if value??></#if>
-----------------code
<#if users??>
<#list users as user >
${user.id} - ${user.name}
</#list>
<#else>
${user!"变量为空则给一个默认值"}
</#if>
3.7 list与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>
List集合:
<#assign listData=["ITDragon", "blog", "is", "cool"]>
<#list listData as value>${value} </#list>
3.8 include指令
include指令:
引入其他文件:<#include "hello.ftl" />
3.9 宏指令
可以理解为java的封装方法,供其他地方使用。宏指令也称为自定义指令,macro指令
语法很简单:<#macro val > 声明macro </#macro>; 使用macro <@val />
--------------------------code
macro宏指令:
<#macro mo>
定义无参数的宏macro--${name}
</#macro>
使用宏macro: <@mo />
<#macro moArgs a b c>
定义带参数的宏macro-- ${a+b+c}
</#macro>
使用带参数的宏macro: <@moArgs a=1 b=2 c=3 />
3.10 命名空间
可以理解为java的import语句,为避免变量重复。一个重要的规则就是:路径不应该包含大写字母,使用下划线_分隔词语,myName --> my_name
语法很简单:<#import "xxx.ftl" as val>
---------------------code
命名空间:
<#import "otherFreeMarker.ftl" as otherFtl>
${otherFtl.otherName}
<@otherFtl.addMethod a=10 b=20 />
<#assign otherName="修改otherFreeMarker.ftl中的otherName变量值"/>
${otherFtl.otherName}
<#assign otherName="修改otherFreeMarker.ftl中的otherName变量值" in otherFtl />
${otherFtl.otherName}
四、汇总实例
learn.ftl
字符串输出:
${"Hello ${name} !"} / ${"Hello " + name + " !"}
<#assign cname=r"特殊字符完成输出(http:\www.baidu.com)">
${cname}
字符串截取 :
通过下标直接获取下标对应的字母: ${name[2]}
起点下标..结尾下标截取字符串:${name[0..5]}
算数运算:
<#-- 支持"+"、"-"、"*"、"/"、"%"运算符 -->
<#assign number1 = 10>
<#assign number2 = 5>
"+" : ${number1 + number2}
"-" : ${number1 - number2}
"*" : ${number1 * number2}
"/" : ${number1 / number2}
"%" : ${number1 % number2}
比较运算符:
<#if number1 + number2 gte 12 || number1 - number2 lt 6>
"*" : ${number1 * number2}
<#else>
"/" : ${number1 / number2}
</#if>
内建函数:
<#assign data = "abcd1234">
第一个字母大写:${data?cap_first}
所有字母小写:${data?lower_case}
所有字母大写:${data?upper_case}
<#assign floatData = 12.34>
数值取整数:${floatData?int}
获取集合的长度:${users?size}
时间格式化:${now?string("yyyy-MM-dd")}
空判断和对象集合:
<#if users??>
<#list users as user >
${user.id} - ${user.name}
</#list>
<#else>
${user!"变量为空则给一个默认值"}
</#if>
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>
List集合:
<#assign listData=["ITDragon", "blog", "is", "cool"]>
<#list listData as value>${value} </#list>
include指令:
引入其他文件:<#include "hello.ftl" />
macro宏指令:
<#macro mo>
定义无参数的宏macro--${name}
</#macro>
使用宏macro: <@mo />
<#macro moArgs a b c>
定义带参数的宏macro-- ${a+b+c}
</#macro>
使用带参数的宏macro: <@moArgs a=1 b=2 c=3 />
命名空间:
<#import "otherFreeMarker.ftl" as otherFtl>
${otherFtl.otherName}
<@otherFtl.addMethod a=10 b=20 />
<#assign otherName="修改otherFreeMarker.ftl中的otherName变量值"/>
${otherFtl.otherName}
<#assign otherName="修改otherFreeMarker.ftl中的otherName变量值" in otherFtl />
${otherFtl.otherName}
otherFreeMarker.ftl
其他FreeMarker文件
<#macro addMethod a b >
result : ${a + b}
</#macro>
<#assign otherName="另外一个FreeMarker的变量">
测试类:FreeMarkerTest.java
public class FreemarkerTest {
// 模板目录
private static final String TEMPLATE_PATH = "d://tmp/freemark/templates";
// 输出目录
private static final String OUTPUT_PATH = "d://tmp/freemark/output";
@Test
public void test001() {
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("name", "WorldWorld");
dataMap.put("now", new Date());
List<User> users = new ArrayList<>();
for (int i=0; i<19; i++) {
users.add(new User(i, "name" + i));
}
dataMap.put("users", users);
// hello.ftl中用到的数据
dataMap.put("classPath", "com.freemark.hello");
dataMap.put("className", "AutoCodeDemo");
dataMap.put("helloWorld", "通过简单的 <代码自动生产程序> 演示 FreeMarker的HelloWorld!");
dataMap.put("otherName", "这是otherName");
testFreemarker("learn.ftl", dataMap, "learn.txt");
}
public void testFreemarker(String templateName, Map<String, Object> dataMap, String outputName) {
// step1 创建freeMarker配置实例
Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);
Writer out = null;
try {
// step2 获取模版路径
configuration.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH));
// step3 创建数据模型
// step4 加载模版文件
Template template = configuration.getTemplate(templateName);
// step5 生成数据
File docFile = new File(OUTPUT_PATH + "\\" + outputName);
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
// step6 输出文件
template.process(dataMap, out);
System.out.println("^^^^^^^^^^^^^^^^^^^^^^^^" + outputName + " 文件创建成功 !");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != out) {
out.flush();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
public class User {
private Integer id;
private String name;
public User(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
五、参考
FreeMarker速查手册的更多相关文章
- 《zw版·Halcon-delphi系列原创教程》 zw版-Halcon常用函数Top100中文速查手册
<zw版·Halcon-delphi系列原创教程> zw版-Halcon常用函数Top100中文速查手册 Halcon函数库非常庞大,v11版有1900多个算子(函数). 这个Top版,对 ...
- 25个有用的和方便的 WordPress 速查手册
如果你是 WordPress 开发人员,下载一些方便的 WordPress 备忘单可以在你需要的时候快速查找.下面这个列表,我们已经列出了25个有用的和方便的 WordPress 速查手册,赶紧收藏吧 ...
- R之data.table速查手册
R语言data.table速查手册 介绍 R中的data.table包提供了一个data.frame的高级版本,让你的程序做数据整型的运算速度大大的增加.data.table已经在金融,基因工程学等领 ...
- 25个有用和方便的 WordPress 速查手册
如果你是一个 WordPress 编码器或开发人员,下载一些方便的 WordPress 备忘单寻找你的工作然后你在正确的地方.我们已经列出了25个有用的和方便的 WordPress 速查手册.Word ...
- 几个较好的SQL速查手册网址
微软 SQL server 数据库开发手册 数据库设计 Transact-SQL 速查手册 数据库设计 MySQL 中文参考手册速查 结构化查询语言 SQL 学习手册速查 转自:http://www. ...
- web 开发:CSS3 常用属性——速查手册!
web 开发:CSS3 常用属性——速查手册! CSS3 简介:http://www.runoob.com/css3/css3-intro.html 1.目录 http://caniuse.com/ ...
- Markdown速查手册
之前一直使用简书做笔记,沉浸式的写作环境很棒.然而不知什么时候起,氛围愈发浮躁,软文鸡汤泛滥,离"简"字越来越远. 相比更加喜欢沉稳低调.内涵取胜的博客园.于是乎搬家! 搬家就要丢 ...
- Pandas速查手册中文版
本文翻译自文章: Pandas Cheat Sheet - Python for Data Science ,同时添加了部分注解. 对于数据科学家,无论是数据分析还是数据挖掘来说,Pandas是一个非 ...
- SSM 项目从搭建爬坑到 CentOS 服务器部署 - 速查手册
SSM 项目从搭建爬坑到 CentOS 服务器部署 - 速查手册 提示: (1)CSDN 博客左边有操作工具条上有文章目录 (2)SSM 指 Spring,Spring MVC,MyBatis Mav ...
随机推荐
- vs code下代码提示图标的含义(c++)
其实不同的语言这些东西的含义还有不同 但差别也不是很大,比如Python中的那个大括号图标就成了模块(module)了
- mian中的argv调用时为什么不是*argv
c++main函数char * argv[]是个指针数组,元素是指针,为何argv[1]得到不是地址? 照我的理解char *argv[]保存的应该是一组指针,即地址,每个地址中保存的是char类型变 ...
- H5: 表单验证失败的提示语
前言 前端的童鞋在写页面时, 都不可避免的总会踩到表单验证这个坑. 这时候, 我们就要跪了, 因为要写一堆js来检查. 但是自从H5出现后, 很多常见的表达验证, 它都已经帮我们实现了, 让我 ...
- nginx之配置文件公用抽取
nginx之配置文件公用抽取 因为某些原因,需要同时部署同一应用两个不同分支的代码,而配置文件存在较大重复,因此有此篇. 最近构建的过程中遇到了一些跟nginx配置相关的问题,记录下. 简单说下构建的 ...
- Windows中Nginx配置nginx.conf不生效解决方法
转:https://lucifer.blog.csdn.net/article/details/83860644?utm_medium=distribute.pc_relevant.none-task ...
- Python入门-面向对象-特殊方法
调用拦截功能 class Message: def send(self,info): print("消息发送:",info) class Me: def __getattribut ...
- drf中的请求与响应
请求与响应(3星) 请求:Request REST framework 传入视图的request对象不再是Django默认的HttpRequest对象,而是REST framework提供的扩展了Ht ...
- js刷新页面window.location.reload()
window.location.reload()刷新当前页面 window.parent.location.reload()刷新父亲对象(用于框架) opener.location.reload()刷 ...
- vue预渲染及其cdn配置
VUE SEO方案一 - 预渲染及其cdn配置 项目接入VUE这样的框架后,看起来真是太漂亮了,奈何与MCV框架比起来,单页应用程序却满足不了SEO的业务需求,首屏渲染时间也是个问题.总不能白学VUE ...
- 2021.11.11 EXKMP
2021.11.11 EXKMP https://www.luogu.com.cn/problem/P5410 下标以1开头: #include<cstdio> #include<i ...