杰瑞科技汇

Freemarker教程怎么学?核心语法有哪些?

Freemarker 教程:从入门到精通

目录

  1. 什么是 Freemarker?
  2. 为什么选择 Freemarker?
  3. 核心概念
    • 1 模板
    • 2 数据模型
    • 3 配置
    • 4 处理
  4. 快速上手:第一个 Freemarker 程序
  5. Freemarker 常用语法详解
    • 1 注释
    • 2 输出变量:
    • 3 逻辑指令:<#if>, <#list>, <#switch>
    • 4 循环控制:<#break>, <#continue>
    • 5 模板包含:<#include>, <#import>
    • 6 宏定义:<#macro>, <@macro>
    • 7 命名空间:<#import>
    • 8 内建函数
    • 9 空值处理: 和
    • 10 算术和比较运算
  6. 最佳实践与注意事项
  7. 实际应用场景
    • 1 生成静态 HTML 页面
    • 2 生成 XML/JSON 配置文件
    • 3 在 Spring Boot 中使用 Freemarker
  8. 总结与资源

什么是 Freemarker?

FreeMarker 是一个用 Java 语言编写的模板引擎,它基于模板来生成文本输出,它的作用就是将数据(Model)和模板(Template)结合起来,生成最终的输出文本(View)

Freemarker教程怎么学?核心语法有哪些?-图1
(图片来源网络,侵删)

你可以把它想象成一个“填空题”工具:

  • 模板:是带有特殊标记(如 ${name})的文本文件(如 .ftl 文件)。
  • 数据:是一个 Java 对象或数据结构,包含了要填入空格的实际内容。
  • 引擎:Freemarker 本身,它会读取模板,用数据替换掉所有标记,然后生成最终的纯文本。

工作流程图:

[Java 数据] + [Freemarker 模板] --(Freemarker Engine)--> [最终输出文本]

为什么选择 Freemarker?

  • 关注点分离:设计人员(HTML/CSS)和开发人员(Java 逻辑)可以独立工作,设计师修改模板而无需触碰 Java 代码,反之亦然。
  • 强大的模板语言:提供了丰富的指令(if, list, macro 等)来处理复杂的逻辑,如循环、条件判断等。
  • 与 Web 容器无关:它不依赖于任何 Web 框架,可以单独使用,也可以轻松集成到 Spring, Struts, Servlet 等各种框架中。
  • 通用性:不仅可以生成 HTML,还可以生成任何基于文本的格式,如 XML, JSON, CSV, Java 源代码等。
  • 性能良好:模板在第一次加载时会被编译成高效的 Java 字节码,后续处理速度非常快。

核心概念

在开始编码前,必须理解 Freemarker 的三个核心组件。

1 模板

模板是使用 Freemarker 标记编写的文本文件,通常以 .ftl (FreeMarker Template) 作为后缀。

Freemarker教程怎么学?核心语法有哪些?-图2
(图片来源网络,侵删)

示例 hello.ftl:

<html>
<head><title>欢迎</title></head>
<body>
    <h1>你好,${user}!</h1>
    <p>当前时间是:${.now?string("yyyy-MM-dd HH:mm:ss")}</p>
</body>
</html>

这里的 ${user}${.now} Freemarker 的标记。

2 数据模型

数据模型是 Java 端提供的数据,它是一个树形结构,最简单的形式是 java.util.Map,但更常用的是 freemarker.template.Configuration 所能接受的任何对象,如 POJO (普通 Java 对象)。

示例数据模型:

Freemarker教程怎么学?核心语法有哪些?-图3
(图片来源网络,侵删)
Map<String, Object> dataModel = new HashMap<>();
dataModel.put("user", "张三");
// 也可以放入整个对象
// dataModel.put("currentUser", new User("张三", 30));

3 配置

Configuration 类是 Freemarker 的核心,它负责管理模板的加载路径、编码、版本等全局设置。

示例配置:

Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);
// 设置模板所在的目录
cfg.setDirectoryForTemplateLoading(new File("src/main/resources/templates"));
// 设置模板文件编码
cfg.setDefaultEncoding("UTF-8");

4 处理

处理过程就是将数据模型和模板结合,生成最终输出的过程,通过 Template 对象的 process 方法完成。

Template template = cfg.getTemplate("hello.ftl");
Writer out = new FileWriter("output.html");
template.process(dataModel, out);
out.close();

快速上手:第一个 Freemarker 程序

让我们创建一个简单的 Java 程序来生成一个欢迎页面。

