Freemarker 基础入门
都依凡
撰写于 2023年 04月 27 日

官网:FreeMarker Java Template Engine (apache.org)

FreeMarker 是一个用 Java 语言编写的模板引擎,它基于模板来生成文本输出。FreeMarker与 Web 容 器无关,即在 Web 运行时,它并不知道 Servlet 或 HTTP。它不仅可以用作表现层的实现技术,而且还 可以用于生成 XML,JSP 或 Java 等。

Freemarker 模板语言是FTL文件编写的(Freemarker 文件后缀 .ftl)

虽然FreeMarker最初是为生成HTML页面而创建的 MVC Web 应用程序框架,它不绑定到 servlet 或 HTML 或 任何与网络相关的内容。它在非 Web 应用程序环境中运作。

1. FreeMarker的几个亮点

  • 强大的模板语言:条件块,迭代,赋值,字符串和算术运算和格式设置,宏和函数,包括其他模板,默认情况下可以转义(可选),等等
  • 多用途和轻量级:零依赖,任何输出格式,可以从任何地方加载模板,可插拔许多配置选项
  • 国际化:区域设置敏感,数字和日期/时间格式,本地化模板变化
  • XML处理功能:将XML Dom-S放入数据建模和遍历,甚至处理他们,使用声明方式
  • 通用数据模型:Java对象向模板公开,作为可插拔适配器的变量树,他决定模板如何看到他们

2. 从官网中获取当前最新的稳定版本号

官网:下载 / Maven - Apache FreeMarker™

获取到Maven坐标

<dependency>
  <groupId>org.freemarker</groupId>
  <artifactId>freemarker</artifactId>
  <version>2.3.32</version>
</dependency>
直到2007年左右,Maven组名是 “freemarker”而不是“org.freemarker”, 正如上面的XML注释所说,这可能会导致问题,因为Maven 将将它们视为两个独立的工件,没有版本冲突。 如果您遇到此问题,请找到依赖于旧 FreeMarker 的,并插入其中。
<exclusions>
    <exclusion>
        <groupId>freemarker<!-- Legacy org-less group --></groupId>
        <artifactId>freemarker</artifactId> 
    </exclusion>
