🌟 一、核心概念
FreeMarker 提供了一系列内置的 字符串格式化函数(字符串处理指令),用于对字符串进行格式转换、转义、大小写处理、空格清理等操作。这些格式化函数以 ? 开头,紧跟格式化方法名,是模板中处理字符串输出的核心工具。
1. 常见字符串格式化方法
| 格式化方法 | 说明 | 示例 |
|---|---|---|
?html |
HTML 转义(将 <, >, &, " 等字符转义为 HTML 实体) |
"Hello <b>World</b>" → "Hello <b>World</b>" |
?cap_first |
首字母大写 | "hello" → "Hello" |
?lower_case |
全部转小写 | "HELLO" → "hello" |
?upper_case |
全部转大写 | "hello" → "HELLO" |
?trim |
去除首尾空格 | " Hello " → "Hello" |
🛠️ 二、操作步骤(详细)
✅ 步骤 1:基本使用格式
${变量名?格式化方法}
示例 1:HTML 转义
<#assign text = "This is <b>bold</b> and & special characters.">
${text?html}
输出:
This is <b>bold</b> and & special characters.
示例 2:首字母大写
<#assign name = "john">
${name?cap_first}
输出:
John
示例 3:全部转小写
<#assign title = "WELCOME TO FREEMARKER">
${title?lower_case}
输出:
welcome to freemarker
示例 4:全部转大写
<#assign code = "abc123">
${code?upper_case}
输出:
ABC123
示例 5:去除首尾空格
<#assign input = " FreeMarker is powerful ">
${input?trim}
输出:
FreeMarker is powerful
✅ 步骤 6:多个格式化方法组合使用
<#assign input = " hello world ">
${input?trim?cap_first?upper_case}
输出:
HELLO WORLD
✅ 步骤 7:在 <#if>、<#list> 等逻辑中使用格式化方法
<#assign users = ["Alice", "bob", "CHARLIE"]>
<#list users as user>
<#if user?lower_case == "alice">
<p>欢迎管理员:${user}</p>
</#if>
</#list>
⚠️ 三、常见错误与注意事项
❌ 错误 1:对非字符串使用格式化方法
<#assign num = 12345>
${num?upper_case} <#-- 报错:无法对非字符串调用 ?upper_case -->
解决方法:
- 确保变量是字符串类型
- 或先转换为字符串:
${(num)?upper_case}
❌ 错误 2:误用 ?html 导致双转义
<#assign htmlContent = "<p>Hello</p>"?html>
${htmlContent} <#-- 已经转义过一次 -->
${htmlContent?html} <#-- 再次转义,导致双转义 -->
输出:
<p>Hello</p>
解决方法:
- 只在输出 HTML 时使用
?html - 不要对已转义的内容重复转义
❌ 错误 3:在 <pre> 或 <textarea> 中使用 ?html 转义
<pre>${userInput?html}</pre>
问题:
- 用户输入中的换行和空格会被转义,破坏格式
解决方法:
- 如果需要保留格式,不要使用
?html - 或使用
<#noescape>包裹输出
❌ 错误 4:误用 ?trim 导致内容被截断
<#assign input = " Hello World ">
${input?trim} <#-- 输出:Hello World -->
注意:
?trim只去除首尾空格,不处理中间空格- 若需去除中间多余空格,需结合其他方法(如正则替换)
🧠 四、使用技巧
1. 安全输出用户输入内容(防止 XSS)
<p>${userInput?html}</p>
推荐用于所有用户输入的展示场景。
2. 格式化标题或用户名
<h1>${title?cap_first?trim}</h1>
3. 统一搜索关键词大小写
<#if search?lower_case == "freemarker">
<p>搜索到关键词 FreeMarker</p>
</#if>
4. 拼接 URL 参数时格式化字符串
<#assign keyword = " FreeMarker Guide "?trim?url>
<a href="/search?keyword=${keyword}">搜索</a>
结合
?url使用,防止 URL 注入
5. 多语言适配时格式化大小写
<#if lang == "zh">
<p>欢迎</p>
<#else>
<p>${"welcome"?upper_case}</p>
</#if>
🏆 五、最佳实践
| 实践项 | 建议 |
|---|---|
输出 HTML 时使用 ?html |
防止 XSS 攻击 |
| 对用户输入统一转义 | 避免内容污染模板输出 |
在逻辑判断中使用 ?lower_case |
统一比较逻辑 |
| 避免对数字使用字符串格式化 | 会抛出异常或产生意外结果 |
使用 ?trim 清理用户输入 |
提高数据一致性 |
| 避免对已转义内容重复转义 | 防止双转义问题 |
| 组合使用多个格式化方法 | 提高代码可读性和灵活性 |
🔧 六、性能优化
| 优化项 | 说明 |
|---|---|
避免在 <#list> 中频繁调用格式化方法 |
可提前格式化并赋值给变量 |
| 减少格式化链长度 | 多个格式化操作会增加字符串处理开销 |
避免在 <#if> 中重复调用格式化方法 |
如 ${name?lower_case} 多次出现,建议赋值给变量 |
| 对静态内容不使用格式化 | 如 "HELLO" 无需转大写 |
避免对大文本频繁使用 ?html |
大文本处理会增加渲染时间,建议在 Java 层处理 |
📚 七、总结
| 维度 | 内容 |
|---|---|
| 核心格式化方法 | ?html, ?cap_first, ?lower_case, ?upper_case, ?trim |
| 使用方式 | ${变量名?格式化方法} |
| 注意事项 | 仅适用于字符串、避免双转义、避免对非字符串使用 |
| 最佳实践 | 安全输出、统一比较、避免冗余处理 |
| 性能优化 | 避免频繁调用、减少格式化链长度、合理缓存变量 |
| 推荐组合 | ?trim?cap_first, ?lower_case, ?html 等搭配使用 |
📌 附录:格式化方法对比表
| 方法 | 功能 | 示例输入 | 输出结果 |
|---|---|---|---|
?html |
HTML 转义 | "Hello <b>World</b>" |
"Hello <b>World</b>" |
?cap_first |
首字母大写 | "hello" |
"Hello" |
?lower_case |
全部小写 | "HELLO" |
"hello" |
?upper_case |
全部大写 | "hello" |
"HELLO" |
?trim |
去除首尾空格 | " Hello " |
"Hello" |
📚 推荐阅读
📌 总结一句话:
FreeMarker 提供了丰富的字符串格式化方法,如 ?html, ?cap_first, ?lower_case, ?upper_case, ?trim,它们在内容安全、格式统一、大小写处理、空格清理等方面非常实用。掌握其使用方式、注意事项与最佳实践,是高效开发 FreeMarker 模板的关键能力。