Java Spring Mustache遍历JSONObject报No method or field错误
问题根本原因
- Mustache Java实现的默认属性解析逻辑,完全基于Java Bean反射机制设计。当模板中书写
{{字段名}}表达式时,解析器会在当前上下文对象中,优先查找和字段名同名的Java成员变量,或是符合Java Bean命名规范的getter方法(比如查找name时,会尝试匹配类中的name成员、或是getName()方法),找不到对应内容就会抛出No method or field with name 'xxx'的错误。 - 模板中使用
{{.}}能正常输出内容,和属性解析逻辑无关。{{.}}的作用是直接返回当前上下文对象的字符串表示,不需要拆解对象内部结构。你传入的JSONObject不管是Fastjson、Jackson还是其他JSON库的实现,其toString()方法会直接输出自身存储的完整JSON结构字符串,所以哪怕解析器不识别对象内部存储的键值对,这个表达式也能正常运行。 - 具体到当前场景:JSONArray中的每个元素都是JSONObject,这类对象本质是将键值对存储在内部的Map结构中,本身没有名为
name的Java成员变量,也没有提供符合Java Bean规范的getName()getter方法。部分早期版本的Mustache实现默认仅支持Java Bean的属性解析,完全不兼容Map类型的对象结构,自然无法识别JSONObject内部的name键,最终触发字段找不到的报错。
正确实现方式
- 方式一:开启Mustache的Map类型解析支持(最小改动适配现有结构)
Mustache内置了Map兼容的解析处理器,开启后会在解析属性时优先判断当前上下文是否为Map结构:如果是Map类型,就直接通过map.get("字段名")的方式取值。由于所有主流JSON库的JSONObject都实现了Map接口,开启这个配置后,原有模板就可以直接读取JSONObject内部的字段。
Spring Boot环境下的配置示例:
配置完成后,@Bean public MustacheFactory mustacheFactory() { DefaultMustacheFactory factory = new DefaultMustacheFactory(); // 替换默认解析逻辑为兼容Map类型的处理器 factory.setObjectHandler(new MapObjectHandler()); return factory; }<ul>{{#data}}<li>{{name}}</li>{{/data}}</ul>模板就可以正常提取每个JSONObject的name字段值。 - 方式二:将JSONArray元素转换为标准Java POJO
如果不想全局调整Mustache的解析配置,可以在渲染前将JSONArray中的每个JSONObject,转换为对应业务结构的Java实体类(比如定义包含name、age字段的User类,搭配符合Java Bean规范的getter方法)。转换后的对象完全适配Mustache默认的Bean解析逻辑,不需要额外配置即可正常读取字段值,也更利于复杂业务下的结构维护。 - 不推荐的写法:不要在模板中手动调用JSONObject的
get()方法取值,这类写法会和具体JSON库的实现强绑定,后续切换JSON库时容易出现兼容问题。
内容的提问来源于stack exchange,提问作者Sardorkhuja Tukhtakhodjaev
相关产品推荐
相关产品推荐

