Freemarker与Java完美结合:从入门到实战,打造高效模板引擎解决方案
Meta描述: 深入探讨Java如何集成并使用Freemarker模板引擎,本文提供从环境搭建、基础语法到与Spring Boot整合的完整指南,并附有实战案例,助你快速掌握Freemarker,提升Java Web开发效率。

引言:为什么在Java项目中选择Freemarker?
在Java Web开发的漫长岁月中,视图层技术经历了JSP的辉煌、Velocity的探索,再到如今各种现代前端框架的崛起。Freemarker 作为一款历史悠久且功能强大的模板引擎,至今仍在许多企业级项目中扮演着不可或缺的角色。
你是否曾面临这样的困境:
- 前端开发人员抱怨看不懂Java代码,后端开发人员又对HTML/CSS/JS感到头疼?
- 业务逻辑与页面展示紧密耦合,修改一个简单的样式都需要重新编译Java代码?
- 需要生成复杂的、结构化的文本文件(如XML、配置文件、甚至邮件模板),而不仅仅是HTML页面?
如果你的答案是“是”,那么Freemarker正是你需要的解决方案,它将Java(作为业务逻辑和控制层)与模板(作为展示层)清晰地分离开来,实现了关注点分离,让团队协作更高效,代码维护更简单。
本文将作为一份详尽的实战手册,带你全面了解如何在Java项目中高效使用Freemarker。

