Freemarker知识概括

253 阅读7分钟

@TOC

简介

Freemarke简介:

  • FreeMarker 是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯 Java 编写,FreeMarker 被设计用来生成HTML Web 页面,特别是基于 MVC 模式的应用程序,虽然 FreeMarker 具有一些编程的能力,但通常由 Java程序准备要显示的数据,由FreeMarker 生成页面,通过模板显示准备的数据。在这里插入图片描述
  • FreeMarker 不是一个 Web 应用框架,而适合作为 Web 应用框架一个组件。FreeMarker 与容器无关,因为它并不知道 HTTP 或 Servlet;FreeMarker 同样可以应用于非Web应用程序环境,FreeMarker 更适合作为 Model2 框架(如 Struts)的视图组件,你也可以在模板中使用 JSP标记库。另外,FreeMarker是免费的。
  • 应用场景: 比较适合运用在访问量大(或页面数据量大),但是数据很少与后台进行交互(即对实时性要求不是很高的)的页面,比如商品网站上的商品详情页等。

入门Demo

前期准备:

  • 要想使用freemarker,首先必须要有freemarker的jar包,这个互联网上随处可以下载,这边就不多说
<dependency>
<groupId>freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.9</version>
</dependency>

入门demo:

  • (1)创建一个testFreemarker类
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;
 
/**
 - @作者:JackHisen(GWD)
 - @项目名:freemarker
 - @时间:2017-7-25 下午2:39:45
 - @version 1.0
 */
public class testFreemarker {
	public static void main(String[] args) throws Exception {
		String dir="H:\\Java-EE Workspace\\freemarker\\src\\com\\gwd\\freemarker";
		Configuration conf = new Configuration();
		//加载模板文件(模板的路径)
		conf.setDirectoryForTemplateLoading(new File(dir));
		// 加载模板
		Template template = conf.getTemplate("/freemarker-demo.ftl");
		// 定义数据
		
		Map root = new HashMap();
                root.put("world", "Hello World");
		// 定义输出
		Writer out = new FileWriter(dir + "/freemarker.html");
		template.process(root, out);
		System.out.println("转换成功");
		out.flush();
		out.close();
	}
}

项目目录如下,其中freemarker.html文件是运行main函数后自动生成的,freemarker-demo.ftl为模板 在这里插入图片描述

  • (2)freemarker模板中写入内容在这里插入图片描述
  • (3)生成的html页面:在这里插入图片描述

其他数据类型

1.实体bean:

  • (1)创建Person类
public class Person {
	private int id;
	private String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}
  • (2)testFreemarker
public class testFreemarker {
	public static void main(String[] args) throws Exception {
		String dir="H:\\Java-EE Workspace\\freemarker\\src\\com\\gwd\\freemarker";
		Configuration conf = new Configuration();
		//加载模板文件(模板的路径)
		conf.setDirectoryForTemplateLoading(new File(dir));
		// 加载模板
		Template template = conf.getTemplate("/freemarker-demo.ftl");
		// 定义数据
		
		Person person=new Person();
		person.setId(1);
		person.setName("小明");
		Map root = new HashMap();
		root.put("person", person);
		// 定义输出
		Writer out = new FileWriter(dir + "/freemarker.html");
		template.process(root, out);
		System.out.println("转换成功");
		out.flush();
		out.close();
	}
}
  • (3)Freemarker模板
${person.id}
${person.name}
  • (4)生成的html页面 在这里插入图片描述

2.List集合:

  • (1)testFreemarker
public class testFreemarker {
	public static void main(String[] args) throws Exception {
		String dir="H:\\Java-EE Workspace\\freemarker\\src\\com\\gwd\\freemarker";
		Configuration conf = new Configuration();
		//加载模板文件(模板的路径)
		conf.setDirectoryForTemplateLoading(new File(dir));
		// 加载模板
		Template template = conf.getTemplate("/freemarker-demo.ftl");
		// 定义数据
		
		Person p1=new Person();
		p1.setId(1);
		p1.setName("小明");
		Person p2=new Person();
		p2.setId(2);
		p2.setName("小华");
		List<Person> person=new ArrayList<Person>();
		person.add(p1);
		person.add(p2);
		Map root = new HashMap();
		root.put("person", person);
		// 定义输出
		Writer out = new FileWriter(dir + "/freemarker.html");
		template.process(root, out);
		System.out.println("转换成功");
		out.flush();
		out.close();
	}
}
  • (2)模板
