文章目录
- 1. 介绍
- 2.FreeMarker环境搭建(maven版本)
- 3. 语法
- 3.1 freemarker的数据类型
- 3.1.1 布尔类型
- 3.1.2 日期类型
- 3.1.3 数值类型
- 3.1.4 字符串类型
- 3.1.5 字符串空值情况处理
- 3.1.6 sequence类型
- 3.1.7 hash类型
- 3.2 freemarker常见指令
- 3.2.1 asign指令
- 3.2.2 if elseif else指令
- 3.2.3 list遍历
- 3.2.4 macro宏定义
- 3.2.5 nested 占位指令
- 3.2.6 import导入指令
- 3.2.7 include包含指令
- 3.3 freemarker页面静态化
- 3.3.1 定义模板
- 3.4 FreeMarker运算符
- 3.4.1 算数运算符
- 3.4.2 逻辑运算符
- 3.4.3 比较运算符
- 3.4.4 空值运算符
FreeMarker视频教程
1. 介绍
FreeMarker 是一款
模板引擎
: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。模板编写为FreeMarker Template Language (FTL)。它是简单的,专用的语言, 不是 像PHP那样成熟的编程语言。 那就意味着要准备数据在真实编程语言中来显示,比如数据库查询和业务运算, 之后模板显示已经准备好的数据。在模板中,你可以专注于如何展现数据, 而在模板之外可以专注于要展示什么数据。
这种方式通常被称为
MVC (模型 视图 控制器)
模式,对于动态网页来说,是一种特别流行的模式。 它帮助从开发人员(Java 程序员)中分离出网页设计师(HTML设计师)。设计师无需面对模板中的复杂逻辑, 在没有程序员来修改或重新编译代码时,也可以修改页面的样式。
而FreeMarker最初的设计,是被用来在MVC模式的Web开发框架中生成HTML页面的,它没有被绑定到 Servlet或HTML或任意Web相关的东西上。它也可以用于非Web应用环境中。FreeMarker 不是一个Web应用框架,而适合作为Web应用框架一个组件
FreeMarker与容器无关,因为他并不直到HTTP或Servlet。FreeMarker同样可以应用于非Web应用程序环境。
FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以再模板中使用JSP标记库。ftl文件不能通过浏览器直接访问到,必须通过java代码进行访问,不然不能够解析里面的表达式
2.FreeMarker环境搭建(maven版本)
- 引入pom依赖
<!--freemarker坐标依赖-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
<!--servlet-api坐标依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
- 使用jetty启动,配置jetty插件(
版本很重要,不知道为啥其他版本启动后不能访问
)
<!--配置jetty插件-->
<plugins>
<!--配置jetty插件,默认端口8080-->
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.1.v20140609</version>
</plugin>
</plugins>
- 配置web.xml
<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>
<!--模板默认的编码UTF-8-->
<param-name>default_encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</servlet>
<!--处理所有以.ftl结尾的插件;ftl是freemarker默认的文件后缀-->
<servlet-mapping>
<servlet-name>freemarker</servlet-name>
<url-pattern>*.ftl</url-pattern>
</servlet-mapping>
- 配置jetty启动
<#-- ftl注释,浏览器中无法看到 -->
<!-- html注释,浏览器中可以看到-->
3. 语法
freemarker的语法:
- html中所有的标签都适用
- js与css的使用,与html中语法一致
3.1 freemarker的数据类型
3.1.1 布尔类型
在servlet中设置布尔类型的数据
req.setAttribute("flag", true);
${flag?c}
${flag?string}
${flag?string('yes','no')}
3.1.2 日期类型
在servlet中设置时间的数据
req.setAttribute("createDate", new Date());
- 年月日
?date
- 时分秒
?time
- 年月日时分秒
?datetime
- 指定格式
?sting("自定义格式")
y:年, M:月, d:日
H:时, m:分, s:秒
<#–输出日期格式–>
${createDate?date}
<#–输出时间格式–>
${createDate?time}
<#–输出日期时间格式–>
${createDate?datetime}
<#–输出格式化日期–>
${createDate?string(“yyyy年MM月dd日 HH:mm:ss”)}
3.1.3 数值类型
在servlet中设置数值类型
//数值类型 req.setAttribute("age",18);//数值型 req.setAttribute("avg",0.545);//浮点型
- 转字符串
1.1 普通字符串?c
1.2 货币性字符串?string.currency
1.3 百分比型字符串?string.percent
- 保留浮点型数值指定小数位(#表示一个小数位)
?string["0.##"]
<#–直接输出数值型–>
${age}
${avg}
<#–将数值转换成字符串输出–>
${age?c}
<#–将数值转换成货币类型字符串输出–>
${age?string.currency}
<#–百分比型字符串输出–>
${age?string.percent}
<#–保留浮点型数值指定小数位(#表示一个小数位) ---->
${avg?string[“0.##”]}
3.1.4 字符串类型
在servlet中设置字符串类型数据
req.setAttribute("msg","hello"); req.setAttribute("msg2","freemarker");
- 直接输出
- 截取字符串(左闭右开)
?substring(start,end)
- 首字母小写输出
?uncap_first
- 首字母大写输出
?cap_first
- 字母转小写输出
?lower_case
- 字母转大写输出
?upper_case
- 是否以指定字符开头(boolean类型)
?starts_with("xx")?string
- 是否已指定字符结尾(boolean类型)
?ends_with("xx")?string
- 获取指定字符的索引
?index_of("xx")
- 去除字符串前后空格
?trim
- 替换指定字符串
?replace("xx","bb")
3.1.5 字符串空值情况处理
在servlet中设置空值类型
//空值类型 req.setAttribute("bb",null);
FreeMarker 的变量必须赋值,否则就会抛出异常。而对于FreeMarker来说,
null
和不存在
的变量是完全一样的,因为FreeMarker无法理解null值
FreeMarker提供两个运算符来避免控制;
①!
: 指定缺失变量的默认值
${value!}: 如果value值为空,则默认值是空字符串
${value!“默认值”}: 如果value值为空,则默认值是字符“默认值”
②??
: 判断变量是否存在
如果变量存在, 返回true,否则返回false
${(value??)?string}
3.1.6 sequence类型
在servlet中设置系列类型
//序列类型(数组,list,set) //数组操作 String[] stars=new String[]{"周杰伦","林俊杰","陈奕迅","五月天"}; req.setAttribute("stars",stars); //List操作 List<String> listStars = Arrays.asList("周杰伦", "林俊杰", "陈奕迅", "五月天"); req.setAttribute("listStars",listStars); //JavaBean集合 ArrayList<User> users = new ArrayList<>(); users.add(new User(2,"lisi",22)); users.add(new User(1,"zhangsan",22)); users.add(new User(3,"wangwu",30));
<#list 系列名 as 元素名>
${名称}
</#list>
①获取系列的长度${序列名?size}
②获取系列元素的下标${元素名?index}
③获取第一个元素${序列名?first}
④获取最后一个元素${序列名?last}
⑤倒序
输出序列名?sort
⑥升序输出序列名?sort?reverse
⑦降序
输出序列名?sort_by("字段名")
⑧指定字段名排序
注:一般是javabean集合,对应的字段名需要提供get方法
3.1.7 hash类型
在servlet中设置hash类型
//hash类型(map) HashMap<String, String> cityMap = new HashMap<>(); cityMap.put("sh","上海"); cityMap.put("bj","北京"); cityMap.put("sz","深圳"); req.setAttribute("cityMap",cityMap);
<#--key遍历输出-->
<#list hash?keys as key>
${key} -- ${hash[key]}
</#list>
<#--value遍历输出-->
<#list hash?values as value>
${value}
</#list>
3.2 freemarker常见指令
3.2.1 asign指令
定义多个/单个变量
<#assign name="chen" age=18 seq = ["foo", "bar", "baz"]>
<#–使用变量–>${name}<br/>
3.2.2 if elseif else指令
<#if condition>
...
<#elseif condition2>
...
<#elseif condidion3>
...
<#else>
</#if>
注:`1.condition,condidtion2等;将被计算成布尔值的表达式
2.elseif和else指令时可选的
`
<#assign score=800>
<#--小于等于-->
<#if score lte 60>
小于60
<#elseif score lt 80 && score gt 60>
60-80中间
<#elseif score lte 100 && score gte 60>
大于等于80
<#else>
大于100
</#if>
3.2.3 list遍历
<#list sequence as item>
Part repeated for each item
<#else>
Part executed when there are 0 items
</#list>
注意:
1.else是可选的,去掉else和序列遍历无区别
2.sequence:想要迭代的项,可以是系列或结合的表达式
3.item:循环变量的名称
4.当没有迭代选项时,才使用else指令,可以输出一些特殊扥鹅绒而不是知识空再那里
<#assign seq2 = ["foo", "bar", "baz"]>
<#list seq2 as s>
${s}<br/>
<#else>
空了
</#list>
3.2.4 macro宏定义
1.定义
<#macro 指令名>
指令内容
</#macro>
使用:<@指令名></@指令名>
2.定义(含参数)
<#macro 指令名 参数一 参数二>
指令内容
</#macro>
使用:<@指令名 参数一=xxx 参数二=mmm></@指令名>
注意:
1.指令可以被多次使用
2.自定义指令中可以包含字符串,也可以包含内置指令
<hr/>
<#--宏定义-->
<#macro welcom>
hello world<br/>
</#macro>
<@welcom></@welcom>
<@welcom></@welcom>
<#macro welcome2 username>
hello world:${username}<br/>
</#macro>
<@welcome2 username="张三"></@welcome2>
3.2.5 nested 占位指令
nested 指令执行
自定义指令
开始和结束标签中间的模板片段。 嵌套的片段可以包含模板中任意合法的内容:插值,指令等…它在上下文环境中被执行, 也就是宏被调用
的地方,而不是宏定义体的上下文中。因此,比如, 你不能看到嵌套部分的宏的局部变量。如果你没有调用 nested 指令, 自定义指令开始和结束标记中的部分将会被忽略
(自己输入的内容将被忽略)。
<#macro name param1 param2 ... paramN>
<#nested loopvar1, loopvar2, ..., loopvarN>
</#macro>
3.2.6 import导入指令
引入一个库。也就是说,它创建一个新的空命名空间, 然后在那个命名空间中执行给定 path 参数中的模板, 所以模板用变量(
宏,函数
等)填充命名空间。 然后使得新创建的命名空间对哈希表的调用者可用。 这个哈希表变量将会在命名空间中,由 import (就像你可以用 assign 指令来创建一样。) 的调用者被创建成一个普通变量,名字就是 hash 参数给定的。
如果你用同一个 path 多次调用 import,它会创建命名空间, 但是只运行第一次 import 的调用。 后面的调用仅仅创建一个哈希表变量,你只是通过它来访问 同一个 命名空间。
<#import path as hash>
eg:
<#import "/libs/mylib.ftl" as my>
<@my.copyright date="1999-2002"/>
3.2.7 include包含指令
include可以使用它在你的模板中插入另外一个 FreeMarker 模板文件 (由 path 参数指定)。 被包含模板的输出格式是在 include 标签出现的位置插入的。 被包含的文件和包含它的模板共享变量,就像是被
复制粘贴
进去的一样。
<#--包含指令(引入其他页面文件)-->
<#--html文件-->
<#include "../index.html">
<#--ftl文件-->
<#include "./f03.ftl">
<#--txt文件-->
<#include "./test.txt">
3.3 freemarker页面静态化
通过freemarker将数据库的数据合并到html中,再次访问,不至于再次访问数据库.
3.3.1 定义模板
<h1>${title}</h1>
<p>${content}</p>
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
//实例化模板对象
Configuration configuration = new Configuration();
//设置加载模板的上下文,以及加载模板的路径(模板存放路径)
configuration.setServletContextForTemplateLoading(req.getServletContext(),"/template");
//设置模板的编码格式
configuration.setDefaultEncoding("UTF-8");
//加载模板文件,获取模板对象
Template template = configuration.getTemplate("f04.ftl");
//设置数据类型
HashMap<String, String> map = new HashMap<>();
map.put("title","新闻标题");
map.put("source","新闻来源");
map.put("pubTime","发布时间");
map.put("content","新闻内容");
//获取项目的根目录
String realPath = req.getServletContext().getRealPath("");
//设置html的存放路径
File htmlFile = new File(realPath + "/html");
if (!htmlFile.exists()) {
htmlFile.mkdir();
}
// String fileName = UUID.randomUUID() + ".html";
String fileName = "1.html";
// FileWriter fileWriter = new Out(new File(htmlFile , fileName));
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(new File(htmlFile, fileName)), "UTF-8");
//生成html(将数据填充到模板中)
template.process(map,outputStreamWriter);
}
3.4 FreeMarker运算符
3.4.1 算数运算符
${a1}+${a2}=${a1 + a2 }<br/>
${a1}-${a2}=${a1 - a2 }<br/>
${a1}*${a2}=${a1 * a2 }<br/>
${a1}/${a2}=${a1 / a2 }<br/>
${a1}%${a2}=${a1 % a2 }<br/>
<!--字符串运算-->
${"hello" + "hello2" }<br/>
3.4.2 逻辑运算符
&& || !
3.4.3 比较运算符
> (gt):大于,推荐使用gt
< (lt)
>= (gte)
<= (lt3)
==
!=
3.4.4 空值运算符
①
!
: 指定缺失变量的默认值
${value!}: 如果value值为空,则默认值是空字符串
${value!“默认值”}: 如果value值为空,则默认值是字符“默认值”
②??
: 判断变量是否存在
如果变量存在, 返回true,否则返回false
${(value??)?string}