添加依赖 如果你使用 Maven,在 pom.xml 中添加:

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.32</version> <!-- 建议使用最新稳定版 -->
</dependency>

创建模板文件src/main/resources/templates 目录下创建 welcome.ftl

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">欢迎页</title>
</head>
<body>
    <h2>欢迎, ${name}!</h2>
    <p>您的角色是: ${role}</p>
</body>
</html>

编写 Java 代码

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class FreemarkerDemo {
    public static void main(String[] args) {
        // 1. 创建 Configuration 实例
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);
        try {
            // 2. 设置模板加载路径(指向存放 .ftl 文件的目录)
            cfg.setDirectoryForTemplateLoading(new File("src/main/resources/templates"));
            // 3. 准备数据模型
            Map<String, Object> dataModel = new HashMap<>();
            dataModel.put("name", "李四");
            dataModel.put("role", "管理员");
            // 4. 加载模板
            Template template = cfg.getTemplate("welcome.ftl");
            // 5. 生成输出到文件
            try (FileWriter out = new FileWriter("welcome.html")) {
                template.process(dataModel, out);
                System.out.println("welcome.html 文件已成功生成!");
            }
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
        }
    }
}

运行程序 运行 FreemarkerDemo,你会在项目根目录下发现生成的 welcome.html 文件,内容如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">欢迎页</title>
</head>
<body>
    <h2>欢迎, 李四!</h2>
    <p>您的角色是: 管理员</p>
</body>
</html>

Freemarker 常用语法详解

1 注释

<#-- 这是一个注释,不会被输出到最终结果中 -->

2 输出变量:

这是最常用的语法,用于输出变量的值。

<p>用户名: ${username}</p>

如果变量不存在,会抛出异常,为了避免异常,可以使用空值处理(见 5.9)。

3 逻辑指令

<#if> 条件判断
<#if user.isLogged>
    <p>欢迎回来,${user.name}!</p>
<#else>
    <p>请先登录。</p>
</#if>
<#if user.age >= 18>
    <p>您已成年。</p>
<#elseif user.age >= 13>
    <p>您是青少年。</p>
<#else>
    <p>您是儿童。</p>
</#if>
<#list> 循环遍历
<h3>商品列表:</h3>
<ul>
<#list products as product>
    <li>${product_index + 1}. ${product.name} - 价格: ${product.price}</li>
</#list>
</ul>

在循环中,有两个特殊变量:

  • product_index: 当前项的索引(从 0 开始)。
  • product_has_next: 判断是否还有下一项。

4 循环控制

  • <#break>: 立即跳出当前循环。
  • <#continue>: 跳过当前迭代,继续下一次循环。

5 模板包含:<#include>, <#import>

<#include>

用于包含其他模板文件的内容,被包含的模板会直接共享当前模板的数据模型。

<#include "header.ftl">
<h1>页面主体</h1>
<#include "footer.ftl">
<#import>

类似于 Java 的 import,用于导入一个库文件(通常是包含宏的模板),并为其创建一个命名空间。

<#import "/lib/common.ftl" as common> <!-- 导入 common.ftl,并命名为 common -->
<#-- 使用 common 命名空间中的宏 -->
<@common.greet "World"/>

6 宏定义:<#macro>, <@macro>

宏类似于函数或方法,可以接收参数,并在模板中重复使用。

定义宏 (在 my_lib.ftl 中):

<#macro greet person>
    <p>你好, ${person}!</p>
</#macro>
<#macro repeat count, word>
    <#list 1..count as i>
        ${word}<#if i != count>, </#if>
    </#list>
</#macro>

使用宏:

<#import "my_lib.ftl" as my>
<@my.greet person="宏的世界"/>
<@my.repeat count=5, word="FreeMarker"/>

输出:

<p>你好, 宏的世界!</p>
FreeMarker, FreeMarker, FreeMarker, FreeMarker, FreeMarker

7 命名空间

通过 <#import> 导入的模板会创建一个命名空间,可以有效避免宏名冲突。<@common.greet> 中的 common 就是命名空间。

8 内建函数

在变量后通过 调用,用于处理或转换数据。

  • ?string: 将值转为字符串。
    ${.now?string}          <!-- 2025-10-27 10:30:00 -->
    ${.now?string("yyyy-MM-dd")} <!-- 2025-10-27 -->
  • ?html: 对字符串进行 HTML 转义,防止 XSS 攻击。
    ${userInput?html} <!-- userInput 是 "<script>alert(1)</script>",会输出 &lt;script&gt;alert(1)&lt;/script&gt; -->
  • ?cap_first: 首字母大写。
  • ?upper_case: 全部转为大写。
  • ?lower_case: 全部转为小写。
  • ?size: 获取集合或字符串的大小。
    <p>商品数量: ${products?size}</p>
  • ?date, ?time, ?datetime: 专门处理日期对象。

