使用SnakeYaml结合自定义Java类解析YAML文件报错排查
问题:YAML解析自定义Java对象失败的排查与替代方案
尝试将YAML文件内容加载到自定义Java对象中,无论如何修改都出现解析错误,项目采用Maven配置。
YAML文件内容
tables: - cid: 10 sopClass: default codeMeanings: - codeMeaning: Alpha-adrenergic blocking agent configurations: - type: 0 Code Meaning: Alpha-adrenergic blocking agent Code Value: C-80131 Coding Scheme Designator: SRT - type: 1 Code Meaning: Alpha-adrenergic blocking agent Code Value: '67440007' Coding Scheme Designator: SCT
相关Java类代码
CidTable.java
import java.util.List; public class CidTable { private List<CodingSchemeTable> tables; }
CodingSchemeTable.java
import java.util.List; public class CodingSchemeTable { private String cid; private String sopClass; private List<CodeMeanings> codeMeaning; }
CodeMeanings.java
import java.util.List; public class CodeMeanings { private String codeMeanings; private List<Configurations> configurations; }
Configurations.java
import java.util.List; public class Configurations { private List<BasicCodeSequenceMacro> codeSequenceMacros; }
BasicCodeSequenceMacro.java
public class BasicCodeSequenceMacro { private int type; private final String codeValue; private final String codingSchemeDesignator; private final String codeMeaning; }
错误信息
Cannot create property=tables for JavaBean=com.test.common.CidTable@7d3d101b in 'reader', line 1, column 1: tables: ^ Unable to find property 'tables' on class: com.test.common.CidTable in 'reader', line 2, column 1: - cid: 10 ^
错误原因与修复方案
核心错误点
- 私有字段无访问入口:所有Java类的字段都是private,且没有提供getter/setter方法,YAML解析库无法对私有属性进行赋值。
- 字段名称完全不匹配:
CodingSchemeTable中的字段是codeMeaning,但YAML中对应的键是codeMeanings(复数形式)CodeMeanings中的字段是codeMeanings,但YAML中对应的键是codeMeaning(单数形式)
- 多余的层级嵌套:YAML里的
configurations是直接包含type、Code Meaning等字段的对象数组,但你的代码里用Configurations类多套了一层codeSequenceMacros,完全不符合YAML结构。 - final字段与构造方法缺失:
BasicCodeSequenceMacro中的字段是final修饰,且没有提供无参构造方法或带参构造方法,解析库无法实例化该类;同时YAML中的键是空格分隔格式(如Code Meaning),与类中的驼峰字段名不匹配。
修复步骤
- 添加getter/setter方法:给所有需要注入的私有字段添加标准的getter和setter方法,或者将字段改为public(不推荐后者)。
- 修正字段名称匹配:
CodingSchemeTable的字段改为List<CodeMeanings> codeMeaningsCodeMeanings的字段改为String codeMeaning
- 删除冗余的Configurations类:让
CodeMeanings直接持有List<BasicCodeSequenceMacro> configurations,对齐YAML结构。 - 调整BasicCodeSequenceMacro类:去掉final修饰(或添加带参构造配合注解),并使用注解映射YAML中的空格键:
import com.fasterxml.jackson.annotation.JsonProperty; public class BasicCodeSequenceMacro { private int type; @JsonProperty("Code Value") private String codeValue; @JsonProperty("Coding Scheme Designator") private String codingSchemeDesignator; @JsonProperty("Code Meaning") private String codeMeaning; // 必须提供无参构造方法 public BasicCodeSequenceMacro() {} }
Java解析YAML的常用方法
- SnakeYAML:轻量灵活的纯YAML解析库,支持JavaBean和自定义类型,是Java生态最常用的YAML处理工具。Maven依赖:
<dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <version>2.2</version> </dependency> - Jackson YAML:基于Jackson的扩展,适合已使用Jackson处理JSON的项目,支持统一的序列化/反序列化逻辑和丰富的注解。Maven依赖:
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-yaml</artifactId> <version>2.15.2</version> </dependency> - Spring Boot内置支持:如果是Spring Boot项目,可通过
@ConfigurationProperties注解直接将YAML配置绑定到JavaBean,无需额外编写解析代码。
内容的提问来源于stack exchange,提问作者Idan Cohen
相关产品推荐
相关产品推荐