</exclusions>`

还有一个单独的Google App Engine兼容 (“gae”)变体

<dependency>
  <groupId>org.freemarker</groupId>
  <artifactId>freemarker-gae</artifactId>
  <version>2.3.32</version>
</dependency>

3. 基础使用范例

  1. 文件准备

    • 创建一个文件夹,在文件夹中创建一个以 .ftl 结尾的文件,这里使用的是一个index.ftl文件
<html>
    <head>
        <meta charset="utf-8">
        <title>Freemarker入门</title>
    </head>
    <body>
        <#--我只是一个注释,我不会有任何输出 -->
        ${name}你好,${message}
    </body>
</html>
  1. 创建一个FreemarkerTest.class 类文件
        // 创建Freemarker中的configuration对象,构造方法里面传入版本号
        Configuration configuration = new Configuration(Configuration.getVersion());
        // 设置模板所在的目录
        configuration.setDirectoryForTemplateLoading(new File("C:\\Users\\DYF\\Desktop\\ftl"));
        // 设置编码集
        configuration.setDefaultEncoding("utf-8");
        // 加载模板,加载对应的模板文件
        Template template = configuration.getTemplate("index.ftl");
        // 创建数据模型
        HashMap<String, String> map = new HashMap<>();
        map.put("name","张三");
        map.put("message","这条消息是message");
        // 创建输出流
        FileWriter fileWriter = new FileWriter(new File("C:\\Users\\DYF\\Desktop\\ftl\\index.html"));
        // 生成对应的Html静态文件
        template.process(map,fileWriter);
        // 关闭流
        fileWriter.close();
  1. 运行代码,会发现当前设置的目录下多了一个index.html 文件,打开之后,发现生成了一个静态文件,直接将 ${} 所包含的文本直接生成了一个静态的数据
在项目中应用时可以将Configuration对象的创建交由Spring框架来完成,并通过依赖注入方 式将字符集和模板所在目录注入进去。

1. 数据设置原理

比如有模板文件

<html>
<head>
  <title>Welcome!</title>
</head>
<body>
  <h1>Welcome ${user.name}!</h1>
  <p>Our latest product:
  <a href="${user.latestProduct.name}">${user.latestProduct.name}</a></br>
  <a href="${user.latestProduct.arrTest[0]}">${user.latestProduct.arrTest[0]}</a>
</body>
</html>

有Java对象User 并且生成Get和Set方法

public class User {
    private String name;
    private LatestProduct latestProduct;
}

有Java对象 LatestProduct 并且生成Get和Set方法

public class LatestProduct {
    private String name;
    private Integer[] arrTest;
}

测试代码

    public static void main(String[] args) throws Exception {
        // 创建Freemarker中的configuration对象,构造方法里面传入版本号
        Configuration configuration = new Configuration(Configuration.getVersion());
        // 设置模板所在的目录
        configuration.setDirectoryForTemplateLoading(new File("C:\\Users\\DYF\\Desktop\\ftl"));
        // 设置编码集
        configuration.setDefaultEncoding("utf-8");
        // 加载模板
        Template template = configuration.getTemplate("index2.ftl");
        // 创建数据模型
        HashMap<String, Object> map = new HashMap<>();
        Integer[] arr = {1,2,3,4};
        User user = new User("李四", new LatestProduct("王五", arr));
        map.put("user",user);
        // 创建输出流
        FileWriter fileWriter = new FileWriter(new File("C:\\Users\\DYF\\Desktop\\ftl\\index2.html"));
        template.process(map,fileWriter);
        fileWriter.close();
    }
我们会发现在Freemarker中模板注入使用的方式和jsp中的表达式差不多一致

2. 使用注意

不需要重复创建 `Configuration` 实例; 它的代价很高,尤其是会丢失缓存。`Configuration` 实例就是应用级别的单例。

数据模型+模板=输出

数据模型:就是Java对象,使用Map集合将Java对象放入,然后页面中可以调用

模板,及页面中的模板取值

4. FreeMarker的常用指令

1. assign 指令

assign指令用于在页面上定义一个变量

  1. 定义简单数据类型
    <#assign linkman="周先生">
    联系人:${linkman}
    <#assign 变量名=值 变量名=值> (定义多个变量)
    <#assign num=1 names=["zhangsan","lisi","wangwu"] > (定义数组,遍历数组)
    ${num} -- ${names?join(",")}
  1. 定义对象类型
<#assign info={"mobile":"1391XXXXXX",'address':'郑州市金水区'} >
电话:${info.mobile} 地址:${info.address}

2. include指令

include指令用于模板的文件的嵌套

使用步骤:

  1. 创建一个模板文件如:head.ftl
<h1>程序员</h1>
  1. 创建另一个模板文件如:test.ftl
<#include "head.ftl"/>
  1. 包含多种文件
<#--包含指令(引入其他页面文件) include-->
<#--html文件-->
<#include "test.html"> 
<#--freemarker文件-->
<#include "test.ftl"> 
<#--text文件-->
<#include "test.txt">

注意:

被包含的文件和包含它的模板共享变量,就像是被复制粘贴进去的一样。

3. if 指令

​ if 指令用于条件判断,选择判断使用

<#if success=true>
你已通过实名认证
<#else>
你未通过实名认证
</#if>

在模板中加入下面代码

map.put("success",true);
在freemarker的判断中,可以使用= 也可以使用==

4. if else if 指令

if else if 使用多条判断语句

<#if 条件>
 ...
<#elseif 条件>
 ...
<#elseif 条件>
 ...
<#else>

5. list指令

list集合用于遍历

  1. 创建模板文件
<#list goodsList as goods>
商品名称: ${goods.name} 价格:${goods.price}<br>
</#list>
  1. 创建Java类代码
List goodsList=new ArrayList();
Map goods1=new HashMap();
goods1.put("name", "苹果");
goods1.put("price", 5.8);
Map goods2=new HashMap();
goods2.put("name", "香蕉");
goods2.put("price", 2.5);
Map goods3=new HashMap();
goods3.put("name", "橘子");
goods3.put("price", 3.2);
goodsList.add(goods1);
goodsList.add(goods2);
goodsList.add(goods3);
map.put("goodsList", goodsList);

5. macro 自定义指令

1. 指令可以被多次使用。
2. 自定义指令中可以包含字符串,也可包含内置指令

1. 自定义指令

  1. 声明指令
  <#macro 指令名>
     指令内容
  </#macro>
  1. 使用指令
<@指令名></@指令名>
  1. 使用方式
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入门</title>
</head>
<body>
<#macro test> 这个测试指令</#macro>
使用指令
<@test></@test>
</body>
</html>

java代码可以直接写上面的测试使用范例,编译执行即可

2. 自定义指令(带参数)

  声明格式:
       <#macro 指令名 参数名1 参数名2>
          指令内容
      </#macro>
  使用格式:
      <@指令名 参数名1=参数值1 参数名2=参数值2></@指令名>
  1. 使用方式
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入门</title>
</head>
<body>
    定义指令
<#macro test a b>${a}</br>${b}</#macro>
使用指令
<@test a=1 b=2></@test>
</body>
</html>

3. 自定义指令(包含内置指令)

  1. 使用方式
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入门</title>
</head>
<body>
<#macro test>
遍历1到9 使用 i 给每次遍历的结果赋值</br>
 <#list 1..9 as i>
    遍历1到 i 使用 j 给每次遍历的结果赋值
        <#list 1..i as j>
           ${j}*${i}=${j*i}&nbsp;
        </#list>
        <br>
    </#list> 
</#macro>
使用指令</br>
<@test></@test>
</body>
</html>

6. nested 占位符指令

nested占位符一般会和macro一起使用

  1. 使用方式
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入门</title>
</head>
<body>
<#macro test>
    这是一段文本!
    <#nested>
    <#nested> 
</#macro>
使用指令</br>
<@test><h4>这是文本后面的内容!</h4></@test>
</body>
</html>

7、import 导入指令

import 指令可以引入一个库。也就是说,它创建一个新的命名空间, 然后在那个命名空间中执行给定路径的模

板。可以使用引入的空间中的指令。

  1. 创建commons.ftl文件
<#macro cfb>
    <#list 1..9 as i>
        <#list 1..i as j>
           ${j}*${i}=${j*i}&nbsp;
        </#list>
        <br>
    </#list> 
</#macro>

在其他ftl页面中通过import导入commons.ftl的命名空间,使用该命名空间中的指令

  1. 创建test.ftl文件
<#-- 导入命名空间 -->
<#import "commons.ftl" as common> 
<#-- 使用命名空间中的指令 -->
<@common.cfb></@common.cfb>

Freemarker 基础入门

官网:FreeMarker Java Template Engine (apache.org)

FreeMarker 是一个用 Java 语言编写的模板引擎,它基于模板来生成文本输出。FreeMarker与 Web 容 器无关,即在 Web 运行时,它并不知道 Servlet 或 HTTP。它不仅可以用作表现层的实现技术,而且还 可以用于生成 XML,JSP 或 Java 等。

Freemarker 模板语言是FTL文件编写的(Freemarker 文件后缀 .ftl)

虽然FreeMarker最初是为生成HTML页面而创建的 MVC Web 应用程序框架,它不绑定到 servlet 或 HTML 或 任何与网络相关的内容。它在非 Web 应用程序环境中运作。

1. FreeMarker的几个亮点

  • 强大的模板语言:条件块,迭代,赋值,字符串和算术运算和格式设置,宏和函数,包括其他模板,默认情况下可以转义(可选),等等
  • 多用途和轻量级:零依赖,任何输出格式,可以从任何地方加载模板,可插拔许多配置选项
  • 国际化:区域设置敏感,数字和日期/时间格式,本地化模板变化
  • XML处理功能:将XML Dom-S放入数据建模和遍历,甚至处理他们,使用声明方式
  • 通用数据模型:Java对象向模板公开,作为可插拔适配器的变量树,他决定模板如何看到他们

2. 从官网中获取当前最新的稳定版本号

官网:下载 / Maven - Apache FreeMarker™

获取到Maven坐标

<dependency>
  <groupId>org.freemarker</groupId>
  <artifactId>freemarker</artifactId>
  <version>2.3.32</version>
</dependency>
直到2007年左右,Maven组名是 “freemarker”而不是“org.freemarker”, 正如上面的XML注释所说,这可能会导致问题,因为Maven 将将它们视为两个独立的工件,没有版本冲突。 如果您遇到此问题,请找到依赖于旧 FreeMarker 的,并插入其中。
<exclusions>
    <exclusion>
        <groupId>freemarker<!-- Legacy org-less group --></groupId>
        <artifactId>freemarker</artifactId> 
    </exclusion>
</exclusions>`

