javasnakeyaml

How to load a list of custom objects with SnakeYaml


I've been trying to deserialize the following yaml to a List<Stage> using SnakeYaml:

- name: Stage1
  items: 
    - item1
    - item2

- name: Stage2
  items: 
    - item3

public class Stage {
    private String name;
    private List<String> items;

    public Stage() {
    }

    public Stage(String name, List<String> items) {
        this.name = name;
        this.items = items;
    }

    // getters and setters
}

The closest question I found was SnakeYaml Deserialise Class containing a List of Objects. After reading it, I am aware of Constructor and TypeDescriptor classes, but I am still unable to get it working (I get list of HashMaps, not Stages).

The difference with the question in the link above is that my top-level structure is a list, not a custom object.


Solution

  • One way would be to create your own snakeyaml Constructor like this:

    public class ListConstructor<T> extends Constructor {
      private final Class<T> clazz;
    
      public ListConstructor(final Class<T> clazz) {
        this.clazz = clazz;
      }
    
      @Override
      protected Object constructObject(final Node node) {
        if (node instanceof SequenceNode && isRootNode(node)) {
          ((SequenceNode) node).setListType(clazz);
        }
        return super.constructObject(node);
      }
    
      private boolean isRootNode(final Node node) {
        return node.getStartMark().getIndex() == 0;
      }
    }
    

    and then use it when constructing the Yaml:

    final Yaml yaml = new Yaml(new ListConstructor<>(Stage.class));