Velocity模板因变量含$字符渲染失败如何解决?
问题根因
Velocity默认会对插值输出的内容进行二次解析,当变量值中包含$标识符时,会被识别为新的Velocity变量尝试解析,找不到对应变量就会抛出缺失错误。你之前用普通转义工具不生效是因为没有针对Velocity的语法规则做特殊字符转义。
解决方案
方案1:模板端用EscapeTool转义(灵活可控,推荐)
这是最常用的处理方式,不需要修改全局配置,可针对单个变量控制:
- 先在Java代码的Velocity上下文里引入官方自带的EscapeTool:
import org.apache.velocity.tools.generic.EscapeTool; // 初始化上下文时加入 context.put("esc", new EscapeTool());
- 模板中所有可能包含特殊字符的变量输出时用
$esc.velocity()包裹即可,嵌套对象也直接使用:
"name": "$esc.velocity($user.name)" "address": "$esc.velocity($user.address)"
不管变量值里包含多少个$、#等Velocity特殊字符,都会被自动转义为字面量输出,不会触发二次解析。
方案2:Java端预处理变量值
如果不想引入工具类,可以在把变量存入上下文前,手动替换特殊字符:
// 把值里的$替换为Velocity可识别的转义格式\$ String processedName = user.getName().replace("$", "\\$"); user.setName(processedName); context.put("user", user);
模板中直接正常输出$user.name即可。
方案3:全局配置自动转义(适合全项目大量场景)
如果项目内多数变量都可能包含Velocity特殊字符,可以直接修改velocity.properties配置,开启全局自动转义:
eventhandler.referenceinsertion.class = org.apache.velocity.app.event.implement.EscapeVelocityReference
配置后所有输出的变量都会自动做Velocity特殊字符转义,不需要额外在模板里加转义方法。
错误写法说明
你之前尝试的#set($username = "$user.name")写法无效,是因为双引号包裹的内容会被Velocity先做一次插值解析,当$user.name的值里包含$时,解析阶段就会触发报错,不需要提前做#set赋值,直接用上述转义方案输出即可。
内容的提问来源于stack exchange,提问作者tensor
相关产品推荐
相关产品推荐