还有一个单独的Google App Engine兼容 (“gae”)变体

<dependency>
  <groupId>org.freemarker</groupId>
  <artifactId>freemarker-gae</artifactId>
  <version>2.3.32</version>
</dependency>

3. 基础使用范例

  1. 文件准备

    • 创建一个文件夹,在文件夹中创建一个以 .ftl 结尾的文件,这里使用的是一个index.ftl文件
<html>
    <head>
        <meta charset="utf-8">
        <title>Freemarker入门</title>
    </head>
    <body>
        <#--我只是一个注释,我不会有任何输出 -->
        ${name}你好,${message}
    </body>
</html>
  1. 创建一个FreemarkerTest.class 类文件
        // 创建Freemarker中的configuration对象,构造方法里面传入版本号
        Configuration configuration = new Configuration(Configuration.getVersion());
        // 设置模板所在的目录
        configuration.setDirectoryForTemplateLoading(new File("C:\\Users\\DYF\\Desktop\\ftl"));
        // 设置编码集
        configuration.setDefaultEncoding("utf-8");
        // 加载模板,加载对应的模板文件
        Template template = configuration.getTemplate("index.ftl");
        // 创建数据模型
        HashMap<String, String> map = new HashMap<>();
        map.put("name","张三");
        map.put("message","这条消息是message");
        // 创建输出流
        FileWriter fileWriter = new FileWriter(new File("C:\\Users\\DYF\\Desktop\\ftl\\index.html"));
        // 生成对应的Html静态文件
        template.process(map,fileWriter);
        // 关闭流
        fileWriter.close();
  1. 运行代码,会发现当前设置的目录下多了一个index.html 文件,打开之后,发现生成了一个静态文件,直接将 ${} 所包含的文本直接生成了一个静态的数据
