FreeMarker 是老牌且強大的 Java 模板引擎,廣泛用於代碼生成、靜態頁生成、郵件模板等場景。本文手把手帶你搭建 Maven 項目、編寫第一個模板、整合數據模型並輸出結果。
<!-- pom.xml -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.32</version> <!-- 或最新穩定版 -->
</dependency>
項目結構建議:
src/ ├── main/ │ ├── java/ │ │ └── com/example/freemarker/ │ │ └── FreeMarkerTest.java │ └── resources/ │ └── templates/ │ └── example.ftl
example.ftl<!-- example.ftl -->
歡迎使用 ${product}!
版本:${version}
<#if features?has_content>
核心特性:
<#list features as f>
- ${f}
</#list>
</#if>
${...}:插值表達式,自動轉義輸出;#if / #list:控制指令,注意結尾 /#if;?has_content:內建函數判斷非空非零長度。package com.example.freemarker;
import freemarker.template.*;
import java.io.*;
import java.util.*;
public class FreeMarkerTest {
public static void main(String[] args) throws IOException, TemplateException {
// 1. 創建 Configuration(單例,線程安全)
Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);
cfg.setClassForTemplateLoading(FreeMarkerTest.class, "/templates");
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
cfg.setLogTemplateExceptions(false);
cfg.setWrapUncheckedExceptions(true);
cfg.setFallbackOnNullLoop(false);
// 2. 獲取模板
Template template = cfg.getTemplate("example.ftl");
// 3. 準備數據模型
Map<String, Object> root = new HashMap<>();
root.put("product", "FreeMarker");
root.put("version", "2.3.32");
root.put("features", Arrays.asList("高性能", "模板繼承", "宏系統", "自動轉義"));
// 4. 渲染輸出到控制台
try (Writer out = new OutputStreamWriter(System.out, "UTF-8")) {
template.process(root, out);
}
}
}
歡迎使用 FreeMarker! 版本:2.3.32 核心特性: - 高性能 - 模板繼承 - 宏系統 - 自動轉義
| 場景 | 指令/語法 | 說明 |
|---|---|---|
| 判空輸出默認值 | ${user.name!'匿名用戶'} | 避免 NullPointerException |
| 日期格式化 | ${date?string('yyyy-MM-dd HH:mm')} | 內建 ?string 格式化 |
| 數字格式化 | ${price?string.currency} / ${num?string('0.00')} | 貨幣/保留小數 |
| HTML 轉義 | ${content?html} 或 全局 cfg.setAutoEscapingPolicy(...) | 防 XSS 必開 |
| 模板繼承 | <#import "layout.ftl" as layout> + <@layout.page> | 類似 JSP include 但更強 |
| 自定義指令/函數 | 實現 TemplateDirectiveModel / TemplateMethodModelEx | 擴展業務標籤 |
@Bean,避免重複解析模板;cfg.setTemplateUpdateDelayMilliseconds(0) 熱加載;RETHROW_HANDLER 拋出異常由統一異常處理器捕獲,避免模板錯誤吞沒;cfg.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER) 禁止任意類實例化。「模板引擎是視圖層的編譯器,好模板像好架構——關注點分離、邏輯極簡、擋住噁心的字符串拼接。」