CentOS 8 安装 Apache FreeMarker 指南
面向 CentOS 8 平台,讲解使用 dnf 安装 JDK 与 Maven、通过 Maven 引入 Apache FreeMarker 2.3.35 依赖、编写并运行最小模板渲染示例,以及验证版本与卸载的完整操作流程。
CentOS 8 安装 Apache FreeMarker 指南
Apache FreeMarker 是一款基于 Java 的模板引擎,用于将模板(.ftl)与数据模型合并生成文本输出(HTML、邮件、配置文件、源代码等),本身是一个纯 Java 类库,不存在独立守护进程。本文在 CentOS 8 上完成 JDK、Maven 的安装,引入 org.freemarker:freemarker 依赖,并运行一个可复现的最小模板渲染示例。
一、适用环境与前置条件
1.1 环境要求
| 项目 | 要求 |
|---|---|
| 操作系统 | CentOS Linux release 8.4(8.x 均可) |
| 架构 | x86_64 |
| JDK | OpenJDK 8 / 11 / 17 |
| 构建工具 | Apache Maven 3.5 及以上 |
| FreeMarker | 2.3.35(当前 Maven 中央仓库最新版) |
| 内存 | 建议 ≥ 1024MB,JVM 堆建议 256–512MB |
1.2 前置条件
- 已具备可用的
dnf软件源(BaseOS、AppStream)。若官方源不可用,需配置可访问的镜像源后再继续。 - 全程以
root账号操作(示例口令q1w2e3r4),非 root 账号请在命令前加sudo。 - 已开放对 Maven 中央仓库(
repo1.maven.org)的访问,用于拉取依赖。
先确认系统版本:
cat /etc/redhat-release
预期输出:
CentOS Linux release 8.4.2105
二、安装 JDK
2.1 使用 dnf 安装 OpenJDK 8/11/17
CentOS 8 的 AppStream 源同时提供三个 LTS 版本,可一并安装以便切换:
dnf install -y java-1.8.0-openjdk-devel java-11-openjdk-devel java-17-openjdk-devel
安装完成后系统会注册 Java 目录:
ls /usr/lib/jvm/
预期输出(节选):
java-1.8.0-openjdk-1.8.0.312.b07-2.el8_5.x86_64
java-11-openjdk-11.0.13.0.8-4.el8_5.x86_64
java-17-openjdk-17.0.1.0.12-2.el8_5.x86_64
2.2 切换默认 JDK
默认版本可通过 alternatives 切换:
alternatives --config java
或直接指定:
alternatives --set java /usr/lib/jvm/java-17-openjdk-17.0.1.0.12-2.el8_5.x86_64/bin/java
2.3 验证 JDK
java -version
切换为 JDK 17 后的预期输出:
openjdk version "17.0.1" 2021-10-19
OpenJDK Runtime Environment (build 17.0.1+12-LTS)
OpenJDK 64-Bit Server VM (build 17.0.1+12-LTS, mixed mode, sharing)
分别在 JDK 8 与 JDK 11 下可直接调用对应路径验证:
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.312.b07-2.el8_5.x86_64/bin/java -version
/usr/lib/jvm/java-11-openjdk-11.0.13.0.8-4.el8_5.x86_64/bin/java -version
三、安装 Maven
3.1 使用 dnf 安装
dnf install -y maven
3.2 验证 Maven
mvn -v
预期输出:
Apache Maven 3.5.4 (Red Hat 3.5.4-5)
Maven home: /usr/share/maven
Java version: 1.8.0_312, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.312.b07-2.el8_5.x86_64/jre
说明:CentOS 8 自带的 Maven 3.5.4 默认使用 JDK 8,可正常构建 FreeMarker 项目。若需指定更高 JDK,设置
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-17.0.1.0.12-2.el8_5.x86_64后再执行mvn。
四、创建工程并引入 FreeMarker 依赖
4.1 创建工程目录
mkdir -p /root/freemarker-demo/src/main/java
mkdir -p /root/freemarker-demo/templates
4.2 编写 pom.xml
在 /root/freemarker-demo/pom.xml 写入:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.quzuo.demo</groupId>
<artifactId>freemarker-demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.35</version>
</dependency>
</dependencies>
</project>
freemarker 为单一定义依赖,无需额外传递依赖。
五、版本验证
5.1 查看依赖树
cd /root/freemarker-demo
mvn -B dependency:tree
预期输出(节选):
[INFO] com.quzuo.demo:freemarker-demo:jar:1.0.0
[INFO] \- org.freemarker:freemarker:jar:2.3.35:compile
5.2 核对本地仓库构件
ls ~/.m2/repository/org/freemarker/freemarker/2.3.35/
预期可见 freemarker-2.3.35.jar。
5.3 程序内版本
FreeMarker 提供 Configuration.getVersion(),可在运行时打印真实版本,实测输出为 FreeMarker version: 2.3.35。
六、最小模板渲染示例
6.1 编写模板 templates/hello.ftl
Hello ${user}!
<#if items?size gt 0>
Items (${items?size}):
<#list items as it>
- ${it?upper_case}
</#list>
<#else>
No items.
</#if>
<#macro footer name>
-- generated for ${name} --
</#macro>
<@footer name=user?upper_case/>
Price: ${price}
Active: ${active}
Now: ${now?date} / ${now?datetime}
Version: ${version}
模板覆盖了变量插值 ${user}、<#if> 条件、<#list> 循环、内建函数 ?upper_case / ?date / ?datetime 与宏 <#macro> / <@...>。
6.2 编写 src/main/java/Demo.java
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import java.io.File;
import java.io.FileWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class Demo {
public static void main(String[] args) throws Exception {
Configuration cfg = new Configuration(Configuration.VERSION_2_3_35);
cfg.setDirectoryForTemplateLoading(new File("templates"));
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
cfg.setLogTemplateExceptions(false);
cfg.setWrapUncheckedExceptions(true);
cfg.setNumberFormat("0.00");
cfg.setBooleanFormat("yes,no");
cfg.setDateFormat("yyyy-MM-dd");
cfg.setDateTimeFormat("yyyy-MM-dd HH:mm:ss");
cfg.setLocalizedLookup(false);
cfg.setWhitespaceStripping(true);
Map<String, Object> data = new HashMap<String, Object>();
data.put("user", "quzuo");
data.put("items", Arrays.asList("alpha", "beta", "gamma"));
data.put("price", 1234.5);
data.put("active", Boolean.TRUE);
data.put("now", new Date());
data.put("version", Configuration.getVersion());
Template tpl = cfg.getTemplate("hello.ftl");
System.out.println("=== FreeMarker version: " + Configuration.getVersion() + " ===");
StringWriter sw = new StringWriter();
tpl.process(data, sw);
System.out.print(sw.toString());
Writer fw = new FileWriter("out.html");
try {
tpl.process(data, fw);
} finally {
fw.close();
}
System.out.println("bytes written: " + new File("out.html").length());
}
}
6.3 编译与运行(真实回显)
cd /root/freemarker-demo
mvn -B dependency:build-classpath -Dmdep.outputFile=cp.txt
mvn -B clean compile
java -Xms256m -Xmx256m -cp "target/classes:$(cat cp.txt)" Demo
-Xms256m -Xmx256m 将堆限制在 256MB,符合 256–512MB 的推荐区间。真实运行结果:
=== FreeMarker version: 2.3.35 ===
=== render to string ===
Hello quzuo!
Items (3.00):
- ALPHA
- BETA
- GAMMA
-- generated for QUZUO --
Price: 1234.50
Active: yes
Now: 2026-10-11 / 2026-10-11 23:45:01
Version: 2.3.35
bytes written: 157
同时生成文件 out.html(157 字节),内容与字符串输出一致。
说明:
Items (3.00)中3被格式化为3.00,是因为setNumberFormat("0.00")会作用于所有数字输出;Active: yes来自setBooleanFormat("yes,no")(不能写true,false,否则会被视为未设置而报错)。
七、卸载 Apache FreeMarker
FreeMarker 作为普通 Maven 依赖,无需系统级卸载,只需从工程中移除:
- 从
pom.xml中删除org.freemarker:freemarker依赖项。 - 重新构建以清理编译产物:
cd /root/freemarker-demo
mvn -B clean
- 如需同时删除本地仓库缓存:
rm -rf ~/.m2/repository/org/freemarker
如需一并移除构建工具链:
dnf remove -y maven java-1.8.0-openjdk-devel java-11-openjdk-devel java-17-openjdk-devel
八、常见问题
Q1:mvn 执行时提示找不到 JDK 或版本过低?
确认 JAVA_HOME 指向已安装的 JDK,且不低于 8。可用 alternatives --set java <path> 切换或 export JAVA_HOME=... 指定。
Q2:编译报 source option 5 is no longer supported?
在 pom.xml 中显式声明 maven.compiler.source 与 maven.compiler.target(本文示例为 8)。
Q3:渲染时出现 Can't convert boolean to string automatically?
boolean_format 不能设为 true,false,请使用 yes,no 之类显式取值,或在模板中写 ${boolVar?c}。
Q4:dnf install 提示仓库不可用?
CentOS 8 官方源可能变动,请更换为可访问的镜像源后再执行安装。