在项目中应用时可以将Configuration对象的创建交由Spring框架来完成,并通过依赖注入方 式将字符集和模板所在目录注入进去。

1. 数据设置原理

比如有模板文件

<html>
<head>
  <title>Welcome!</title>
</head>
<body>
  <h1>Welcome ${user.name}!</h1>
  <p>Our latest product:
  <a href="${user.latestProduct.name}">${user.latestProduct.name}</a></br>
  <a href="${user.latestProduct.arrTest[0]}">${user.latestProduct.arrTest[0]}</a>
</body>
</html>

有Java对象User 并且生成Get和Set方法

public class User {
    private String name;
    private LatestProduct latestProduct;
}

有Java对象 LatestProduct 并且生成Get和Set方法

public class LatestProduct {
    private String name;
    private Integer[] arrTest;
}

测试代码

    public static void main(String[] args) throws Exception {
        // 创建Freemarker中的configuration对象,构造方法里面传入版本号
        Configuration configuration = new Configuration(Configuration.getVersion());
        // 设置模板所在的目录
        configuration.setDirectoryForTemplateLoading(new File("C:\\Users\\DYF\\Desktop\\ftl"));
        // 设置编码集
        configuration.setDefaultEncoding("utf-8");
        // 加载模板
        Template template = configuration.getTemplate("index2.ftl");
        // 创建数据模型
        HashMap<String, Object> map = new HashMap<>();
        Integer[] arr = {1,2,3,4};
        User user = new User("李四", new LatestProduct("王五", arr));
        map.put("user",user);
        // 创建输出流
        FileWriter fileWriter = new FileWriter(new File("C:\\Users\\DYF\\Desktop\\ftl\\index2.html"));
        template.process(map,fileWriter);
        fileWriter.close();
    }
我们会发现在Freemarker中模板注入使用的方式和jsp中的表达式差不多一致

2. 使用注意

不需要重复创建 `Configuration` 实例; 它的代价很高,尤其是会丢失缓存。`Configuration` 实例就是应用级别的单例。

数据模型+模板=输出

数据模型:就是Java对象,使用Map集合将Java对象放入,然后页面中可以调用

模板,及页面中的模板取值

4. FreeMarker的常用指令

1. assign 指令

assign指令用于在页面上定义一个变量

  1. 定义简单数据类型
    <#assign linkman="周先生">
    联系人:${linkman}
    <#assign 变量名=值 变量名=值> (定义多个变量)
    <#assign num=1 names=["zhangsan","lisi","wangwu"] > (定义数组,遍历数组)
    ${num} -- ${names?join(",")}
  1. 定义对象类型
<#assign info={"mobile":"1391XXXXXX",'address':'郑州市金水区'} >
电话:${info.mobile} 地址:${info.address}

2. include指令

include指令用于模板的文件的嵌套

使用步骤:

  1. 创建一个模板文件如:head.ftl
