FTL遍历对象数组访问带连字符JSON属性报错问题排查
报错原因
该报错本质是变量类型不匹配导致的:
- 传入模板的
blank_3数组中,元素的template字段实际是JSON格式的字符串,而非已经完成反序列化的结构化JSON对象 - FreeMarker默认对象包装逻辑会将字符串类型值包装为
StringModel,不会自动解析字符串内部的JSON结构为可通过key取值的哈希模型;错误信息里明确标注父值类型为extended_hash+string、org.json.JSONObject被包装为f.e.b.StringModel,就是指要操作的test变量实际是字符串类型,无法使用变量名[key]的哈希取值语法读取子属性,因此触发报错。
解决方法
可根据实际项目场景选择以下任意一种方案修复:
- 上游传参修正(最推荐)
在数据传入FreeMarker上下文之前,提前将每个元素的template字段从JSON字符串反序列化为结构化对象(JavaBean、HashMap、原生JSONObject均可),不要直接传JSON格式的字符串。修正后无需改动模板原有取值逻辑,test["clm-medical-examination"]??的判断可以正常执行。 - 模板内解析JSON字符串(无法修改上游传参时使用)
借助FreeMarker内置的?eval内建函数,先将JSON格式的字符串解析为FTL可识别的哈希对象,再做属性判断,修正后的模板代码如下:
注意:使用该方案需要保证<#list blank_3 as data> <#if data.template??> <#assign test = data.template?eval /> <#if test["clm-medical-examination"]??> Hi </#if> </#if> </#list>data.template的值是标准合法的JSON格式字符串,否则?eval执行时会抛出解析异常。 - 全局配置FreeMarker对象包装器
如果项目中大量使用org.json的JSONObject作为传参类型,可以修改FreeMarker全局配置,将默认对象包装器替换为支持org.json类型识别的适配器,比如开启DefaultObjectWrapper的useAdaptersForContainers配置,或注册专门的JSON类型解析适配器,让FreeMarker自动识别JSON对象为哈希模型,避免被错误包装为字符串模型。
内容的提问来源于stack exchange,提问作者Ganesh Mandapati
相关产品推荐
相关产品推荐

