freemarker
介绍
freemarker是apache的一个开源的模板引擎。
作用:freemarker模板引擎可以通过模板和数据生成静态化页面。
优点:
- 提前根据模板和数据生成静态化页面,通过io流,将页面写入到硬盘上,访问时直接访问,可以不用访问数据库,可以大大降低数据库的高并发读取性能,使数据库访问量降低
- 由于页面是提前生成的,所以访问速度快,客户体验好。
- 由于html不需要tomcat解析,浏览器可以直接访问,所以给tomcat降低高并发访问压力。
使用场景:
- 新闻网站或新闻页面通过freemarker提前生成
- 电商网站的商品详情页面
使用原则:页面有固定的样式,一次生成多次读取,尽量少得改动数据
同类型技术:velocity,但被替代了
freemarker生成静态化页面:
-
页面=模板+数据
-
模板:模板在freemarker中是以.ftl为后缀名的文件,在模板中可以使用html标签,css,js,图片等静态资源,模板中可以使用el表达式来获取数据,但无法使用jstl来判断和循环,所以模板引擎会有一套自己的标签库。
-
数据:数据一般存储在关系型数据库或redis或mongodb中获取
原理
小例子
一、引入依赖
<dependencies>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
</dependencies>
二、创建ftl模板
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入门小DEMO </title>
</head>
<body>
<#--我只是一个注释,我不会有任何输出 -->
${name},你好。${message}
</body>
</html>
三、生成静态页面
- 创建模板引擎对象
- 加载模板所在目录
- 加载模板
- 创建数据
- 创建io流,流中指定文件的输出位置和文件名
- 生成页面
- 关闭io流
public class TestFreemarker {
public static void main(String[] args) throws Exception {
//1.创建模板引擎对象
Configuration conf = new Configuration();
//2.加载模板所在目录
conf.setDirectoryForTemplateLoading(new File("D:\\Program Files\\IDEA Projects\\freemarkerDemo\\src\\main\\resources\\ftl"));
//3.加载模板
Template template = conf.getTemplate("test.ftl");
//4.创建数据
Map<String,Object> dataMap = new HashMap<>();
dataMap.put("name","王五");
dataMap.put("message","你好!");
//5.创建io流,流中指定文件的输出位置和文件名
Writer writer = new FileWriter(new File("D:\\Program Files\\IDEA Projects\\freemarkerDemo\\src\\main\\resources\\pages\\hello.html"));
//6.生成页面
template.process(dataMap,writer);
//7.关闭io流
writer.close();;
}
}
四、生成的静态页面
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入门小DEMO </title>
</head>
<body>
王五,你好。你好!
</body>
</html>
FTL指令
assigh指令
(1)定义简单类型:
<#assign linkman="周先生">
联系人:${linkman}
(2)定义对象类型:
<#assign info={"mobile":"13301231212",'address':'北京市昌平区王府街'} >
电话:${info.mobile} 地址:${info.address}
效果
include指令
此指令用于模板文件的嵌套,相当于一个页面引入另一个页面
创建模板文件head.ftl
<h1>黑马信息网</h1>
我们修改test.ftl,在模板文件中使用include指令引入刚才我们建立的模板
<#include "head.ftl"/>
list
注意:${person_index}
可以取出索引
<#-- 模拟获取List集合数据 -->
<#list personList as person>
集合索引:${person_index}
${person}
</#list>
生成页面
public class TestFreemarker {
public static void main(String[] args) throws Exception {
//1.创建模板引擎对象
Configuration conf = new Configuration();
//2.加载模板所在目录
conf.setDirectoryForTemplateLoading(new File("D:\\Program Files\\IDEA Projects\\freemarkerDemo\\src\\main\\resources\\ftl"));
//3.加载模板
Template template = conf.getTemplate("test.ftl");
//4.创建数据
Map<String,Object> dataMap = new HashMap<>();
dataMap.put("name","王五");
dataMap.put("message","你好!");
/**
* 模拟List集合数据
*/
List<String> personList = new ArrayList<>();
personList.add("王五");
personList.add("张三");
personList.add("老刘");
personList.add("老七");
dataMap.put("personList",personList);
//5.创建io流,流中指定文件的输出位置和文件名
Writer writer = new FileWriter(new File("D:\\Program Files\\IDEA Projects\\freemarkerDemo\\src\\main\\resources\\pages\\hello.html"));
//6.生成页面
template.process(dataMap,writer);
//7.关闭io流
writer.close();;
}
}
生成的页面
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入门小DEMO </title>
</head>
<body>
王五,你好。你好!
集合索引:0
王五
集合索引:1
张三
集合索引:2
老刘
集合索引:3
老七
</body>
</html>
map
也是使用list指令来取
<#--模拟Map集合-->
<#list personMap?keys as key>
key:${key}
value:${personMap[key]}
</#list>
结果
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入门小DEMO </title>
</head>
<body>
王五,你好。你好!
集合索引:0
王五
集合索引:1
张三
集合索引:2
老刘
集合索引:3
老七
key:001
value:王五
key:002
value:王四
key:003
value:王三
key:004
value:王二
</body>
</html>
判断
<#-- 模拟获取List集合数据 -->
<#list personList as person>
<#if person_index == 0>
第一次循环
<#else>
第${person_index+1}循环
</#if>
集合索引:${person_index}
${person}
</#list>
结果
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入门小DEMO </title>
</head>
<body>
王五,你好。你好!
第一次循环
集合索引:0
王五
第2循环
集合索引:1
张三
第3循环
集合索引:2
老刘
第4循环
集合索引:3
老七
key:001
value:王五
key:002
value:王四
key:003
value:王三
key:004
value:王二
</body>
</html>
内建函数和运算符
内建函数语法格式: 变量+?+函数名称
获取集合大小
共 ${goodsList?size} 条记录
日期格式化
代码中对变量赋值:
map.put("today", new Date());
在模板文件中加入
当前日期:${today?date} <br>
当前时间:${today?time} <br>
当前日期+时间:${today?datetime} <br>
日期格式化: ${today?string("yyyy年MM月")}
数字转换为字符串
代码中对变量赋值:
map.put("point", 102920122);
如果不转化:每三位加一个逗号
累计积分:${point}
进行转化:原样显示
累计积分:${point?c}
空值处理运算符
用法为:variable??
如果该变量存在,返回true,否则返回false
<#if aaa??>
aaa变量存在
<#else>
aaa变量不存在
</#if>
缺失变量默认值:“!”
如果不存在展示后面的东西,如果存在打印值
${aaa!'这个变量不存在'}
运算符
和java中相同,有一个不同
区别
=或者==:判断两个值是否相等.