什么是 FreeMarker?
FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
模板编写为FreeMarker Template Language (FTL)。它是简单的,专用的语言, 不是 像PHP那样成熟的编程语言。 那就意味着要准备数据在真实编程语言中来显示,比如数据库查询和业务运算, 之后模板显示已经准备好的数据。在模板中,你可以专注于如何展现数据, 而在模板之外可以专注于要展示什么数据。
这种方式通常被称为 MVC (模型 视图 控制器) 模式,对于动态网页来说,是一种特别流行的模式。 它帮助从开发人员(Java 程序员)中分离出网页设计师(HTML设计师)。设计师无需面对模板中的复杂逻辑, 在没有程序员来修改或重新编译代码时,也可以修改页面的样式。
而FreeMarker最初的设计,是被用来在MVC模式的Web开发框架中生成HTML页面的,它没有被绑定到 Servlet或HTML或任意Web相关的东西上。它也可以用于非Web应用环境中。
FreeMarker 是免费的, 基于Apache许可证2.0版本发布。
作用与优点
作用:freemarker模板引擎可以通过模板和数据生成静态页面
优点:
1.提前根据模板和数据生成静态化页面 可以通过IO流 将页面写在硬盘上 访问的时候直接进行访问不去访问数据库 提高了用户的体验度
2.以往用JSP展现数据时,程序员并不熟悉界面设计技术,反之界面开发人员,也并不熟悉程序语言。协调工作很困难,使用FreeMarker后,作为界面开发人员,只专心创建HTML文件、图像以及Web页面的其他可视化方面,不用理会数据;而程序开发人员则专注于系统实现,负责为页面准备要显示的数据。
3.由于是静态页面 所以html不需要tomcat解析浏览器就可以直接访问
缺点:
应用FreeMarker模板技术,在修改模板后,可能会看到已经过期的数据。如:生成静态的HTML页面后,如果一旦模板改变,而没有及时更新模板生成的HTML页面的话,用户看到的就是过期的数据。
使用场景
1.新闻网站 新闻页面 通过freemarker提前生成好
2.电商网站的商品详情页面 通过freemarker提前生成的
原则:页面固定的样式 并且一次生成多次读取 尽量的少改动数据
同类技术
和freemarker同类型的技术
velocity技术-------------------也是一个模板引擎框架 但是被freemarker所替代
模板:在freemarker中式以.ftl为后缀的文件。模板中可以使用CSS JS img 图片等静态资源 可以使用el表达式来获取数据
无法使用jstl来进行判断和循环 但是自身有一套标签库可以提供我们使用
数据:一般存在在关系型数据库 redis mongodb 中
使用步骤和入门Demo
使用步骤:
第一步:创建一个Configuration对象,直接new一个对象。
第二步:设置模板文件所在的路径。
第三步:设置模板文件使用的字符集。一般就是utf-8.
第四步:加载一个模板,创建一个模板对象。
第五步:创建一个模板使用的数据集,可以是pojo也可以是map。一般是Map。
第六步:创建一个Writer对象,一般创建一FileWriter对象,指定生成的文件名。
第七步:调用模板对象的process方法输出文件。
第八步:关闭流。
第一步 引入meven中的POM.xml
<dependencies> <dependency> <groupId>org.freemarkergroupId> <artifactId>freemarkerartifactId> <version>2.3.23version> dependency> dependencies>
第二步 代码引入
public static void main(String[] args) throws Exception{ //1创建模板引擎 Configuration conf = new Configuration(); //2加载模板所在路径位置 conf.setDirectoryForTemplateLoading(new File("E:\\ideaProject\\freemarkerDemo\\src\\main\\resources\\ftl")); //3加载模板对象 Template template = conf.getTemplate("test.ftl"); //4模拟假数据 将这些数据放入到模板中 Map<String, Object> rootMap = new HashMap<String,Object>(); rootMap.put("name","张三"); rootMap.put("message","这是一个freemarker生成的静态页面"); // 模拟List集合数据 List<String> personList = new ArrayList<String>(); personList.add("青龙"); personList.add("白虎"); personList.add("老牛"); personList.add("龙头"); rootMap.put("personList",personList); // 模拟Map集合数据 Map<String, String> personMap = new HashMap<>(); personMap.put("001","韦小宝"); personMap.put("002","双儿"); personMap.put("003","阿珂"); personMap.put("004","建宁"); personMap.put("005","龙儿"); personMap.put("006","曾柔"); rootMap.put("personMap",personMap);
//模拟日期格式 rootMap.put("today",new Date());
//模拟资薪中间的间隔 rootMap.put("point",882168988); // 5 创建io流 流中指定文件输出位置和文件名 Writer out = new FileWriter(new File("E:\\ideaProject\\freemarkerDemo\\src\\main\\java\\admin\\hhh.html")); // 6生成静态页面 template.process(rootMap,out); // 7关闭流 out.close();
第三步 所对应的ftl文件
<html> <head> <meta charset="utf-8"/> <title>Freemarker入门小demotitle> head> <body> <#--引入外部页面--> <#include "head.ftl"/> <#--我只是一个注释我不会有任何的输出--> 姓名:${name} <br> 简述:${message} <br/> <#assign linkman="李四"> <#assign linkman="王五"> 联系人:${linkman} <#assign info={"mobile":"1588888","address":"这是一个地址XXXXX"}> 电话:${info.mobile} 地址:${info.address} <#--去List集合数据--> <#list personList as person> <#if person_index==0> 这是第一次循环 <#else> 这是第${person_index+1}次循环 #if> 集合索引 ${person_index} ${person} #list> 共${personList?size}条记录 <#--获取map集合中的数据--> <#list personMap?keys as key> map中的key为:${key} map中的value为:${personMap[key]} #list> 当前日期:${today?date}<br> 当前时间:${today?time}<br> 当前 日期+时间 :${today?datetime}<br> 格式化:${today?string("yyyy年MM月dd日")}<br> ${point}<br> 累计月薪 ${point?c} <#if aaa??> aaa变量存在 <#else> aaa变量不存在 #if> ${aaa!'这个aaa变量不存在'} body> html>
第四步 生成静态页面 效果
语法详解
数据类型
和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表达式差不多,直接点出来。
字符串操作
字符串连接:可以直接嵌套${"hello , ${name}"} ; 也可以用加号${"hello , " + name}
字符串截取:string[index]。index 可以是一个值,也可以是形如 0..2 表示下标从0开始,到下标为2结束。一共是三个数。
比较运算符
== (等于),!= (不等于),gt(大于),gte(大于或者等于),lt(小于),lte(小于或者等于)。不建议用 >,< 可能会报错!
一般和 if 配合使用
内建函数
FreeMarker 提供了一些内建函数来转换输出,其结构:变量?内建函数,这样就可以通过内建函数来转换输出变量。
1. html: 对字符串进行HTML编码;
2. cap_first: 使字符串第一个字母大写;
3. lower_case: 将字符串转成小写;
4. upper_case: 将字符串转成大写;
5. size: 获得集合中元素的个数;
6. int: 取得数字的整数部分。
变量空判断
! 指定缺失变量的默认值;一般配置变量输出使用
?? 判断变量是否存在。一般配合if使用 <#if value??>#if>
宏指令
可以理解为java的封装方法,供其他地方使用。宏指令也称为自定义指令,macro指令
语法很简单:<#macro val > 声明macro #macro>; 使用macro <@val />
命名空间
可以理解为java的import语句,为避免变量重复。一个重要的规则就是:路径不应该包含大写字母,使用下划线_分隔词语,myName --> my_name
语法很简单:<#import "xxx.ftl" as val>
其他没有说明的语法是因为和java一样,没什么特别之处。所以没有列出来。
总结
1. 知道了FreeMarker是一块模版引擎,可以生产xml,html,java等文件
2. 知道了FreeMarker文件提供占位符,java文件提供数据,通过FreeMarker模版引擎生产有数据的页面,文中是将数据放在Map中。web应用可以用setter/getter 方法
3. 知道了FreeMarker语法中字符串的显示特殊字符,截取的操作。以及一些内置方法的使用
4. 重点了解FreeMarker的空判断知识点。判断变量是否为空用 "??" ,如果变量为空设置默认值。如果不注意空问题,可能会出现黄色页面的提示哦!
5. FreeMarker的宏概念,命名空间,引入文件,给变量赋值,集合的遍历等。
6. Freemarker 整合SpringMVC。