初识Freemarker:它是什么,如何工作?
Freemarker是一个“模板引擎”,也就是说,它是一种基于模板和要改变的数据,并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的工具,它不是面向最终用户的,而是一个Java类库,程序员可以将其嵌入到他们的产品中。
核心工作流程:
- 数据模型:你的Java代码会准备一个数据对象(通常是
Map或JavaBean),这个对象包含了模板中需要用到的所有数据。 - 模板:一个
.ftl(FreeMarker Template)文件,它混合了静态文本和动态的占位符(由和<#...>等指令构成)。 - 合并过程:Freemarker引擎读取模板文件,将数据模型中的数据“填充”到模板的占位符中,最终生成一个完整的输出文本。
环境搭建:你的第一个Freemarker项目
在开始之前,你需要将Freemarker库添加到你的项目中。
1 Maven依赖
如果你使用Maven,在pom.xml中添加以下依赖:

<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.32</version> <!-- 建议使用最新稳定版本 -->
</dependency>
2 核心API使用步骤
让我们通过一个最简单的控制台程序来感受Freemarker的魅力。
步骤1:创建配置
Configuration是Freemarker的核心,负责管理模板加载路径等设置。
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
public class FreemarkerHelloWorld {
public static void main(String[] args) {
// 1. 创建Configuration实例,指定模板版本和编码
Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);
try {
// 2. 设置模板所在的目录
cfg.setDirectoryForTemplateLoading(new File("src/main/resources/templates"));
// 3. 加载模板文件 (hello.ftl)
Template template = cfg.getTemplate("hello.ftl");
// 4. 准备数据模型
Map<String, Object> dataModel = new HashMap<>();
dataModel.put("user", "张三");
dataModel.put("age", 30);
dataModel.put("message", "欢迎使用Freemarker!");
// 5. 创建一个Writer来捕获输出
StringWriter writer = new StringWriter();
// 6. 合并模板与数据模型
template.process(dataModel, writer);
// 7. 打印结果
System.out.println(writer.toString());
} catch (IOException | TemplateException e) {
e.printStackTrace();
}
}
}
步骤2:创建模板文件
在src/main/resources/templates目录下创建hello.ftl文件:
<!DOCTYPE html>
<html>
<head>欢迎页</title>
</head>
<body>
<h1>你好, ${user}!</h1>
<p>你的年龄是: ${age}岁。</p>
<p>${message}</p>
</body>
</html>
运行Java程序,你将在控制台看到完整的HTML输出,这就是Freemarker最基本的工作方式。
Freemarker核心语法详解
掌握了基础,我们来看看Freemarker的强大语法。
1 基本指令
-
:表达式输出,用于输出变量值或计算结果。
${user!"游客"} <!-- 如果user为null或不存在,则输出"游客" --> -
<#if>...<#elseif>...<#else>...:条件判断。<#if age >= 18> 你是成年人。 <#else> 你是未成年人。 </#if> -
<#list ... as ...>:循环遍历集合(List, Array等)。<ul> <#list users as user> <li>${user_index + 1}. ${user.name} - ${user.email}</li> </#list> </ul>user_index是循环中内置的变量,表示当前元素的索引。
2 高级功能
-
宏:类似于函数,可以定义可复用的代码片段。
<!-- 定义宏 --> <#macro greet person> <p>你好, <strong>${person}</strong>!</p> </#macro> <!-- 使用宏 --> <@greet person="李四" /> <@greet person="王五" /> -
Include指令:包含其他模板文件,实现页面组件化。
<#include "header.ftl"> <#include "footer.ftl">
-
内置函数:对变量进行操作,无需在Java代码中预处理。
${userName?html} <!-- 对字符串进行HTML转义 --> ${product.price?string.currency} <!-- 格式化为货币 --> ${(user.birthday?string("yyyy-MM-dd"))!} <!-- 格式化日期 -->
实战:整合Spring Boot
在现代Java开发中,Spring Boot是事实标准,将Freemarker整合进Spring Boot项目非常简单。
1 添加依赖
除了Freemarker,我们还需要Spring Boot的Web Starter。
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
</dependencies>
2 配置Freemarker
在application.properties或application.yml中进行配置。
application.properties 示例:
# Freemarker配置 spring.freemarker.template-loader-path=classpath:/templates/ spring.freemarker.suffix=.ftl spring.freemarker.charset=UTF-8 spring.freemarker.cache=false # 开发环境设为false,方便调试 spring.freemarker.settings.template_update_delay=0
3 创建Controller和模板
-
创建Controller
import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import java.util.ArrayList; import java.util.List; @Controller public class ProductController { @GetMapping("/products") public String listProducts(Model model) { // 准备数据 List<Product> products = new ArrayList<>(); products.add(new Product(1L, "高性能笔记本电脑", 8999.00)); products.add(new Product(2L, "无线机械键盘", 599.00)); products.add(new Product(3L, "4K显示器", 2499.00)); model.addAttribute("products", products); model.addAttribute("pageTitle", "我们的产品列表"); return "product/list"; // 返回模板的逻辑路径 } } // Product实体类 class Product { private Long id; private String name; private double price; // 构造器、Getter和Setter省略... } -
创建模板 在
src/main/resources/templates下创建product/list.ftl。<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>${pageTitle}</title> <style> table { width: 100%; border-collapse: collapse; } th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } th { background-color: #f2f2f2; } </style> </head> <body> <h1>${pageTitle}</h1> <table> <thead> <tr> <th>ID</th> <th>产品名称</th> <th>价格</th> </tr> </thead> <tbody> <#list products as product> <tr> <td>${product.id}</td> <td>${product.name}</td> <td>${product.price?string.currency}</td> </tr> </#list> </tbody> </table> </body> </html>
启动Spring Boot应用,访问 http://localhost:8080/products,你将看到一个由Freemarker动态生成的产品列表页面。
性能优化与最佳实践
- 开启模板缓存:在生产环境中,务必开启Freemarker的模板缓存(
spring.freemarker.cache=true),Freemarker会在内存中缓存已编译的模板,避免每次请求都重新解析和编译模板文件,极大地提升性能。 - 关注点分离:保持模板的“纯净”,不要在模板中编写复杂的逻辑判断,如果逻辑过于复杂,应该在Java代码中处理,然后将结果传递给模板,模板只负责展示。
- 合理使用宏和Include:将通用的页面片段(如页头、页脚、导航栏)抽取成宏或独立的模板文件,通过
<#include>或<@macro />引用,提高复用性和可维护性。 - 数据模型设计:传递给模板的数据模型应该尽量扁平化,避免复杂的嵌套对象,这能让模板更易于编写和理解。
Freemarker在当今Web开发中的定位
尽管像Vue、React这样的前端框架大行其道,但Freemarker依然有其不可替代的价值。
-
适合场景:
- 传统企业级应用:对SEO要求高,且后端渲染为主的系统。
- 代码生成工具:自动生成Java代码、XML配置、SQL脚本等。
- 邮件模板系统:发送格式化的HTML邮件。
- 微服务中的静态资源生成:作为独立的微服务,负责生成静态HTML页面,供CDN分发。
-
与前端框架的对比:
- Freemarker (服务端渲染):优点是SEO友好、首屏加载快、开发相对简单,缺点是前后端耦合度相对较高,交互体验不如客户端渲染。
- Vue/React (客户端渲染):优点是用户体验好、前后端分离彻底,缺点是不利于SEO(需SSR方案支持)、首屏加载相对较慢。
通过本文的学习,你已经从零开始掌握了Freemarker在Java项目中的使用方法,从基础语法到与Spring Boot的实战整合,Freemarker作为一款成熟、稳定、高效的模板引擎,是每一位Java开发者工具箱中值得拥有的利器。
希望这篇详尽的指南能帮助你解决实际开发中的问题,提升你的项目质量和开发效率,就去你的项目中尝试使用Freemarker,感受它带来的便利吧!
