Freemarker notes | Freemarker学习笔记
2017-11-27 16:05
567 查看
Freemarker
应用场景
对比 JSP Freemarker Velocity
在java领域,表现层技术主要有三种:jsp、freemarker、velocity。JSP
jsp是大家最熟悉的技术优点:
1、功能强大,可以写java代码
2、支持jsp标签(jsp tag)
3、支持表达式语言(el)
4、官方标准,用户群广,丰富的第三方jsp标签库
5、性能良好。jsp编译成class文件执行,有很好的性能表现
缺点:
jsp没有明显缺点,非要挑点骨头那就是,由于可以编写java代码,如使用不当容易破坏mvc结构
Velocity
velocity是较早出现的用于代替jsp的模板语言优点:
1、不能编写java代码,可以实现严格的mvc分离
2、性能良好,据说比jsp性能还要好些
3、使用表达式语言,据说jsp的表达式语言就是学velocity的
缺点:
1、不是官方标准
2、用户群体和第三方标签库没有jsp多。
3、对jsp标签支持不够好
freemarker
优点:1、不能编写java代码,可以实现严格的mvc分离
2、性能非常不错
3、对jsp标签支持良好
4、内置大量常用功能,使用非常方便
5、宏定义(类似jsp标签)非常方便
6、使用表达式语言
缺点:
1、不是官方标准
2、用户群体和第三方标签库没有jsp多
选择freemarker的原因
1、性能。velocity应该是最好的,其次是jsp,普通的页面freemarker性能最差(虽然只是几毫秒到十几毫秒的差距)。但是在复杂页面上(包含大量判断、日期金额格式化)的页面上,freemarker的性能比使用tag和el的jsp好。2、宏定义比jsp tag方便
3、内置大量常用功能。比如html过滤,日期金额格式化等等,使用非常方便
4、支持jsp标签
5、可以实现严格的mvc分离
6、jsp和freeMarker是两种不同的技术,或者说不通的理念。
jsp需要访问的时候访问Dao层抓取数据,生成html页面,返给浏览器。
freeMarker则是提前根据模板生成好html的静态页面,这样在访问时,直接访问到的就是一个静态页面,这个就是效率问题了,不过freeMarker适合用变化不大,但是内容很多的网页。
7. 相比较FreeMarker而言,Velocity更加简单、轻量级,但它的功能却没有FreeMarker那么强大。
FreeMarker Introduction
FreeMarker是一款模板引擎,是一个Java类库,用来生成html页面把页面静态化。模板编写为FreeMarker Template Language(FTL)。
原理:模板页面=》解析标签和替换变量=》html页面
https://freemarker.apache.org/
2017-11-03 2.3.27
2016-06-26 2.3.25
2015-09-02 2.3.24-pre01 GNU=>Apache Incubation
http://fm-classic.sourceforge.net/
2004-06-15 2.2.8
2003-02-08 2.1.5
2002-06-12 2.0.3
1999-01-03 1.0
https://archive.apache.org/dist/incubator/freemarker/engine
Freemarker-2.3.25
Reference
Doc
https://freemarker.apache.org/docs/index.htmlhttps://sourceforge.net/projects/freemarker/files/chinese-manual/
Java API
https://freemarker.apache.org/docs/api/index.htmlhttps://freemarker.apache.org/docs/ref_directive_list.html
https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
FreeMarker模板开发指南
基本结构
插值:${...} interpolation(插值)。标签:预定义标签以#开头;用户自定义的FTL标签使用@来代替#。
注释: <#-- -->。不像HTML注释<!-- -->那样,FTL注释不会出现在访问者的页面中。
Note:
Anything not an FTL tag or an interpolation or comment is considered static text and will not be interpreted by FreeMarker; it is just printed to the output as-is.
FTL是区分大小写的。
预定义指令可以不要 # , 不建议这样用。
可以在FTL标签和FTL注释中, 使用 [ 和 ] 来代替 < 和 >。
表达式
直接指定值字符串:
"Foo"或者
'Foo'或者
"It's \"quoted\""或者
'It\'s "quoted"'或者
r"C:\raw\string"
数字:
123.45
布尔值:
true,
false
序列:
["foo", "bar", 123.45]; 值域:
0..9,
0..<10(或
0..!10),
0..
哈希表:
{"name":"green mouse", "price":150}
检索变量
顶层变量:
user
从哈希表中检索数据:
user.name,
user["name"]
从序列中检索数据:
products[5]
特殊变量:
.main
字符串操作
插值(或连接):
"Hello ${user}!"(或
"Hello " + user + "!")
获取一个字符:
name[0]
字符串切分: 包含结尾:
name[0..4],不包含结尾:
name[0..<5],基于长度(宽容处理):
name[0..*5],去除开头:
name[5..]
序列操作
连接:
users + ["guest"]
序列切分:包含结尾:
products[20..29], 不包含结尾:
products[20..<30],基于长度(宽容处理):
products[20..*10],去除开头:
products[20..]
哈希表操作
连接:
passwords + { "joe": "secret42" }
算术运算:
(x * 1.5 + 10) / 2 - y % 100
比较运算:
x == y,
x != y,
x < y,
x > y,
x >= y,
x <= y,
x lt y,
x lte y,
x gt y,
x gte y, 等等。。。。。。
逻辑操作:
!registered && (firstVisit || fromEurope)
内建函数:
name?upper_case,
path?ensure_starts_with('/')
方法调用:
repeat("What", 3)
处理不存在的值:
默认值:
name!"unknown"或者
(user.name)!"unknown"或者
name!或者
(user.name)!
检测不存在的值:
name??或者
(user.name)??
赋值操作:
=,
+=,
-=,
*=,
/=,
%=,
++,
--
Note:
原生字符串:在原生字符串中, 反斜杠和 ${ 没有特殊含义, 它们被视为普通的字符。在开始的引号或单引号之前放置字母r,${r"C:\foo\bar"}
科学记数法暂不支持使用 (1E3 就是错误的), 而且也不能在小数点之前不写0(.5 也是错误的)。
值域表达式:start..end,start..<end, start..!end, start..*length, start..
变量
子变量
用.(点)来访问空变量
FreeMarker不能引用不存在的变量,一个不存在的变量和一个是null值的变量,对于FreeMarker来说是一样的。
可以指定一个默认值来避免变量丢失,在变量名后面跟着一个 !(感叹号)和默认值: ${user!"visitor"}
可以在变量名后面通过放置??来询问一个变量是否存在
<#if user??>
<h1>Welcome ${user}!</h1>
</#if>
多级访问的变量
animals.python.price!0 vs. (animals.python.price)!0命名空间
通常来说,变量因为名称冲突时也会相互冲突。 所以要为每个库中的变量使用不同的命名空间。简单的情况下可以只使用一个命名空间,称之为 主命名空间。
import vs. include: <#import "/lib/my_test.ftl" as my>
Directives 指令|标签 介绍
if
<#if condition>...
<#elseif condition2>
...
<#elseif condition3>
...
<#else>
...
</#if>
list, items, sep,else
<#list misc.fruits>
<p>Fruits:
<ul>
<#items as fruit>
<li>${fruit}<#sep> and</#sep>
</#items>
</ul>
<#else>
<p>We have no fruits.
</#list>
include可以在模板中插入另外一个FreeMarker模板文件
<#include "/copyright_footer.html">
数值类型
标量scalars:string, number, boolean, date|time
字符串只是字符的任意序列,不能将它用于计算目的,也不能和其它数字进行比较等等。使用保留字 true 和 false 来指定布尔值。
受到Java平台的限制,FreeMarker 有时是不能决定日期的部哪分被使用。
FTL并没有独立的字符类型, 获取字符${user[0]}。
Containers: hash, sequence, collections
集合是有限制的序列。不能获取集合的大小, 也不能通过索引取出集合中的子变量,但是它们仍然可以通过list指令来遍历。
序列(集合)中的变量可以是任意类型的, 这些变量也可以是哈希表,序列(或集合)。
Built-ins 内建函数|方法
在数值上添加
animal.name?cap_first常见函数
user?html给出user的HTML转义版本,比如&会由&来代替。user?upper_case给出user值的大写版本(比如“JOHN DOE”来替代“John Doe”)
animal.name?cap_first给出animal.name的首字母大写版本(比如“Mouse”来替代“mouse”)
user?length给出user值中字符的数量(对于“John Doe”来说就是8)
animals?size给出animals序列中项目的个数
list内使用
<#list animals as animal>…</#list>l animal?index给出了在animals中基于0开始的animal的索引值
l animal?counter也像index,但是给出的是基于1的索引值
l animal?item_parity基于当前计数的奇偶性,给出字符串“odd”或“even”。在给不同行着色时非常有用,比如在<td class="${animal?item_parity}Row">中。
带参数的内建函数
l string: animal.protected?string("Y", "N")基于animal.protected的布尔值来返回字符串“Y”或“N”。l animal?item_cycle('lightRow','darkRow')是item_parity更为常用的变体形式。
l fruits?join(", ")通过连接所有项,将列表转换为字符串,在每个项之间插入参数分隔符(比如“orange,banana”)
l user?starts_with("J")根据user的首字母是否是“J”返回布尔值true或false。
内建函数应用可以链式操作
user?upper_case?html
Freemarker自定义标签Directives
自定义指令用 macro 指令来定义
<#macro name param1 param2 ... paramN>...
<#nested loopvar1, loopvar2, ..., loopvarN>
...
<#return>
...
</#macro>
Java实现
public class UpperDirective implements TemplateDirectiveModelFreemarker自定义函数Function
ftl定义:function, return
<#function name param1 param2 ... paramN>...
<#return returnValue>
...
</#function>
Java实现
public class IndexOfMethod implements TemplateMethodModelEx所有内建函数
字符串内建函数
字符串属性:length, index_of, last_index_of,字符串替换: replace, trim, cap_first, uncap_first, capitalize, chop_linebreak, keep_after, keep_after_last, keep_before, keep_before_last, left_pad, right_pad, lower_case, remove_beginning, remove_ending, ensure_ends_with, ensure_starts_with,
字符串判断:contains, starts_with, ends_with, boolean, matches, groups
字符串转换:split, word_list, number, date, time, datetime, string, url, url_path, html, xhtml, xml, j_string, js_string, json_string, rtf,
通用标志:i, f, r, m, s, c
支持使用这些通用标志的内建函数:replace, split, matches, keep_after, keep_after_last, keep_before, keep_before_last, ensure_starts_with
数字内建函数
abs, string, round, floor, ceiling, c,is_infinite,is_nan,lower_abc, upper_abc,日期内建函数
string, date, time, datetime, date_if_unknown, time_if_unknown, datetime_if_unknown, iso_...(iso_utc, iso_local, …)${openingTime?string["yyyy-MM-dd hh:mm:ss a"]}
布尔值内建函数
then, c, string三元运算符: booleanExp?then(whenTrue, whenFalse)
序列内建函数
size, seq_contains, seq_index_of, seq_last_index_of, sort, sort_by, join, chunk, first, last, reverse,哈希表内建函数
keys, valuesXML结点内建函数
ancestors, children, node_name, node_namespace, node_type, parent, root循环变量内建函数
counter, has_next, index, is_even_item, is_first, is_last, is_odd_item, item_cycle, item_parity, item_parity_cap这些内建函数只能用于list 和 items 指令 的循环变量 (也可以用于已经废弃的 foreach 指令)。
Type independent built-ins
switch
priority?switch(1, "low", 2, "medium", 3, "high"),或者是 true?switch(priority <= 1, "low", priority == 2, "medium", priority >= 3, "high")。
很少使用的和专家级的内建函数
has_content, is_...(is_sring, is_number, is_date_like, is_time, is_datetime, …), eval,byte, double, float, int, long, short
number_to_date, number_to_time, number_to_datetime
所有指令: <#xxx …>…</#xxx>, <#xxx…>,
l assign, global, local, settingl import, include
l if, else, elseif
l list, else, items, sep, break
l switch, case, default, break
l attempt, recover
l visit, recurse, fallback: xml
l escape, noescape
l function, return
l macro, nested, return
l compress
l flush
l ftl
l noparse, stop
l nt, t, lt, rt
l User-defined directive (<@...>)
FTL 中的保留名称
true:布尔值"true"false:布尔值"false"
gt:比较运算符"大于"
gte:比较运算符"大于或等于"
lt:比较运算符"小于"
lte:比较运算符"小于或等于"
as:由少数指令使用
in:由少数指令使用
using:由少数指令使用
程序开发指南
开发步骤
创建 Configuration 实例创建数据模型
获取模板
合并模板和数据模型
Configuration
配置(configuration)就是 freemarker.template.Configuration 对象, 它存储了常用(全局,应用程序级)的设置,定义了想要在所有模板中可用的变量(称为共享变量)。应用程序典型的用法是使用一个独立的共享 Configuration 实例。
Shared variables
Settings
相关文章推荐
- Freemarker学习笔记
- Freemarker学习笔记
- FreeMarker学习笔记
- freemarker学习笔记_宏和自定义函数
- FreeMarker系列学习笔记(1)
- 【学习笔记】spring boot + zookeeper + dubbo + rabbitMq + mysql + thymeleaf/freemarker + mybaits 代码试验
- Freemarker学习笔记
- Freemarker 学习笔记一Freemarker 的介绍以及创建步骤
- 开源jeecms,jeebbs学习笔记1——freemarker
- FreeMarker系列学习笔记(2)
- FreeMarker 学习笔记
- 开源jeebbs学习笔记1——freemarker
- FreeMarker系列学习笔记(3)——sturts2 result type为 freemarker
- 【学习笔记】初识FreeMarker简单使用
- JAVA学习笔记28——网页静态化之Freemarker(二)
- FreeMarker学习笔记
- 整理一下当年的学习笔记之:初步学习freemarker ,先做一个简单的HelloWord程序!
- FreeMarker学习笔记
- SpringBoot学习笔记之JSP与freemarker支持
- FreeMarker系列学习笔记(2)