Freemarker中Properties模型如何直接获取带点号的完整键属性值
Freemarker访问带点号的Properties键实现方案
该需求可以实现,根据你是否允许修改现有FTL表达式,可选择两类落地方案:
方案1:可修改FTL表达式(实现成本最低)
Freemarker的方括号取值语法默认会把括号内的字符串作为完整Map键查找,不会按点号拆分路径,不需要修改任何全局配置即可生效:
- 如果你的Properties实例直接作为Freemarker数据模型的根对象传入,写法如下:
<#if .data_model["property.name"] == "true"> - 如果你的Properties实例是数据模型下的一个普通变量(比如变量名为
config),写法如下:<#if config["property.name"] == "true">
这个写法是Freemarker原生支持的标准语法,对所有包含点、横杠、空格等特殊字符的Map键都生效,兼容性最好。
方案2:不修改现有FTL表达式,保持property.name写法
这种场景需要调整Freemarker的对象包装器配置,改变点号表达式的默认查找优先级:
- 如果你使用Freemarker 2.3.22及以上版本,直接在初始化配置时开启Map键优先查找开关即可:
配置生效后,Freemarker遇到// 初始化对象包装器,版本号替换为你实际使用的Freemarker版本即可 DefaultObjectWrapperBuilder owBuilder = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_32); // 开启配置:点号表达式优先匹配完整Map键,匹配失败再回退到分层属性查找 owBuilder.setPreferDirectMapKeyLookup(true); ObjectWrapper customWrapper = owBuilder.build(); // 把自定义包装器设置到Freemarker全局配置中 Configuration freemarkerCfg = new Configuration(Configuration.VERSION_2_3_32); freemarkerCfg.setObjectWrapper(customWrapper);property.name这类点号表达式时,会先在当前Map/Properties对象中查找完整键property.name,找到就直接返回对应值,找不到才会按原有逻辑先查property键、再查其下的name属性,不会影响原有其他正常表达式的执行。 - 如果你使用的Freemarker版本较低,不支持上述配置,可以在传入Properties对象到数据模型前,手动将其转换为自定义的Hash模型,重写取值逻辑直接按完整键查找即可,不需要修改全局配置。
注意:如果你的Properties中同时存在
property和property.name两个键,开启上述配置后会优先返回property.name对应的值,不会再读取property键下的name属性,使用前需要确认不存在这类键冲突。
内容的提问来源于stack exchange,提问作者JochenW
相关产品推荐
相关产品推荐

