目录
前言
Freemarker学习笔记。
一、Freemarker 概述
FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据,并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。是一个Java类库。
FreeMarker 被设计用来生成 HTMLWeb 页面,特别是基于 MVC 模式的应用程序,将视图从业务逻辑中抽离处理,业务中不再包括视图的展示,而是将视图交给 FreeMarker 来输出。虽然 FreeMarker 具有一些编程的能力,但通常由Java 程序准备要显示的数据,由FreeMarker 生成页面,通过模板显示准备的数据(如下图):
FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件。
FreeMarker与容器无关,因为它并不知道HTTP或Servlet。FreeMarker同样可以应用
于非Web应用程序环境。
FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在板中使用JSP标记库。
二、Freemarker 数据类型
1.布尔类型
布尔型:等价于Java中的 boolean 类型,不同的是不能直接输出,可转化为字符串输出。
布尔类型不能在模板中直接使用,需要使用c、string、string('true','false')等方法进行转换。
//设置数据(给模版设置数据)
req.setAttribute("flag",false);
//模版
${flag?c}
${flag?string}
${flag?string('对了','错了')}
2.日期类型
日期型:等价于Java中的 Date 类型,不同的是不能直接输出,需要转换成字符串再输出。
日期类型不能在模板中直接使用,需要使用string('yyyy.MM.dd HH:mm:ss')、date、time、datetime等方法进行转换。
//设置数据(给模版设置数据)
req.setAttribute("date",new Date());
//模版
<#-- 自定义时间输出格式。-->
${date?string('yyyy.MM.dd HH:mm:ss')}</br>
<#--仅日期部分,没有一天当中的时间部分。-->
${date?date}</br>
<#--仅一天当中的时间部分,没有日期部分。-->
${date?time}</br>
<#--日期和时间都在-->
${date?datetime}
3.数值类型
等价于 Java 中的 int,float,double 等数值类型。有三种显示形式:数值型(默认),货币型(string.currency),百分比型(string.percent)。
//设置数据(给模版设置数据)
req.setAttribute("numberId",532930);
req.setAttribute("age",24);
req.setAttribute("avg",0.253);
//模版
<#--将数值转化为字符串类型-->
${numberId?c}<br>
<#--将数值转换为货币类型-->
${age?string.currency}<br>
<#-- 将数值转换为百分百类型-->
${avg?string.percent}<br>
4.字符串类型
等价于Java中的字符串,有很多内置函数。
//设置数据(给模版设置数据)
req.setAttribute("name","陈清零");
//模版
<#--字符串长度-->
${name?length}<br>
<#--提取字符串前两个字符并输出。-->
${name?substring(0,2)}<br>
<#--将字符串转换为小写并输出。-->
${name?lower_case}<br>
<#--将字符串的首字母大写并输出-->
${name?cap_first}<br>
5.sequence类型
FreeMarker 的变量必须赋值,否则就会抛出常。而对于 FreeMarker 来说,null 值和不存在的变量是完全一样的,因为 FreeMarker 无法理解 null 值。
FreeMarker 提供两个运算符来避免空值:
1. ! : 指定缺失变量的默认值
${ value! } : 如果value值为空,则默认值是空字符串
${ value! "默认值" } : 如果value值为空,则默认值是字符串"默认值"
2. ?? : 判断变量是否存在
${ (value??) ?string } : 如果变量存在,返回 true,否则返回 false
${CD!"CD不存在"}<br>
${(CD??)?string}
6.序列类型(数组、List、Set)
6.1数组
遍历数组:通过list指令输出序列
<#list 序列名 as 元素名>
${元素名}
</#list>
获取序列的长度:${序列名?size}
获取序列元素的下标:${元素名?index}
获取第一个元素:${序列名?first}
获取最后一个元素:${序列名?last}
//设置数据(给模版设置数据)
String[] strs={"java","c++","python","c"};
req.setAttribute("strs",strs);
//模版
<#list strs as item>
下标:${item?index}-课程名称:${item}<br>
</#list>
数组长度:${strs?size}<br>
第一个元素:${strs?first}<br>
最后一个元素:${strs?last}<br>
6.2集合
遍历集合:通过list指令输出序列
<#list 序列名 as 元素名>
${元素名}
</#list>
倒序输出:序列名?reverse
升序输出:序列名?sort
降序输出:序列名?sort?reverse
//设置数据(给模版设置数据)
List<String> list= Arrays.asList("云南","贵州","四川","重庆");
req.setAttribute("list",list);
//模版
<#list list as item>
${item} -
</#list><br>
<#--倒序输出 序列名?reverse-->
倒序输出:
<#list list?reverse as item>
${item}
</#list><br>
<#--升序输出 序列名?sort-->
升序输出:
<#list list?sort as item>
${item}
</#list><br>
<#--降序输出 序列名?sort?reverse-->
降序输出:
<#list list?sort?reverse as item>
${item}
</#list>
遍历Java对象
//设置数据(给模版设置数据)
//java 对象
List<Student> stu= new ArrayList<>();
stu.add(new Student(1,"张三",18,"北京市","12345678901","计算机网络1班"));
stu.add(new Student(2,"李四",16,"北京市","12345678901","人工智能1班"));
stu.add(new Student(3,"王五",24,"北京市","12345678901","大数据网络1班"));
req.setAttribute("stu",stu);
//模版
<#--遍历java对象-->
<#list stu?sort_by("age")?sort?reverse as student>
<li>
学号:${student.id}
姓名:${student.name}
年龄:${student.age}
地址:${student.address}
手机号:${student.phone}
班级:${student.className}
</li>
</#list>
6.1hash
遍历hash:
法一:key遍历输出
<#list 序列名?keys as key>
${key} -- ${hash[key]}
</#list>法二:value遍历输出
<#list 序列名?values as value>
${value}
</#list>
//设置模版(给模版设置数据)
Map<String, Object> map = new HashMap<>();
map.put("id",1);
map.put("name","塔斯汀");
map.put("age",18);
map.put("sex","男");
req.setAttribute("ttmap",map);
//模版
<#-- 法一 -->
<#list ttmap?keys as key >
${key}:${ttmap[key]}
</#list><br>
<#-- 法二 -->
<#list ttmap?values as value >
${value}
</#list><br>
<#-- 法三 -->
<#list ttmap as key,value>
${key}:${value}
</#list>
三、Freemarker 常见指令
1.assign 自定义变量指令
语法:
<#assign 变量名=值>
<#assign 变量名=值 变量名=值>(定义多个变量)
<#assign name="张三" age=18 love=["红","蓝","黄"]>
${name}-${age}
<#list love as item>
${item}
</#list>
2.if elseif else 逻辑判断指令
格式:
<#if condition>
<#elseif condition2>
<#elseif condition3>
<#else>
</#if>
注:
1.condition,condition2等,将被计算成布尔值的表达式。
2.elseif 和 else 指令 是可选的。
<#assign score=80>
<#if score<60>
考试不及格
<#elseif score gt 60 && score lt 80>
考试及格
<#else>
考试优秀
</#if>
3.list 遍历指令
格式1:
<#list sequence as item>
</#list>
格式2:
<#list sequence as item>
<#else>当没有选项时,执行else指令
</#list>
注:
1.else 部分是可选的
2.sequence: 想要迭代的项,可以是序列或集合的表达式
3.item: 循环变量 的名称
4.当没有迭代项时,才使用 else 指令,可以输出一些特殊的内容而不只是空在那里。
<#assign list1=[1,2,3,4,5,6,7,8,9,10]>
<#assign list2=["张三","李四","王五","赵六","钱七","马八","黄九","周十"]>
<#assign list3=[]>
<#list list1 as item>
${item}、
</#list><br>
<#-- 判断数据不为空,再执行遍历。当序列没有数值时,使用默认信息-->
<#if list7??>
<#list list7 as item>
${item}
</#list>
<#else>
没有数据遍历list2:
<#list list2 as item>
${item}
</#list>
</#if>
4.macro 自定义指令
macro自定义指令(宏)
1.基本使用
格式:
<#macro 指令名>
指令内容
</#macro>
使用:
<@指令名></@指令名>
2.有参数的自定义指令
格式:
<#macro 指令名 参数名1 参数名2>
指令内容
</#macro>
使用:
<@指令名 参数名1=参数值1 参数名2=参数值2></@指令名>
注
1.指令可以被多次使用。
2.自定义指令中可以包含字符串,也可包含内置指令-->
//用法一 自定义无参数指令
<#macro patent>
© 1999–2015 The FreeMarker Project. All rights reserved.
</#macro>
<#macro patent02>
嵌套自定义指令<@patent/>
</#macro>
<@patent/><br>
<@patent02/>
//用法二 自定义有参指令
<#macro customerInformation name age ddress>
<p>姓名:${name}</p>
<p>年龄:${age}</p>
<p>地址:${ddress}</p>
</#macro>
<@customerInformation name="李四" age="19" ddress="北京市" />
<#--九九乘法表-->
<#macro jj>
<#list 1..9 as i>
<#list 1..i as j>
${j} * ${i} = ${i*j}
</#list>
<br>
</#list>
</#macro>
<@jj/>
5.nested 占位符指令
nested 相当于占位符,一般结合macro指令一起使用。可以将自定义指令中的内容通过nested指令占位,当使用自定义指令时,会将占位内容显示。
<#macro text>
问君何能尔<#nested>
</#macro>
<@text/><br>
<@text>心远地自偏</@text>
6.import 指令
import 指令用于导入其他模板文件,并使用导入的模板文件中定义的变量。
import 指令的格式:
<#import "模板文件路径" as 指令名>
使用:
<@指令名.变量名/>
// f04.ftl
<#--九九乘法表-->
<#macro jj>
<#list 1..9 as i>
<#list 1..i as j>
${j} * ${i} = ${i*j}
</#list>
<br>
</#list>
</#macro>
<@jj/>
//f03.ftl
<#import "/template/f04.ftl" as f04>
<@f04.jj/>
7.include 包含指令
可以使用 include 指令在你的模板中插入另外一个 FreeMarker 模板文件。 被包含模板的输出格式是在include 标签出现的位置插入的。 被包含的文件和包含它的模板共享变量,就像是被复制粘贴进去的一样。
<#include "f04.ftl" >
四、Freemarker 页面静态化
通过上述介绍可知 Freemarker 是一种基于模板的、用来生成输出文本的通用工具,所以我们必须要定制符合自己业务的模板,然后生成自己的 html页面。
Freemarker 是通过freemarker.template.Configuration 这个对象对模板进行加载的(它也处理创建和缓存预解析模板的工作),然后我们通过 getTemplate 方法获得你想要的模板,有一点要记住freemarker.template.Configuration 在你整个应用必须保证唯一实例。
应用场景:页面上的数据基本不会变,变化频率不高。例如购物平台上的商品分类、新闻发布后的内容等。
1.定义模板
news.ftl
<#--新闻标题-->
<h4 align="center">${title}</h4>
<#--新闻来源 发布时间-->
<p align="center">
<#--本报记者-->
本报记者 ${author}<br>
新闻来源:${source} 发布时间:${date?string('yyyy.MM.dd HH:mm:ss')}
</p>
<#--新闻内容-->
<p style="text-align: center ;text-indent:2em">
${content}
</p>
2.加载模版
//实例化模版对象
Configuration con= new Configuration();
//设置加载模版的上下文 以及加载模版的路径 (模版存放路径)
con.setServletContextForTemplateLoading(this.getServletContext(),"template");
//设置模版的 编码格式
con.setDefaultEncoding("utf-8");
//加载模版文件 获取模版对象
Template template = con.getTemplate("news.ftl");
//设置数据模型
Map<String, Object> map = new HashMap<>();
map.put("title","家门口有了优质中医药服务(健康焦点)");
map.put("content","今年9月,国家中医药管理局等5部门联合发布《关于加快推进县级中医医院高质量发展的意见》(以下简称《意见》),提出到2025年,80%以上县级中医医院力争达到二级甲等以上中医医院水平,500所左右县级中医医院力争达到三级中医医院水平。\n"+"据统计,目前我国县级中医医院有2000多家,约占公办中医医院的3/4,其诊疗量约占县域中医医疗机构总诊疗量的70%。近年来,我国县级中医医院建设取得一定进展,基础设施条件有所改善,管理水平、人员素质有了进一步提高。深入落实《意见》要求,各地正在努力探索,加快推进县级中医医院高质量发展。\n" +"医疗资源沉下去——\n" + "破解基层医疗服务难题,推进县级中医医院医共体建设");
map.put("author","杨xx 游 x 窦xx");
map.put("source","xx日报");
map.put("date",new Date());
3.生成对应的html文件
//获取项目的根目录
String path = req.getServletContext().getRealPath("/");
//设置html文件存放的路径
File htmlFile = new File(path+"/html");
//判断文件(目录)是否存在
if (!htmlFile.exists()){
//如果不存在就创建
htmlFile.mkdir();
}
//得到生成的文件名(生成随机不重复的文件名)
String fileName = System.currentTimeMillis()+".html";
//创建html文件
File file = new File(htmlFile,fileName);
//获取文件输出流
FileWriter fileWriter = new FileWriter(file);
//生成html(将数据模型填充到模版 中)
try {
template.process(map, fileWriter);
} catch (TemplateException e) {
e.printStackTrace();
}finally {
//关闭资源
fileWriter.flush();
fileWriter.close();
}
五、Freemarker 运算符
1.算数运算符
<#-- +、-、*、/、%-->
<#assign a=3 b=5>
${a} + ${b} = ${a+b}<br>
${a} - ${b} = ${a-b}<br>
${a} * ${b} = ${a*b}<br>
${a} / ${b} = ${a/b}<br>
${a} % ${b} = ${a%b}<br>
2.逻辑运算符
<#--&&、||、! -->
<#assign a=3 b=5 c=15>
<#if a*b=c && a<b>
&&
</#if>
<#if a==b || a<b>
||
</#if>
<#if a!=b >
!
</#if>
3. 比较运算符
gt : 大于号,推荐使用 gt
lt : 小于号,推荐使用 lt
gte : 大于等于,推荐是用 gte
lte : 小于等于,推荐使用 lte
== : 等于
!= : 不等于
<#assign a=3 b=5 c=15>
<#if c gt b >
${c} 大于 ${b}<br>
</#if>
<#if a lt b>
${a} 小于 ${b}<br>
</#if>
<#if a*b gte c>
${a} 乘 ${b} 大于等于 ${c}<br>
</#if>
<#if a*b lte c>
${a} 乘 ${b} 小于等于 ${c}
</#if>
4.空值运算符
空值运算符
1. ?? : 判断是否为空,返回布尔类型
如果不为空返回 false,如果为空返回 true,不能直接输出
${(name??)?string}
2. ! : 设置默认值,如果为空,则设置默认值
1.设置默认为空字符串:
${name!}
2.设置指定默认值
${name!'张三'}
<#assign name="">
${(name??)?string}
${(name2??)?string}
${(name2??)?string('存在','不存在')}
${name2!"陈清零"}
总结
学习总结笔记。
标签:string,Freemarker,--,模版,笔记,运算符,指令,FreeMarker,模板 From: https://blog.csdn.net/weixin_45694171/article/details/144529993