SnakeYaml 中的多态集合

Posted

技术标签:

【中文标题】SnakeYaml 中的多态集合【英文标题】:Polymorphic collections in SnakeYaml 【发布时间】:2015-03-26 09:28:55 【问题描述】:

我的意图是使用 jackson 来获得像 JSON 中的多态集合,也许是在标签的帮助下。

我似乎无法正确配置它。

我的 yaml 文件是:

!person
age: 27
job: dev
name: me
skills:
- !devSkill 
  description: 'software development',
  name: android,
  language: java, c++
  years: 7

- !softSkill 
  description: 'good person',
  name: <3,
  reason: lots of NGO work

- !sportsSkill 
  description: 'racing legend',
  name: vrooom,
  championships: - San Marino 2012
                 - San Marino 2015

代码中的哪个将映射到具有(抽象?)BaseSkill 描述和名称的层次结构,以及 3 个子项:dev、soft 和 sports。

我的问题是,我对 SnakeYAML 的文档的理解不足以允许这样做。我目前的选择是:

Constructor constructor = new Constructor(Person.class);
TypeDescription carDescription = new TypeDescription(Person.class);
                carDescription.putListPropertyType("skills", SportsSkill.class);
                carDescription.putListPropertyType("skills", SoftSkill.class);
                carDescription.putListPropertyType("skills", DevSkill.class);
                // Apparently the last is the winner here because it overrides
                constructor.addTypeDescription(carDescription);

Representer representer = new Representer();
                representer.addClassTag(Person.class, new Tag("!person"));
                representer.addClassTag(SoftSkill.class, new Tag("!Softkill"));
                representer.addClassTag(DevSkill.class, new Tag("!devSkill"));
                representer.addClassTag(SportsSkill.class, new Tag("!portsSkill"));

DumperOptions options = new DumperOptions();
                options.setPrettyFlow(true);
Yaml yaml = new Yaml(constructor, representer, options);

错误在

的行中
E/YAML﹕ Can't construct a java object for tag:yaml.org,2002:app.yamlmodel.Person; exception=Cannot create property=skills for JavaBean=Person(name=me, job=dev, age=27, skills=null); null; Can't construct a java object for !sportSkill; exception=Invalid tag: !sportSkill
    in "<reader>", line 1, column 1:
    name: me
    ^

【问题讨论】:

【参考方案1】:

这个帖子已经过时了,但我找到了解决方案,希望它仍然对某人有所帮助。 您的错误是您应该将标签和类型描述符添加到构造函数并让 SnakeYaml 找出对象结构。 在你的情况下:

Constructor constructor = new Constructor(Person.class);
constructor.addTypeDescription(new TypeDescription(SoftSkill.class, new Tag("!softkill"));
constructor.addTypeDescription(new TypeDescription(DevSkill.class, new Tag("!devkill"));
constructor.addTypeDescription(new TypeDescription(SportsSkill.class, new Tag("!sportskill"));

你没有提到你使用的 SnakeYaml 版本,但我使用的是 1.16

【讨论】:

以上是关于SnakeYaml 中的多态集合的主要内容,如果未能解决你的问题,请参考以下文章

如何更改snakeyaml中的隐式类型(int to double)

snakeyaml生成yaml文件空值显示问题

在 OSGi 下使用 SnakeYaml?

使用 SnakeYaml 解析时忽略来自 yaml 的字段(无法在类上找到属性)

SnakeYaml“找不到属性错误”

Snakeyaml - 如何对流样式进行自定义控制