FreeMarker笔记之基础知识

前言

FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具。简单比如来说,html作为只关心前台,无后台数据,而后台数据通过freemarker模板来定义数据,然后在html中取出数据

入门程序

不妨以一个hello world程序作为入门,然后在研究它
1.建立一个普通的java项目
2.引入freemarker.jar包
3.在项目目录下建立模板目录:templates
4.在templates目录下,建立一个xx.ftl文件,内容如下

hello,${msg}

5.然后建立一个测试类:

public static void main(String[] args) throws Exception {
//创建Freemarker配置实例
Configuration cfg = new Configuration();
cfg.setDirectoryForTemplateLoading(new File(“templates”));
//创建数据模型
Map root = new HashMap();
root.put(“msg”, “world”);
//加载模板文件
Template t1 = cfg.getTemplate(“a.ftl”);
//显示生成的数据,//将合并后的数据打印到控制台
Writer out = new OutputStreamWriter(System.out);
t1.process(root, out);
out.flush();
}

输出结果:
hello,world

if指令

不妨先看例子
测试类中添加如下语句
root.put(“random”, new Random().nextInt(100));

模板文件添加如下语句

if语句测试:

${msg}是<#if msg==”world”>is right</#if>

if else 语句测试:
<#if random gt 60>
及格!
<#else>
不及格!

</#if>

if else if else语句测试:
<#if random gte 90>
优秀!
<#elseif random gte 80>
良好!
<#else>
一般!
</#if>

随机输出结果:
if语句测试:

>world是is right

if else 语句测试:

及格!

if else if else语句测试:
优秀!

其中运用了比较运算符

  1. =(或者==): 判断两个值是否相等;
  2. !=: 判断两个值是否不相等;
    注: =和!=可以用作字符串、数值和日期的比较,但两边的数据类型必须相同。而且FreeMarker的比较是精确比较,不会忽略大小写及空格。
  3. (或者gt): 大于

  4. =(或者gte): 大于等于

  5. <(或者lt): 小于
  6. <=(或者lte): 小于等于
    注: 上面这些比较运算符可以用于数字和日期,但不能用于字符串。大部分时候,使用gt比>有更好的效果,因为FreeMarker会把>解释成标签的结束字符。可以使用括号来避免这种情况,如:<#if (x>y)>。

list指令

首先添加一个address类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Address {
private String country;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Address(String country, String city) {
super();
this.country = country;
this.city = city;
}
private String city;
}

然后测试类中添加如下语句

List list = new ArrayList();
list.add(new Address(“中国”,”北京”));
list.add(new Address(“中国”,”上海”));
list.add(new Address(“美国”,”纽约”));
root.put(“lst”, list);

模板文件添加如下

测试list指令:
<#list lst as temp >
${temp.country}

</#list>

include指令

在templates目录下随便写一个文件,比如tt.txt,里面目前只有test字符
模板文件增加如下:
<#include “tt.txt” />
将增加tt.txt里面的文本内容到该模板文件中

macro指令

该指令为宏指令,相当于定义函数和参数
第一个为函数名,后面为参数可有可无
如:

<#macro tt>
hello
world
</#macro>

引用<@tt />
输出结果
hello
world

定义待参宏指令

1
2
3
4
5
<#macro func a b>
${a},${b}
</#macro>
<@func a='hello' b='world'/>

输出结果为hello,world

nested指令
该指定是插入引入的内容到相应位置如:

1
2
3
4
5
6
7
<#macro border>
before
<#nested>
after
</#macro>
<@border >now</@border>

输出结果为
before now after

命名空间
当运行 FTL 模板时,就会有使用 assign 和 macro 指令创建的变量的集合,当引用不同的模板,就需要使用import指令
比如创建如下b.ftl

1
2
3
4
5
6
7
8
9
10
<#macro copyright date>
<p>Copyright (C) ${date} </p>
</#macro>
<#assign mail = "zwl">
在测试模板中
测试命名空间:
<#import "b.ftl" as bb />
<@bb.copyright date="2013-2017" />
${bb.mail}

数据类型

