本文详解如何使用 jackson 的 yamlmapper 正确解析 yaml 中以点号分隔的扁平化键(如 `formatting.template`),避免 `mismatchedinputexception`,关键在于 json pointer 路径必须与 yaml 实际结构严格匹配。
Jackson 的 YAMLMapper 是一个严格遵循 YAML 规范的解析器,它不会将点号(.)自动解释为嵌套层级分隔符——这与 Spring Boot 的 @ConfigurationProperties 加载机制有本质区别。Spring 在内部会将 YAML 转换为 Properties 形式,并将 a.b.c 视为三层嵌套映射;但原生 YAMLMapper 仅按 YAML 文档的真实结构(即缩进/映射关系)解析,formatting.template: 在 YAML 中是一个单层键名(key
name),而非嵌套对象。
因此,当你的 YAML 文件写成:
formatting.template:
fields:
- name: birthdate
type: java.lang.String
subType: java.util.Date
lenght: 10这在 YAML 语法中表示:根级别存在一个键名为字符串 "formatting.template" 的映射,其值是一个包含 fields 的对象。此时,若仍使用 JSON Pointer /formatting/template(意图为“进入 formatting 对象,再进入 template 对象”),YAMLMapper 将找不到对应嵌套路径,导致 MismatchedInputException: No content to map due to end-of-input —— 因为 /formatting/template 在文档中根本不存在,实际存在的只有 /formatting.template。
✅ 正确做法是:JSON Pointer 必须精确匹配 YAML 键名字面量。
修改读取代码中的 JSON Pointer 即可:
return mapper.readerFor(FormattingConfigurationProperties.class)
.at("/formatting.template") // ← 关键:用斜杠包裹完整键名,不拆分为路径
.readValue(inputStream);⚠️ 注意事项:
总结:YAMLMapper 无“点号自动嵌套”逻辑,一切以 YAML 实际结构为准。使用扁平键时,JSON Pointer 必须字面量匹配;追求工程一致性时,推荐采用标准缩进式嵌套写法。