强制JavaBean属性上的YAML标记

时间:2016-06-13 16:22:51

标签: java snakeyaml

我一直在使用SnakeYAML进行某些序列化/反序列化。我的应用程序结合了Python和Java,所以我需要在标签和类型上有一些“合理的行为”。

我在YAML文档上的问题/实际状态:

!!mypackage.MyClassA
someFirstField: normal string
someSecondField:
  a: !!mypackage.ThisIsIt
    subField: 1
    subOtherField: 2
  b: !!mypackage.ThisIsIt
    subField: 3
    subOtherField: 4
someThirdField:
  subField: 5
  subOtherField: 6

我通过重新实现someSecondField并简单地执行checkGlobalTag,实现了集合中标记的使用(请参阅示例return)。如果我理解正确的话,这可以确保没有蛇形的智能清洁并保持标签。到目前为止一切都很好:我到处都需要这种类型。

但是,这还不够,因为someThirdField也是!!mypackage.ThisIsIt,但它有隐式标记,这是一个问题(Python不理解它)。还有其他一些不完整的案例(尝试在Python方面采取一些快捷方式,它们成了一个坏主意)。

确保所有用户定义的类都显示标记的正确方法是什么?我假设我应该覆盖Representer上的一些方法,但我找不到哪一种方法。

1 个答案:

答案 0 :(得分:1)

负责该线路"智能标签自动清洁"如下:

if (property.getType() == propertyValue.getClass())

对于班级representJavaBeanProperty,可在Representer中找到。

我找到的(丑陋)解决方案是使用以下内容扩展Representer@Override representJavaBeanProperty

protected NodeTuple representJavaBeanProperty(Object javaBean, 
        Property property,
        Object propertyValue, 
        Tag customTag) {
    // Copy paste starts here...

    ScalarNode nodeKey = (ScalarNode) representData(property.getName());
    // the first occurrence of the node must keep the tag
    boolean hasAlias = this.representedObjects.containsKey(propertyValue);

    Node nodeValue = representData(propertyValue);

    if (propertyValue != null && !hasAlias) {
        NodeId nodeId = nodeValue.getNodeId();
        if (customTag == null) {
            if (nodeId == NodeId.scalar) {
                if (propertyValue instanceof Enum<?>) {
                    nodeValue.setTag(Tag.STR);
                }
            }
            // Copy-paste ends here !!!
            // Ignore the else block --always maintain the tag.
        }
    }

    return new NodeTuple(nodeKey, nodeValue);

这也会强制显式标记列表行为(之前通过覆盖checkGlobalTag方法强制执行,现在已在representJavaBeanProperty代码中实现)。