一、直接指定值
直接指定值可以是字符串、数值、布尔值、集合及Map对象。

  1. 字符串
    直接指定字符串值使用单引号或双引号限定。字符串中可以使用转义字符”\”。如果字符串内有大量的特殊字符,则可以在引号的前面加上一个字母r,则字符串内的所有字符都将直接输出。

  2. 数值
    数值可以直接输入,不需要引号。FreeMarker不支持科学计数法。

  3. 布尔值
    直接使用true或false,不使用引号。

  4. 集合
    集合用中括号包括,集合元素之间用逗号分隔。
    使用数字范围也可以表示一个数字集合,如1..5等同于集合[1, 2, 3, 4, 5];同样也可以用5..1来表示[5, 4, 3, 2, 1]。

  5. Map对象
    Map对象使用花括号包括,Map中的key-value对之间用冒号分隔,多组key-value对之间用逗号分隔。
    注意:Map对象的key和value都是表达式,但key必须是字符串

6.时间对象
如:root.put(“date1”, new Date());
输出:${date1?string(“yyyy-MM-dd HH:mm”)}
其中后面的为日期输出格式

  1. JAVABEAN的处理
    Freemarker中对于javabean的处理跟EL表达式一致,类型可自动转化

二、输出变量值
FreeMarker的表达式输出变量时,这些变量可以是顶层变量,也可以是Map对象的变量,还可以是集合中的变量,并可以使用点(.)语法来访问Java对象的属性。

  1. 顶层变量
    所谓顶层变量就是直接放在数据模型中的值。输出时直接用${variableName}即可

输出集合元素
可 以根据集合元素的索引来输出集合元素,索引用中括号包括。如: 输出[“1”, “2”, “3”]这个名为number的集合,可以用${number[0]}来输出第一个数字。FreeMarker还支持用number[1..2]来表示原 集合的子集合[“2”, “3”]。

  1. 输出Map元素
    对于JavaBean实例,FreeMarker一样把它看作属性为key,属性值为value的Map对象。
    输出Map对象时,可以使用点语法或中括号语法,如下面的几种写法的效果是一样的:

    book.author.name                                                                                book.author["name"]                                                                              book["author"].name                                                                            book["author"]["name"]                                            
    

    字符串操作

  2. 字符串连接
    直接使用+连接
    截取子串
    截取子串可以根据字符串的索引来进行,如果指定一个索引值,则取得字符串该索引处的字符;如果指定两个索引值,则截取两个索引中间的字符串子串。如:
    <#assign number="01234">
    ${number[0]} <#-- 输出字符0 -->
    ${number[0..3]} <#-- 输出子串“0123” -->
    

内建函数
FreeMarker提供了一些内建函数来转换输出,可以在任何变量后紧跟?,?后紧跟内建函数,就可以通过内建函数来转换输出变量。

字符串相关常用的内建函数:

  1. html: 对字符串进行HTML编码;
  2. cap_first: 使字符串第一个字母大写;
  3. lower_case: 将字符串转成小写;
  4. upper_case: 将字符串转成大写;

集合相关常用的内建函数:

  1. size: 获得集合中元素的个数;

数字值相关常用的内建函数:

  1. int: 取得数字的整数部分。

举例:
root.put(“htm2”, “粗体“);
内建函数:
${htm2?html}

其它类型
集合连接操作
Map连接操作
算术运算符
比较运算符
逻辑运算符
空值处理运算符

数据类型常见示例
直接指定值
 字符串 : “Foo”或 者’Foo’或”It’s \”quoted\””或r”C:\raw\string”
 数字:123.45
 布尔值:true, false
 序列:[“foo”, “bar”, 123.45], 1..100
 哈希表:{“name”:”green mouse”, “price”:150}
 检索变量  顶层变量:user
 从哈希表中检索数据:user.name, user[“name”]
 从序列中检索:products[5]
 特殊变量:.main
 字符串操作
 插值(或连接):”Hello ${user}!”(或”Free” + “Marker”)
 获取一个字符:name[0]
 序列操作
 连接:users + [“guest”]
 序列切分:products[10..19] 或 products[5..]
 哈希表操作
 连接:passwords + {“joe”:”secret42”}
 算数运算: (x * 1.5 + 10) / 2 - y % 100
 比 较 运 算 : x == y, x != y, x < y, x > y, x >= y, x <= y,
x < y, 等等
 逻辑操作:!registered && (firstVisit || fromEurope)
 内建函数:name?upper_case
 方法调用:repeat(“What”, 3)
 处理不存在的值
 默认值:name!”unknown” 或者(user.name)!”unknown” 或者
name! 或者 (user.name)!
 检测不存在的值:name?? 或者(user.name)??

热评文章