1、什么是FreeMarker
FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。模板编写为FreeMarker Template Language (FTL)。它是简单的,专用的语言。
2、Hello Freemarker
1、导入jar包
<dependencies>
<!--导入freemarker-->
<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
<!--servlet-->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
2、在web.xml中注册FreemarkerServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--注册FreemarkerServlet-->
<servlet>
<servlet-name>freemarker</servlet-name>
<servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class>
<!--模板路径-->
<init-param>
<param-name>TemplatePath</param-name>
<!--默认扫描webapp下-->
<param-value>/</param-value>
</init-param>
<!--编码格式-->
<init-param>
<param-name>default_encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>freemarker</servlet-name>
<!--ftl是Freemarker的默认文件后缀-->
<url-pattern>*.ftl</url-pattern>
</servlet-mapping>
</web-app>
3、编写servlet
@WebServlet("/f1")
public class FreeServlet01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("msg", "Hello Freemarker");
req.getRequestDispatcher("/f01.ftl").forward(req, resp);
}
}
4、编写ftl
<#--
ftl文件中,html、css、js皆可用
-->
<h1>${msg}</h1>
3、数据类型
1、布尔类型
<#--
布尔类型:在Freemarker中,布尔类型不能直接输出到Freemarker页面上
如果想输出,有三种方式:
1、?c
2、?string,可以自定义true或false对应的输出
3、?then
-->
<h2>布尔类型</h2>
<#--<h3>${msg?c}</h3>-->
<#--<h3>${msg?string}</h3>-->
<#--<h3>${msg?string("喜欢","不喜欢")}</h3>-->
<h3>${msg?then("嘿嘿","哈啊哈")}</h3>
2、日期类型
<#--
日期类型,无法在Freemarker页面上直接输出,需要转换成字符串
?date:输出日期,2020-8-27
?time:输出时间,11:36:18
?datetime:输出日期时间,2020-8-27 11:36:50
?string:自定义格式
-->
<h2>日期类型</h2>
<#--<h3>${date?date}</h3>-->
<#--<h3>${date?time}</h3>-->
<#--<h3>${date?datetime}</h3>-->
<h3>${date?string("yyyy-MM-dd HH:mm:ss")}</h3>
3、数值类型
<h2>数值类型</h2>
<h3>${age}</h3>
<h3>${salary}</h3>
<h3>${num}</h3>
<#--将数值转换为字符串-->
<h3>${num?c}</h3>
<#--将数值转换为货币类型:¥20,000.00-->
<h3>${salary?string.currency}</h3>
<#--将数值转换为百分比:26%-->
<h3>${num?string.percent}</h3>
<#--保留指定小数位:0.26-->
<h3>${num?string("0.##")}</h3>
4、字符串类型
<h2>字符串类型</h2>
<#--截取字符串-->
<h3>${s1?substring(0,2)}</h3>
<#--首字母小写-->
<h3>${s2?uncap_first}</h3>
<#--首字母大写-->
<h3>${s1?cap_first}</h3>
<#--大写转小写-->
<h3>${s1?lower_case}</h3>
<#--小写转大写-->
<h3>${s2?upper_case}</h3>
<#--去除前后空格-->
<h3>${s1?trim}</h3>
<#--以什么开头,返回布尔值,不能直接输出-->
<h3>${s1?starts_with("He")?c}</h3>
<#--以什么结尾-->
<h3>${s1?ends_with("lo")?string}</h3>
<#--返回字串的索引-->
<h3>${s1?index_of("H")}</h3>
<#--替换-->
<h3>${s1?replace("He","We")}</h3>
5、null
<h2>空值的处理</h2>
<#--
在freemarker中,不存在的变量和null是一个概念
如果遇到空值,会报异常,所以我们需要对空值进行处理
有两种方式:
1、指定变量的默认值
aa!:如果aa为空,则默认为空字符串
aa!"值为空":如果aa为空,则默认为“值为空”
2、判断是否为空
aa??:判断aa是否为空,不为空返回true,为空返回false
-->
<h3>${aa!}</h3>
<h3>${aa!"值为空"}</h3>
<h3>${(aa??)?c}</h3>
6、sequence
<#--遍历数组-->
<#--
stars:表示要遍历的数组
star:数组元素
size:数组大小,不能用length,会报异常
first:第一个元素
last:最后一个元素
-->
<#list stars as star>
${star?index}、${star}<br/>
</#list>
${stars?size}
${stars?first}
${stars?last}
<#--获取某个具体的元素-->
${stars[1]}
<hr/>
<#--遍历list-->
<#--倒序输出-->
<#list list?reverse as li>
${li}<br/>
</#list>
<#--升序输出-->
<#list list?sort as li>
${li}<br/>
</#list>
<#--降序输出-->
<#list list?sort?reverse as li>
${li}<br/>
</#list>
<#--list存放的是pojo-->
<#list userList as user>
${user.name}----${user.age}<br/>
</#list>
<#--按年龄倒序-->
<#list userList?sort_by("age")?reverse as user>
${user.name}-----${user.age}<br/>
</#list>
<#--通过下标遍历-->
<#list 0..(list?size-1) as i>
${list[i]}
</#list>
7、Hash
<#--遍历hashmap-->
<#--
map?keys:代表所有的key
map?values:代表所有的value
map[key]:根据key获取value
-->
<#list map?keys as key>
${key}---${map[key]}<br>
</#list>
<#list map?values as value>
${value}--
</#list>
4、FreeMarker指令
1、assign指令
<#--
assign:用于定义变量
str:变量名
zs:值
-->
<#assign str="zs"/>
<#--定义数组-->
<#assign arr=["a","b","c"]/>
2、if…else if…else
<#--
if...else指令
lt:小于 lte:小于等于
gt:大于 gte:大于等于
=:等于
-->
<#assign score=90/>
<#if score lt 60>
<h4>不及格</h4>
<#elseif score gte 60 && score lt 70>
<h4>及格</h4>
<#elseif score gte 70 && score lt 80>
<h4>良好</h4>
<#elseif score gte 80 && score lt 90>
<h4>优秀</h4>
<#else>
<h4>完美</h4>
</#if>
<#--判断是否为空-->
<#assign list="">
<#if list??>
${list}
<#else>
<h4>数据不存在</h4>
</#if>
3、macro
<#--
macro指令:用于自定义指令,自定义指令可重复使用
-->
<#--定义指令-->
<#macro address>
xxx省xxx市xxxx县xxx村
</#macro>
<#--使用自定义指令,此处会显示自定义指令的内容-->
<@address/>
<#--定义带参数的指令-->
<#macro user name age>
姓名:${name}<br>
年龄:${age}
</#macro>
<#--使用-->
<@user name="张三" age=23/>
4、import和include
<#--
导入其它的ftl,可以将一些公共的代码
放在一个ftl文件中,比如我们自定义的指令,
这样就无需在每个页面都定义
-->
<#--使用com调用导入ftl里面自定义指令-->
<#import "commons.ftl" as com>
<@com.cfb num=5/>
<#--
包含指令
被包含的ftl的输出会显示在它被包含的位置,不会覆盖
我们当前的ftl的输出
-->
<#include "f01.ftl">
5、注意
freemarker页面只能通过 参 数 名 获 取 域 中 的 参 数 , 需 要 注 意 的 是 : 不 能 调 用 该 参 数 的 j a v a 方 法 , 比 如 我 向 r e q u e s t 域 中 存 入 一 个 L i s t 集 合 , 我 们 要 在 f r e e m a r k e r 页 面 获 取 它 的 第 二 个 元 素 , 不 能 使 用 {参数名}获取域中的参数,需要注意的是:不能调用该参数的java方法,比如我向request域中存入一个List集合,我们要在freemarker页面获取它的第二个元素,不能使用 参数名获取域中的参数,需要注意的是:不能调用该参数的java方法,比如我向request域中存入一个List集合,我们要在freemarker页面获取它的第二个元素,不能使用{list.get(1)}获取,而是通过${list[1]}获取。