Сериализация объекта в YAML в Java с использованием библиотеки snakeyaml - PullRequest
2 голосов
/ 13 декабря 2011

У меня нет большого опыта работы с сериализацией. Пытаясь сериализовать простой объект класса ниже, я получаю No JavaBean properties found exception из библиотеки YAML.

Вот класс:

public class MyClass {
    String value;
    public MyClass(String args) {
        value = args;
    }

    public String getValue(){
        return value;
    }
}

А вот как я сериализуюсь, используя SnakeYAMAL:

import java.util.HashMap;
import java.util.Map;

import org.yaml.snakeyaml.Yaml;


public class Test {

    public static void main(String[] args) {

        MyClass obj = new MyClass("this is my data");

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("MyClass", obj);
        Yaml yaml = new Yaml();
        String output = yaml.dump(data);
        System.out.println(output);
    }

}

и после выполнения выдается это исключение:

Exception in thread "main" org.yaml.snakeyaml.error.YAMLException: No JavaBean properties found in MyClass
    at org.yaml.snakeyaml.introspector.PropertyUtils.getProperties(PropertyUtils.java:112) ...

Можете ли вы сказать мне, что мне не хватает в этом, или как я должен сделать это правильно?

РЕДАКТИРОВАТЬ:

public class MyClass {
    String value;
    public MyClass() {}

    public String setValue(String value){
        this.value = value;
    }

    public String getValue(){
        return value;
    }
}

и если я установлю значение перед сериализацией, оно как-то работает. Как вы думаете, это правильное решение или не рекомендуемый подход?

1 Ответ

10 голосов
/ 13 декабря 2011

SnakeYAML предназначен в первую очередь для сериализации JavaBeans.

Приведенный выше пример не соответствует спецификации JavaBean. Чтобы быть JavaBean, объект должен иметь конструктор без аргументов, а каждое поле должно иметь геттер и сеттер.

Если вы переписываете свой класс как бин, SnakeYAML должен сериализовать его без проблем. Кроме того, SnakeYAML может сериализовать открытые поля, так что если вы измените видимость value на public, тогда SnakeYAML найдет и сериализует его.

Если вы действительно хотите избежать изменения MyClass, вы можете явно указать SnakeYAML для сериализации свойств, доступных только для чтения, что-то вроде этого:

PropertyUtils propUtils = new PropertyUtils();
propUtils.setAllowReadOnlyProperties(true);
Representer repr = new Representer();
repr.setPropertyUtils(propUtils);
Yaml yaml = new Yaml(new Constructor(), repr);

Однако выгрузка не-JavaBean-объектов в YAML может вызвать проблемы, когда вы возвращаете их обратно в серию Object, поэтому я рекомендую использовать JavaBeans как самое простое и безопасное решение.

Редактировать: Вот пример MyClass, преобразованный в JavaBean:

public class MyClass {
    String value;

    /* public, no-argument constructor */
    public MyClass() {
    }

    /* Every field has a public getter... */
    public String getValue(){
        return value;
    }

    /* ... and a public setter */
    public void setValue(String value) {
        this.value = value;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...