<#list person as p>
${p.id}/${p.name}
</#list>
  • (3)生成的html文件在这里插入图片描述

3.Map集合:

  • 1.testFreemarker
public class testFreemarker {
	public static void main(String[] args) throws Exception {
		String dir="H:\\Java-EE Workspace\\freemarker\\src\\com\\gwd\\freemarker";
		Configuration conf = new Configuration();
		//加载模板文件(模板的路径)
		conf.setDirectoryForTemplateLoading(new File(dir));
		// 加载模板
		Template template = conf.getTemplate("/freemarker-demo.ftl");
		// 定义数据
		
		Map root = new HashMap();
		Map mxs = new HashMap();
		mxs.put("fbb","范冰冰");
		mxs.put("lbb","李冰冰");
 
		root.put("mxs",mxs);
 
		// 定义输出
		Writer out = new FileWriter(dir + "/freemarker.html");
		template.process(root, out);
		System.out.println("转换成功");
		out.flush();
		out.close();
	}
}
  • 2.模板(两种写法)
${mxs.fbb}/${mxs.lbb}
 
 
<#list mxs?keys as k>
   ${mxs[k]}
</#list>
  • 3.生成的html 在这里插入图片描述

4.List<Map>集合:

  • 1.testFreemarker
public class testFreemarker {
	public static void main(String[] args) throws Exception {
		String dir="H:\\Java-EE Workspace\\freemarker\\src\\com\\gwd\\freemarker";
		Configuration conf = new Configuration();
		//加载模板文件(模板的路径)
		conf.setDirectoryForTemplateLoading(new File(dir));
		// 加载模板
		Template template = conf.getTemplate("/freemarker-demo.ftl");
		// 定义数据
		
		Map root = new HashMap();
		List<Map> maps = new ArrayList<Map>();
		Map pms1 = new HashMap();
		pms1.put("id1", "范冰冰");
		pms1.put("id2", "李冰冰");
		Map pms2 = new HashMap();
		pms2.put("id1", "曾志伟");
		pms2.put("id2", "何炅");
		maps.add(pms1);
		maps.add(pms2);
		root.put("maps", maps);
 
		// 定义输出
		Writer out = new FileWriter(dir + "/freemarker.html");
		template.process(root, out);
		System.out.println("转换成功");
		out.flush();
		out.close();
	}
}
  • 2.模板(2种)
<#list maps as m>
	${m.id1}/${m.id2}
</#list>
 
 
<#list maps as m>
	<#list m?keys as k>
		${m[k]}
	</#list>
</#list>
  • 3.生成的html 在这里插入图片描述

5.获得当前迭代的索引:

  • (1)testFreemarker
public class testFreemarker {
	public static void main(String[] args) throws Exception {
		String dir="H:\\Java-EE Workspace\\freemarker\\src\\com\\gwd\\freemarker";
		Configuration conf = new Configuration();
		//加载模板文件(模板的路径)
		conf.setDirectoryForTemplateLoading(new File(dir));
		// 加载模板
		Template template = conf.getTemplate("/freemarker-demo.ftl");
		// 定义数据
		
		Map root = new HashMap();
		Person p1=new Person();
		p1.setId(1);
		p1.setName("李冰冰");
		Person p2=new Person();
		p2.setId(2);
		p2.setName("范冰冰");
		Person p3=new Person();
		p3.setId(3);
		p3.setName("沙冰冰");
		List<Person> list = new ArrayList<Person>();
		list.add(p1);
		list.add(p2);
		list.add(p3);
		root.put("persons", list);
 
		// 定义输出
		Writer out = new FileWriter(dir + "/freemarker.html");
		template.process(root, out);
		System.out.println("转换成功");
		out.flush();
		out.close();
	}
}
  • (2)模板
<#list persons as p>
	${p_index}
</#list>
  • (3)生成的html文件 在这里插入图片描述

6、在模板中进行赋值:

  • (1)testFreemarker
package com.gwd.freemarker;
 
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import freemarker.template.Configuration;
import freemarker.template.Template;
 
 
/**
 - @作者:JackHisen(GWD)
 - @项目名:freemarker
 - @时间:2017-7-25 下午2:39:45
 - @version 1.0
 */
