SnakeYaml - ClassCastException при десериализации в карту строковых и настраиваемых объектов

Я пытался использовать SnakeYaml для создания карты строк и объектов на Java.

Для хранения информации о человеке существует класс Person.java. Я хотел прочитать информацию о каждом человеке из файла yaml и сохранить ее на карте, где ключ представляет собой имя человека, а значение являющийся объектом Person. т.е. Для каждого имени человека должен быть создан и добавлен на карту объект человека.

РЕДАКТИРОВАТЬ: десериализация YAML должна создать Map<String, Person>

Ниже приводится содержимое каждого файла:

файл YAML:

PersonName1: 
  value1: foo1
  value2: bar1
  value3: foobar1

PersonName2:
  value1: foo2
  value2: bar2
  value3: foobar2

Person.java

public class Person {
    public String value1;
    public String value2;
    public String value3;
}

Main.java

public class Main {
    public static void main(String[] args) throws FileNotFoundException {
        InputStream inputStream = new FileInputStream(new File("SampleYamlFile.yml"));
        Yaml yaml = new Yaml();

        Map<String, Person> persons = (Map<String, Person>) yaml.load(inputStream);
        for(String key : persons.keySet()) {
            System.out.println("key = " + key);
            Person person = persons.get(key);
            System.out.println("person = " + person);
        }
    }
}

Карта создается без ошибок. Ключ также печатается. Но когда я пытаюсь получить доступ к значению ключа, я получаю ClassCastException.

java.lang.ClassCastException: java.util.LinkedHashMap не может быть преобразован в Person

SnakeYaml не поддерживает этот тип десериализации? Любая помощь в том, почему возникает эта проблема и как ее можно решить, очень ценится.


person Balasubramanian    schedule 19.10.2014    source источник


Ответы (3)


Измените это:

Yaml yaml = new Yaml();

to:

Yaml yaml = new Yaml(new Constructor(Person.class));

Вот хороший пример работы со SnakeYaml: https://aqaexplorer.com/2019/12/10/parsing-yaml-with-snake-yaml/

person v.ryabchuk    schedule 05.12.2019

На мой взгляд, ваш Yaml-файл был декодирован в такой структуре:

Map<String, Map<String, String>>

Вы можете попробовать это:

Map<String, Map<String, String>> persons = (Map<String, Map<String, String>>).yaml.load(inputStream);
for(String key : persons.keySet())
{
    System.out.println("key = " + key);
    Map<String, String> personValues = persons.get(key);
    for (String valueKey : personValues.keySet())
    {
        System.out.println(valueKey + " = " + personValues.get(valueKey));
    }
}

редактировать

Я не специалист по Yaml, но чтобы декодировать данные в пользовательские bean-компоненты, взгляните здесь: https://code.google.com/p/snakeyaml/wiki/Documentation#JavaBeans

person ToYonos    schedule 19.10.2014
comment
Да, верно, именно так оно и декодируется. Но я хотел, чтобы он создавался как Map ‹String, Person› вместо Map ‹String, Map‹ String, String ››. Я добавлю это прямо в свой вопрос. - person Balasubramanian; 19.10.2014

Вам нужно добавить set () и get (), например:

public class Person {
    public String value1;
    public String value2; 
    public String value3;

    public String getValue1() {
        return value1;
    }

    public void setValue1(String value1) {
        this.value1 = value1;
    }

    public String getValue2() {
        return value2;
    }

    public void setValue2(String value2) {
        this.value2 = value2;
    }

    public String getValue3() {
        return value3;
    }

    public void setValue3(String value3) {
        this.value3 = value3;
    }
}
person TianTao    schedule 03.03.2017