9 空值处理

这是 Freemarker 中非常重要的一个特性,用于防止因数据缺失导致的页面错误。

  • 操作符: 当值为空时,提供一个默认值。
    ${user.name!"访客"} <!-- user 或 user.name 为空,则显示 "访客" -->
  • 操作符: 判断值是否存在,返回布尔值 truefalse
    <#if user??>
        <p>欢迎您,${user.name}</p>
    <#else>
        <p>您还未登录。</p>
    </#if>

10 算术和比较运算

  • 算术: , , , , ,注意:数字和数字之间可以直接运算。
    ${price * 1.1} <!-- 计算含税价 -->
  • 比较: , , >, >=, <, <=,注意: 和 可以用于任何类型的值,而其他比较符只能用于数字和日期。
    <#if user.age >= 18>
        ...
    </#if>

最佳实践与注意事项

  1. 不要在模板中写复杂逻辑:模板应专注于展示,复杂的业务逻辑(如数据计算、过滤)应在 Java 端完成,然后将处理好的结果传递给模板。
  2. 始终使用 和 :养成良好习惯,对可能为空的变量进行处理,避免页面报错。
  3. 使用内建函数进行转义:对于任何用户输入的内容,在输出到 HTML 时,务必使用 ?html 进行转义,以防止 XSS 安全漏洞。
  4. 宏命名空间:在大型项目中,使用 <#import> 和命名空间来组织宏,避免命名冲突。
  5. 模板缓存Configuration 默认会缓存已加载的模板,这是性能优化的关键,不要频繁地创建和销毁 Configuration 实例,通常一个应用只需要一个全局的 Configuration
  6. 清晰的模板结构:合理使用 <#include> 将页面拆分成头部、主体、底部等模块,提高可维护性。

实际应用场景

1 生成静态 HTML 页面

这是 Freemarker 的经典用途,电商网站的商品详情页、博客文章页等,内容不常变化,可以提前生成静态 HTML 文件,减轻服务器压力。

  • 流程:后台任务定时触发,或内容发布时触发,将数据(商品信息、文章内容)和模板结合,生成 .html 文件,并部署到 CDN 或静态服务器。

2 生成 XML/JSON 配置文件

在需要动态生成配置文件的场景中,Freemarker 非常有用。

  • 示例:根据不同环境(开发、测试、生产)的配置参数,生成对应的 application-dev.xmlconfig-prod.json 文件。

3 在 Spring Boot 中使用 Freemarker

Spring Boot 对 Freemarker 提供了极佳的支持,集成非常简单。

添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

配置 application.yml

spring:
  freemarker:
    template-loader-path: classpath:/templates/ # 模板路径
    suffix: .ftl # 模板后缀
    charset: UTF-8
    cache: true # 开启模板缓存
    settings:
      number_format: '0.##' # 数字格式化

创建 Controller

@Controller
public class HelloController {
    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("message", "Spring Boot + Freemarker");
        model.addAttribute("time", new Date());
        // 视图解析器会自动寻找 /templates/hello.ftl
        return "hello";
    }
}

创建模板 templates/hello.ftl

<!DOCTYPE html>
<html>
<head>Hello Page</title>
</head>
<body>
    <h1>${message}</h1>
    <p>当前时间: ${time?string('yyyy-MM-dd HH:mm:ss')}</p>
</body>
</html>

启动 Spring Boot 应用,访问 /hello 即可看到渲染后的页面。

总结与资源

Freemarker 是一个成熟、稳定且功能强大的模板引擎,特别适合于需要将动态数据与静态模板分离的场景,通过本教程,你应该已经掌握了其核心概念和常用语法,并能够将其应用到实际项目中。

官方资源

  • 官方文档:最权威、最全面的资料,包含了所有指令和函数的详细说明。
  • 官方手册:Designer's Guide,从设计师角度出发的教程。
  • API 文档:Java API 文档。

学习建议

  1. 动手实践:跟着教程敲一遍代码,然后尝试修改模板和数据,观察输出结果的变化。
  2. 多看官方文档:遇到问题时,第一选择是查阅官方文档,因为它最准确。
  3. 模仿优秀项目:如果有机会,可以看看一些开源项目中是如何使用 Freemarker 的,学习其最佳实践。
分享:
扫描分享到社交APP
上一篇
下一篇