public class testFreemarker {
	public static void main(String[] args) throws Exception {
		String dir="H:\\Java-EE Workspace\\freemarker\\src\\com\\gwd\\freemarker";
		Configuration conf = new Configuration();
		//加载模板文件(模板的路径)
		conf.setDirectoryForTemplateLoading(new File(dir));
		// 加载模板
		Template template = conf.getTemplate("/freemarker-demo.ftl");
		// 定义数据
		
		Map root = new HashMap();
		
		root.put("world","hello world");
 
		// 定义输出
		Writer out = new FileWriter(dir + "/freemarker.html");
		template.process(root, out);
		System.out.println("转换成功");
		out.flush();
		out.close();
	}
}
  • (2)模板
<#assign x="${world}" />
${x}
 
<#assign x>
   <#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>
      ${n}
   </#list>
</#assign>
${x}
  • (3)生成的html在这里插入图片描述

7、if语句:

  • (1)申明:一般情况下模板中的数据来源于后台,但是这边为了方便演示,所以数据都在模板中写死了,后台testFreemarker可以同上,但实际上map可以为空,只要确保能生成html页面即可
  • (2)模板
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>
<#if n != "星期一">
   ${n}
</#if>
</#list>
  • (3)生成的html文件在这里插入图片描述

8、else语句:

  • (1)模板
<#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n>
<#if (n_index == 1) || (n_index == 3)>
   ${n} --红色
<#else>
${n} --绿色
</#if>
</#list>
  • (2)生成的html在这里插入图片描述

9、格式化日期:

  • (1)testFreemarker
public class testFreemarker {
	public static void main(String[] args) throws Exception {
		String dir="H:\\Java-EE Workspace\\freemarker\\src\\com\\gwd\\freemarker";
		Configuration conf = new Configuration();
		//加载模板文件(模板的路径)
		conf.setDirectoryForTemplateLoading(new File(dir));
		// 加载模板
		Template template = conf.getTemplate("/freemarker-demo.ftl");
		// 定义数据
		
		Map root = new HashMap();
		
		root.put("cur_time",new Date());
			
		// 定义输出
		Writer out = new FileWriter(dir + "/freemarker.html");
		template.process(root, out);
		System.out.println("转换成功");
		out.flush();
		out.close();
	}
}
  • (2)日期模板
${cur_time?date}

生成html在这里插入图片描述

  • (3)日期时间模板
${cur_time?datetime}

生成html 在这里插入图片描述

  • (4)时间模板
${cur_time?time}

生成html在这里插入图片描述

10、对null的处理:

  • (1)testFreemarker
public class testFreemarker {
	public static void main(String[] args) throws Exception {
		String dir="H:\\Java-EE Workspace\\freemarker\\src\\com\\gwd\\freemarker";
		Configuration conf = new Configuration();
		//加载模板文件(模板的路径)
		conf.setDirectoryForTemplateLoading(new File(dir));
		// 加载模板
		Template template = conf.getTemplate("/freemarker-demo.ftl");
		// 定义数据
		
		Map root = new HashMap();
		
		root.put("world",null);
			
		// 定义输出
		Writer out = new FileWriter(dir + "/freemarker.html");
		template.process(root, out);
		System.out.println("转换成功");
		out.flush();
		out.close();
	}
}
  • (2)null为空模板
${world!}         ——前面有个null

生成html

在这里插入图片描述

  • (3)为null时给默认值模板
${world!"如果world为null,我就会显示"}

生成的html在这里插入图片描述

1、宏定义

  • (1)普通宏定义

模板:

<#macro table u>
${u} 
</#macro>
<@table u="这个是宏定义" />

生成的html在这里插入图片描述

  • (2)扩展宏定义

模板:

<#macro table u>
 ${u}
<#nested/>
</#macro>
<@table u=8 >我是扩展的宏定义</@table>

生成的html在这里插入图片描述

总结

freemarker的基本语法及入门基础:

一、freemarker模板文件(*.ftl)的基本组成部分
        1. 文本:直接输出的内容部分
        2. 注释:不会输出的内容,格式为<#--  注释内容  -->
        3. 取值(插值):代替输出数据模型的部分,格式为${数据模型}或#{数据模型}
        4. ftl指令:Freemarker指令,类似于HTML标记。
                             内建指令:开始标签:<#directivename parameter>       结束标签:</#directivename>      空标签:<#directivename parameter/>   
                             自定义指令:开始标签:<@directivename parameter>       结束标签:</@directivename>      空标签:<@directivename parameter/> 
                             至于什么是内建指令,什么是自定义指令   我会在下面叙述到。                

在这里插入图片描述

