一.概念:一款模板引擎,一种基于模板和要改变的数据,用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具,属于Java类库。
二. 初衷是用来生成HTML WEB 页面, 特别是基于MVC模式的应用程序,将视图从业务逻辑中抽离处理,业务中不再包括视图的展示,而是将视图交给FreeMarker来输出。FreeMarker不是Web应用框架,而是web应用框架的一个组件。
三.
-新建Maven Web项目
-配置坐标依赖和部署插件
junit junit 4.11 test javax.servlet javax.servlet-api 3.1.0 org.freemarker freemarker 2.3.23
-修改配置文件 web.xml , 添加freemarker相关的servlet配置
securityannotation index.jsp freemarker freemarker.ext.servlet.FreemarkerServlet TemplatePath / default_encoding UTF-8 freemarker *.ftl
-编写Servlet类
-新建模板文件ftl
-启动项目
-访问项目
四,
-FreeMarker数据类型:
1.布尔型: 等价于Boolean,但是不能直接输出,可转换为字符串输出。
2.日期型: 等价于Date,不能直接输出,需转换成字符串输出。
3.数值型:等价于 int, float, double 等数值类型,有三种显示形式:数值型,货币型,百分比型
4.字符型: 等价于java 中的字符串。
5.sequence类型: 等价于数组, list,set等集合类型。
6.hash类型: 等价于Map类型。
-设置数据:
布尔型:
request.setAtttribute(“flag”,true);
日期型:
request.setAttribute("Today",new Date());
数值型:
request.setAttribute("age",18);
request.setAttribute("salary",20800.5445);
字符串类型:
request.setAttribute("MyString"," FreeMarker Test");
序列类型(set,list,数组):
String [] MusicArray = new String[]{"一路向北","不能说的秘密","枫","稻香"};
List AddressLists = new ArrayList<>();
AddressLists.add("广州");
AddressLists.add("深圳");
AddressLists.add("北京");
AddressLists.add("上海");
AddressLists.add("南京");
List AuthorLists = new ArrayList<> (); //Bean类型
AuthorLists.add(new User("周杰伦",18));
AuthorLists.add(new User("薛之谦",28));
AuthorLists.add(new User("王嘉尔",20));
AuthorLists.add(new User("Adel",26));
AuthorLists.add(new User("叶聪明",19));
request.setAttribute("MusicArray",MusicArray);
request.setAttribute("AddressLists",AddressLists);
request.setAttribute("AuthorLists",AuthorLists);
hash类型:
Map CityMap = new HashMap<>();
CityMap.put("ShangHai","上海");
CityMap.put("PeKing","北京");
CityMap.put("ShenZhen","深圳");
CityMap.put("GuangZhou","广州");
CityMap.put("XiaMen","厦门");
request.setAttribute("CityMap",CityMap);
-获取数据:
布尔型:
${flag?c}
${flag?string}
${flag?string(“yes”,“no”)} (已废弃)
${flag?then(“勇往直前!”,“回头是岸!”)}
日期型:
${Today?datetime} //年月日时分秒
${Today?date} //年月日
${Today?string("yyyy年mm月dd日 HH:mm:ss")} //自定义格式
数值类型:
${avg?c}
${avg?string.percent}
${avg?string.currency}
${avg?string["0.##"]} //几个“#”号,就代表保留几位小数
字符串型:
${MyString?substring(0,3)}
截取字符串,左闭右开
${MyString?uncap_first}
首字母小写输出
${MyString?cap_first}
首字母大写输出
${MyString?lower_case}
小写输出
${MyString?upper_case}
大写输出
${MyString?length}
字符串长度
${MyString?starts_with("Free")?string("Start with FreeMarker","Not start with FreeMarker")} 是否以指定字符开头(boolean类型)
${MyString?ends_with("Marker")?string("Ends with FreeMarker","Not Ends with Marker")} 是否以指定字符结尾(boolean类型)
${MyString?index_of("Mar")}
获取指定字符的索引
${MyString?trim}
去除字符串前后空格
${MyString?replace("Free","Vodka")}
替换指定字符串
空值类型:
不存在的值会直接报错,FreeMarker无法辨别null值,空字符串可以进行判断
${NullValue!} !:指定确实变量的默认值
${NullValue!"This string is empty!"} 判断变量是否存在,不存在则输出默认语句
${(NullValue??)?string("Not empty!","Empty!")} ??: 判断字符串是否为空,返回布尔类型,若要输出,需要将布尔类型转换成字符串
序列类型(数组,List,Set):
通过 list 指令输出序列:
<#list 序列名 as 元素名>
${元素名}
#list>
${序列名?size} 获取序列长度
${元素名?index} 获取序列元素下标
${序列名?first} 获取第一个元素
${序列名?last} 获取最后一个元素
<#list 序列名?reverse as 元素名>
${元素名}
#list>} 倒序输出
<#list 序列名?sort as 元素名>
${元素名}
#list>} 升序输出
<#list 序列名?sort?reverse as 元素名>
${元素名}
#list>} 降序输出
若是要根据Bean的某个元素进行排序,就得用函数 sort_by("age") ;
Hash 类型:
key 遍历输出:
<#list hash?keys as key>
${key} --- ${hash[key]}
value 遍历输出:
<#list hash?values as value>
${value}
五, FreeMarker常见指令
1. assign: 自定义变量指令,可以用该指令创建一个新的变量,或者替换一个已经存在的变量。(单双标签均可)
<#assign 变量名=值>
<#assign 变量名=值 变量名=值> (定义多个变量)
2.if elseif else 逻辑判断指令:
<# if condition>
...
....
.....
<#else>
...
#if>
(gt: greater than , lt : less than )
例子: 判断数据是否存在
<#if MyLists??>
数据存在
<#else>
数据不存在
#if>
3.用 macro 指令自定义一些指令,自定义指令可以包含字符串,也可以包含内置指令:
1.基本使用:
定义:
<#macro 指令名>
指令内容
#macro>
使用:
<@指令名>@指令名>
2.有参数的自定义指令
定义:
<#macro 指令名 参数一 参数二>
指令内容
#macro>
使用:
<@指令名 参数一=赋值一 参数二=赋值二>@指令名>
例子:
<#macro QueryUser (UserName , Age)>
选手: --- ${UserName}
年龄: --- ${Age}
#macro>
<@QueryUser UserName='Vodka' Age = 18>@QueryUser>
--------------------------------------------------------------------------------
<#--打印九九乘法表-->
<#macro MultiplicationTable (NumSequence)>
<#if NumSequence??>
数列存在,并打印相应乘法表:
<#list 1..NumSequence as i>
<#list 1..i as j>
${j} * ${i} = ${i*j}
#list>
#list>
#if>
#macro>
<@MultiplicationTable NumSequence=10>@MultiplicationTable>
4.nested 占位指令:该指令用于执行自定义指令开始和结束标签中间的模板片段,嵌套的片段可以包含模板中任意合法的内容
,即 nested 相当于占位符,一般结合 macro 指令一起使用,将nested 指令置于 macro 指令中,在调用macro 指令时,可以填充 nested 指令所占用的文本域。
<#macro test>
这是一段文本
<#nested>
<#nested>
#macro>
<@test>
5.import 导入指令:
-引入一个库,即创建一个新的命名空间,然后在那个命名空间中执行给定的路径模板,可以引入空间中的指令。
例如,创建一个公共的指令文件 commons.ftl , 里面有各种各样的自定义指令和组合指令,要使用的时候调用即 可。
<#import “commons.ftl” as common> //引入指令
<@common.Multiplication>/@common.Multiplication //使用指令
6.include 指令:
该指令用于在当前模板中,插入另一个已存在的FreeMarker 模板文件,被包含模板的输出格式是在 include 标签出现的位置插入,被包含的文件和包含的模板共享变量。
<#include “test.html”>
<#include “test.txt”>
<#include “test.ftl”>
7.函数指令:
定义:
<#function AVG x y>
<#return (x+y) / 2>
#function>
使用:
${ AVG(10,20) }
8.swit,case,break等等。
9.FreeMarker 页面静态化:
FreeMarker是一种基于模板,用来生成输出文本的通用工具,所以要制定符合自己业务的模板,生成专属页面。Freemarker是通过 freemarker.template.Configuration 对象(在整个应用中保证是唯一实例)进行模板加载(处理创建和缓存解析),用户再通过 getTemplate方法获得想要的模板。
步骤:
一,创建模板: 例如 , MyTemplate.ftl;
二,获取模板对象:
1.实例化模板对象:
Configuration cfg = new Configuration();
2.设置加载模板的上下文,以及加载模板的路径 (模板存放路径)
cfg.setServletContestForTemplateLoading(getServletContext() , “/template”);
3.设置模板编码格式
cfg.setDefaultEncoding(“UTF-8”);
4.加载模板文件 ,获取模板对象:
Template template = cfg.getTemplate(“MyTemplate.ftl”);
三,设置数据模型(可以是任意数据类型):
Map
MyMap.put(“title”,“XXXXX”);
MyMap.put(“name”,“XXXXX”);
MyMap.put(“content”,“XXXXX”);
四,生成html
1.获取项目的根目录:
String basePath = request.getServletContext().getRealPath("/");
2.设置即将生成的html的存放路径:
File htmlFile = new File(basePath + “/html”);
3.判断 目录是否已经存在
if(!htmlFile.exists()){
htmlFIle.mkdir();
}
4.得到生成文件名(唯一的文件名)
String fileName = System.currentTimeMillis() + “.html”;
5.创建html文件
File file = new File(htmlFile ,fileName);
6.获取文件输出流:
FileWriter writer = new FileWriter(file);
7.生成:
template.process(MyMap,writer);
writer.flush();
writer.close();
10.算术运算符:自行查阅文档