<h1>程序员</h1>
  1. 创建另一个模板文件如:test.ftl
<#include "head.ftl"/>
  1. 包含多种文件
<#--包含指令(引入其他页面文件) include-->
<#--html文件-->
<#include "test.html"> 
<#--freemarker文件-->
<#include "test.ftl"> 
<#--text文件-->
<#include "test.txt">

注意:

被包含的文件和包含它的模板共享变量,就像是被复制粘贴进去的一样。

3. if 指令

​ if 指令用于条件判断,选择判断使用

<#if success=true>
你已通过实名认证
<#else>
你未通过实名认证
</#if>

在模板中加入下面代码

map.put("success",true);
在freemarker的判断中,可以使用= 也可以使用==

4. if else if 指令

if else if 使用多条判断语句

<#if 条件>
 ...
<#elseif 条件>
 ...
<#elseif 条件>
 ...
<#else>

5. list指令

list集合用于遍历

  1. 创建模板文件
<#list goodsList as goods>
商品名称: ${goods.name} 价格:${goods.price}<br>
</#list>
  1. 创建Java类代码
List goodsList=new ArrayList();
Map goods1=new HashMap();
goods1.put("name", "苹果");
goods1.put("price", 5.8);
Map goods2=new HashMap();
goods2.put("name", "香蕉");
goods2.put("price", 2.5);
Map goods3=new HashMap();
goods3.put("name", "橘子");
goods3.put("price", 3.2);
goodsList.add(goods1);
goodsList.add(goods2);
goodsList.add(goods3);
map.put("goodsList", goodsList);

5. macro 自定义指令

1. 指令可以被多次使用。
2. 自定义指令中可以包含字符串,也可包含内置指令

1. 自定义指令

  1. 声明指令
  <#macro 指令名>
     指令内容
  </#macro>
  1. 使用指令
<@指令名></@指令名>
  1. 使用方式
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入门</title>
</head>
<body>
<#macro test> 这个测试指令</#macro>
使用指令
<@test></@test>
</body>
</html>

java代码可以直接写上面的测试使用范例,编译执行即可

2. 自定义指令(带参数)

  声明格式:
       <#macro 指令名 参数名1 参数名2>
          指令内容
      </#macro>
  使用格式:
      <@指令名 参数名1=参数值1 参数名2=参数值2></@指令名>
  1. 使用方式
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入门</title>
</head>
<body>
    定义指令
<#macro test a b>${a}</br>${b}</#macro>
使用指令
<@test a=1 b=2></@test>
</body>
</html>

3. 自定义指令(包含内置指令)

  1. 使用方式
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入门</title>
</head>
<body>
<#macro test>
遍历1到9 使用 i 给每次遍历的结果赋值</br>
 <#list 1..9 as i>
    遍历1到 i 使用 j 给每次遍历的结果赋值
        <#list 1..i as j>
           ${j}*${i}=${j*i}&nbsp;
        </#list>
        <br>
    </#list> 
</#macro>
使用指令</br>
<@test></@test>
</body>
</html>

6. nested 占位符指令

nested占位符一般会和macro一起使用

  1. 使用方式
<html>
<head>
<meta charset="utf-8">
<title>Freemarker入门</title>
</head>
<body>
<#macro test>
    这是一段文本!
    <#nested>
    <#nested> 
</#macro>
使用指令</br>
<@test><h4>这是文本后面的内容!</h4></@test>
</body>
</html>

7、import 导入指令

import 指令可以引入一个库。也就是说,它创建一个新的命名空间, 然后在那个命名空间中执行给定路径的模

板。可以使用引入的空间中的指令。

  1. 创建commons.ftl文件
<#macro cfb>
    <#list 1..9 as i>
        <#list 1..i as j>
           ${j}*${i}=${j*i}&nbsp;
        </#list>
        <br>
    </#list> 
</#macro>

在其他ftl页面中通过import导入commons.ftl的命名空间,使用该命名空间中的指令

  1. 创建test.ftl文件
<#-- 导入命名空间 -->
<#import "commons.ftl" as common> 
<#-- 使用命名空间中的指令 -->
<@common.cfb></@common.cfb>

版权属于:都依凡 所有,采用《知识共享署名许可协议》进行许可,转载请注明文章来源。

本文链接: http://blog.anlucky.cn/index.php/programming/java/122

赞 (2)

评论区(暂无评论)

啊哦,评论功能已关闭~