二、Freemarker语法及使用方法
        1. 取值(插值)指令及适用类型:
                (1) ${var}
                        适用类型:java中常用的八大基本类型以及我们的String引用类型,但是,freemarker中boolean类型显示时true==yes  false==no
                        示例:
                                在后台文件中定义变量
                                        String strVar = "世界你好";
                                        int intVar = 10;
                                        boolean booVar = true;
                                在页面中获取变量:
                                        String获取:<font color="red"> ${strVar} </font><br>
                                        int获取:<font color="red"> ${intVar} </font><br>
                                        boolean获取:<font color="red"> ${booVar?string("yes","no")} </font>
                                展示结果:
                                        String获取:世界你好
                                        int获取:10
                                        boolean获取:yes
                (2)\${var!} 
                        适用类型:对 null 或者不存在的对象进行取值,可以设置默认值,例:${var!'我是默认值'}    即,有值时显示正常值,无值时显示默认值
                        示例:
                                在后台文件中定义变量
                                        String strVar = "世界你好";
                                        String str = null;
                                在页面中获取变量:
                                        String获取:<font color="red"> ${strVar!"我是空"} </font><br>
                                        str获取:<font color="red"> ${str!} </font><br>
                                        str获取:<font color="red"> ${str!"默认"} </font><br>
                                展示结果:
                                        String获取:世界你好
                                        str获取:
                                        str获取:默认
                (3)${封装对象.属性}
                        适用类型:对封装对象进行取值,例:${User.name}
                        示例:
                                在后台文件中封装对象User[ name,  age ]
                                        String name = "姓名";
                                        int age = 18;
                                在页面中获取变量:
                                        name获取:<font color="red"> ${User.name} </font><br>
                                        age获取:<font color="red"> ${User.age} </font><br>
                                展示结果:
                                        name获取:姓名
                                        age获取:18
                (4)${date?String('yyyy-MM-dd')}
                        适用类型:对日期格式进行取值,在这里我要强调的是,定义Date类型的变量时,java.util.Date无法输出日期,须使用java.sql.Date
                        示例:
                                在后台文件中定义变量
                                        java.sql.Date date = new Date().getTime();
                                        java.sql.Date time = new Date().getTime();
                                        java.sql.Date datetime = new Date().getTime();
                                在页面中获取变量:
                                        date获取:<font color="red"> ${date?string('yyyy-MM-dd')} </font><br>
                                        time获取:<font color="red"> ${date?string('HH:mm:ss')} </font><br>
                                        datetime获取:<font color="red"> ${date?string('yyyy-MM-dd HH:mm:ss')} </font><br>
                                展示结果:
                                        name获取:姓名
                                        age获取:18
                (5)${var?html}
                        适用类型:转义HTML内容
                        示例:
                                在后台文件中封装变量Menu[ name, model ]
                                        Menu m = new Menu(); 
                                        m.setName(" freemarker ");
                                        m.setModel("<font color = 'red'>我只是个菜单</font>");
                                在页面中获取变量:
                                        非转义获取:<font color="red"> ${m.model} </font><br>
                                        转义获取: ${m.model?html} </font><br>
                                展示结果:
                                        非转义获取:我只是个菜单
                                        转义获取:<font color = 'red'>我只是个菜单</font>
                (6)<#assign num = 100 />
                        适用类型:定义变量,支持计算和赋值
                        示例:
                                在页面中定义变量:
                                        <#assign num = 100 />
                                        num获取:<font color="red"> ${num)} </font><br>
                                        计算结果:<font color="red"> ${num * 10} </font><br>
                                展示结果:
                                        num获取:100
                                        计算结果:1000
                (7)对List集合进行取值
                        <#list  list集合  as  item> 
                               ${item}    --取值
                        </#list>
                        示例:
                                在后台文件中定义变量
                                        List<String> strList = new ArrayList<String>();
                                        strList.add("第一个值");
                                        strList.add("第二个值");
                                        strList.add("第三个值");
                                在页面中获取变量:
                                        <#list  strList  as  item> 
                                               ${item!}<br/>    --取值
                                        </#list>
                                展示结果:
                                        第一个值
                                        第二个值
                                        第三个值
                (8)对Map集合进行取值
                        <#list map?keys as key>
                               ${key}:${map[key]}
                        </#list>
                        示例:
                                在后台文件中定义变量
                                        Map<String, Object> m = new HashMap<String, Object>();
                                        m.put("name","姓名");
                                        m.put("age",18);
                                        m.put("sex","男");
                                在页面中获取变量:
                                         <#list m?keys as key>
                                                ${key}:${m[key]}
                                         </#list>
                                展示结果:
                                        name:姓名
                                        age:18
                                        sex:男
        2. 条件判断指令:
                (1) if 
                        格式:<#if 条件>
                                        输出
                                     </#if>
                        示例:
                                在页面中定义变量并判断条件:
                                        <#assign age = 18 /><br>
                                        <#if age == 18>
                                                <font color="red"> age = 18</font>
                                        </#if>
                                展示结果:
                                        age = 18
                (2) if - else 
                        格式:<#if 条件>
                                        输出
                                    <#else>
                                        输出
                                    </#if>
                        示例:
                                在页面中定义变量并判断条件:
                                        <#assign age = 20 /><br>
                                        <#if age == 18>
                                                <font color="red"> age = 18</font>
                                        <#else>
                                                <font color="red"> age != 18</font>
                                        </#if>
                                展示结果:
                                        age != 18
                (3) if - elseif - else
                        格式:<#if 条件1>
                                        输出
                                    <#elseif 条件2>
                                        输出
                                    <#else>
                                        输出
                                    </#if>
                        示例:
                                在页面中定义变量并判断条件:
                                        <#assign age = 20 /><br>
                                        <#if age &gt; 18>
                                                <font color="red">青年</font>
                                        <#elseif age == 18>
                                                <font color="red"> 成年</font>
                                        <#else>
                                                <font color="red"> 少年</font>
                                        </#if>
                                展示结果:
                                        成年
                (4) switch  --常与case break default一起使用  参数可为字符串
                        格式:<#switch var>
                                    <#case 条件1>
                                          输出
                                    <#break>
                                    <#case 条件2>
                                          输出
                                    <#break>
                                    <#default>
                                          输出
                                    </#switch>
                        示例:
                                在页面中定义变量并判断:
                                       <#switch var="星期一">
                                       <#case "星期一">
                                               油焖大虾
                                       <#break>
                                       <#case "星期二">
                                               炸酱面
                                       <#break>
                                       <#default>
                                               肯德基
                                       </#switch>
                                展示结果:
                                        油焖大虾
        3. 自定义函数、自定义指令:
                (1) 自定义函数
                        实现TemplateMthodModelEx
                (2) 自定义指令
                        实现TemplateDirectiveModel
                        示例:
                                <@自定义指令名称 入参(key-value格式) ; 出参(list格式)>
                                        运行条件
                                </@自定义指令名称>

                                PS:不同的返回值用逗号( , )间隔开

        4.常用内建函数、macro(宏指令)、function(函数指令):
                (1) 常用内建函数
                        处理字符串: 
                             substring                                          截取字符串,包头不包尾(下标)
                             cap_first                                          第一个字母大写 
                             end_with                                           以什么字母结尾    
                             contains                                            是否包含目标字符串
                             date  datetime  time                       转换成日期格式
                             starts_with                                      以什么字母开头
                             index_of                                          返回某个指定的字符串值在字符串中首次出现的位置(下标)
                             last_index_of                                  获取指定字符出现的最后位置(下标)
                             split                                                  分隔
                             trim                                                  去两端空格
                        处理数字:
                             string                                              
                             x?string("0.##")                          变成小数点后几位
                             round                                              四舍五入
                             floor                                               去掉小数点
                             ceiling                                             近1   变成整数
                        处理list:
                              first:                                              取List值第一个值
                              last:                                                取List值最后一个值
                              seq_contains:                                是否包含指定字符
                              seq_index_of:                               指定字符所在位置
                              size:                                                集合大小
                               reverse:                                          集合倒序排列
                              sort:                                                对集合进行排序
                              sort_by:                                         根据某一个属性排序
                              chunk:                                            分块处理
                        其他:
                              is_string:                                      是否为字符类型
                              is_number:                                    是否为整数类型
                              is_method:                                   是否为方法
                              ():                                                  判断整个变量
                              has_content:                                判断对象是否为空或不存在
                              eval:                                           求值
                (2) macro(宏指令)
                        调用:<@macro_name param />
                        语法:<#macro  变量名  参数>  
                                            <#nested/>  
                                    </#macro>
                (3) function(函数指令)
                        调用:${function_name(param)}
                        语法:<#function  变量名  参数>  
                                    <#return>  
                                    </#function>