Freemarker学习笔记
Freemarker配置
在pom.xml中添加依赖jar包
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
添加jetty插件
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.1.v20140609</version>
</plugin>
</plugins>
在web.xml文件中添加以下内容
<!--FreeMarker的servlet配置-->
<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>
</servlet>
<servlet-mapping>
<!--处理所有以ftl结尾的文件,ftl是FreeMarker默认的文件后缀-->
<servlet-name>freemarker</servlet-name>
<url-pattern>*.ftl</url-pattern>
</servlet-mapping>
在ftl模板文件中,可以正常使用HTML,CSS和JS的代码
<!--这是Html格式的注释,在网页代码中可以看到 -->
<#--这是FreeMarker的注释,在网页代码中不可见-->
FreeMarker类型
布尔类型
<#--数据类型:布尔类型
在FreeMarker中布尔类型不能直接输出;如果输出要先转成字符串
方法一:?c
方法二:?string 或 ?string("true时的文本","false时的文本")
-->
${msg?c} <br>
${msg?string} <br>
${msg?string('yes','no')} <br>
日期类型
<#--
日期类型
1. 年月日 ?date
2. 时分秒 ?time
3. 年月日时分秒 ?datetime
4. 自定义格式 ?string("自定义")
y:年 M:月 d:日
H:时 m:分 s:秒
-->
<h4>日期类型</h4>
${date?date} <br>
${date?time} <br>
${date?datetime} <br>
${date?string("yyyy/MM/dd HH:mm:ss")}
数值类型
<#-- 在FreeMarker中数值类型可以直接输出
1.转字符串
普通字符串 ?c
货币型字符串 ?string.currency
百分比型字符串 ?string.percent
2.浮点型的数值转换成指定小数位输出(#表示小数位)
?string["0.##"]
-->
<h4>数值类型</h4>
${num} <br>
${avg} <br>
${age} <br>
${num?string.currency} <br>
${avg?string.percent} <br>
${avg?string["0.#"]} <br>
${num?c} <br>
字符串类型
字符串连接操作- +
eg:${str1 + str2}
获取字符串的长度- ?length
eg:${str1?length}
取第一次出现的索引- ?index_of()
eg:${str1?index_of('e')}
取最后一次出现的索引- ?last_index_of()
eg:${str1?last_index_of('e')}
字符串截取- ?substring()
eg:${str1?substring(0,2)}
字符串替换- ?replace()
eg:${str1?replace('o','dddd')}
字符串分割- ?split()
eg:<#list str1?split("_") as item>${item}</#list>
去掉前后的空格- ?trim
eg:${str1?length}-${str1?trim?length}
判断字符串是否包含指定的子字符串- ?contains()
eg:${str1?contains('llo')?c}
判断是否以给定的子字符串开头- ?starts_with()
eg:${str1?starts_with("Hel")?c}
判断是否以给定的子字符串结尾- ?ends_with()
eg:${str1?ends_with("oe")?c}
将字符串全部转换为大写- ?upper_case
eg:${str1?upper_case}
将字符串全部转换为小写- ?lower_case
eg:${str1?lower_case}
将字符串的首字母变大写- ?cap_first
eg:${str2?cap_first}
当字符串为空值时:
不存在的值 --报错
值为null --报错
${str!} 如果value的值不存在时,则默认显示空字符串
${str!"xxx"} 如果value的值不存在时,默认显示指定字符串
使用??,判断字符串是否为空;返回布尔类型。如果想要输出,需要将布尔类型转换成字符串
${(str??)?c} 或
${(str??)?string}
sequence类型
通过list指令输出序列
<# list 序列名 as 元素名>
${元素名}
</#list>
获取序列的长度 ${序列名?size}
获取序列元素的下标 ${序列名?index}
获取第一个元素 ${序列名?first}
获取最后一个元素 ${序列名?last}
倒序输出 序列名?reverse
升序输出 序列名?sort
降序输出 序列名?sort?reverse
指定字段名排序 序列名?sort_by("字段名")
注:一般是JavaBean集合,对应的字段名需要提供get方法
<#list stars as star>
${star.name} -- ${star.age} <br>
</#list>
<#list stars?sort_by("age") as star>
${star.name} -- ${star.age} <br>
</#list>
格式二:
<#list sequence as item>
<#else>
当没有选项时,执行else指令
</#list>
注意:
1.else部分是可选的
2.sequence为想要迭代的项,可以是序列或集合的表达式
3.item:循环变量的名称
4.当没有迭代项时,才是用else指令,可以输出一些特殊的内容而不只是空在那里
hash类型(map)
key遍历输出
<#list hash?keys as key>
${key} --- ${hash[key]}
</#list>
Value遍历输出
<#list hash?values as value>
${value}
</#list>
例如:
<#list CityMap?keys as key>
${key} --- ${CityMap[key]}
</#list>
FreeMarker常用指令
assign自定义变量指令
语法:
<#assign 变量名=值>
<#assign 变量名=值 变量名=值> (定义多个变量)
if,elseif,else逻辑判断指令
<#if num lt 60 >
小于60
<#elseif num == 60>
等于60
<#elseif num gt 60>
大于60
<#else>
没有分数
</#if>
lt等同于 < 小于
gt等同于 > 大于
lte等同于 <= 小于等于
gte等同于 >= 大于等于
macro 自定义指令(宏)
1. 基本使用
格式:
<#macro 指令名>
指令内容
</#macro>
使用: <@指令名></@指令名>
2.有参数的自定义指令
格式:
<#macro 指令名 参数名1 参数名2>
指令内容
</#macro>
使用:<@指令名 参数名1=参数值 参数名2=参数值></@指令名>
注意:1.指令可以被多次使用。
2.自定义指令里面可以包含字符串,也可以包括内置指令
3.nested 占位指令
nested相当于占位符,一般结合mmacro指令一起使用。
可以将自定义指令中的内容nested指令占位,当使用自定义指令时,会将占位内容显示。
<#macro test01>
这是一段话!
</#macro>
<@test01></@test01>
<hr>
<#macro test02>
<#list 1..9 as i>
<#list 1..i as j>
${i} * ${j} = ${i*j}
</#list>
<br>
</#list>
</#macro>
<@test02></@test02>
<hr>
<#macro test03 num>
<#list 1..num as i>
<#list 1..i as j>
${i} * ${j} = ${i*j}
</#list>
<br>
</#list>
</#macro>
<@test03 8></@test03>
<hr>
<#macro test04>
<#nested>
这是一段话!
<#nested>
</#macro>
<@test04>插入一句话!</@test04>
include包含指令
可以使用inlcude
指令在你的模板中插入另外一个FreeMarker模板文件。被包含模板的输出格式实在include标签出现的位置插入的,被包含的文件和包含他的模板共享变量,就像是被复制粘贴进去的一样。
插入html文件
<#include "test.html">
插入freemarker文件
<#include "f01.ftl">
插入text文件
<#include "1.txt">
插入的Freemarker文件中带有参数的指令也可以用,两个文件都是通用的
例如:
<#include "f01.ftl">
<@test03 num = 6></@test03>
Freemarker页面静态化
Java代码:
@WebServlet("/news")
public class NewsServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//实例化模板对象
Configuration configuration = new Configuration();
//获取模板的上下文和模板的路径
configuration.setServletContextForTemplateLoading(getServletContext(),"/template");
//设置模板的编码格式
configuration.setDefaultEncoding("UTF-8");
//加载模板文件,获取模板对象
Template template = configuration.getTemplate("news.ftl");
Map<String,Object> map = new HashMap<>();
map.put("title","这就是模板");
map.put("msg","内容就是这个");
//获取项目的根目录
String basepath = req.getServletContext().getRealPath("/");
//设置生成Html的文件路径
File htmlfile = new File(basepath+"/Html");
//判断是否生成了存放html的文件夹
if (!htmlfile.exists()){
//不存在则生成文件夹
htmlfile.mkdir();
}
//获取系统时间戳加后缀
String filename = System.currentTimeMillis()+".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();
}
}
}
模板:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" charset="utf-8">
</head>
<body>
<h1>${title}</h1> <br>
<msg>${msg}</msg> <br>
</body>
</html>