Загрузка Snakeyaml в JavaBean, и если свойство не найдено на карте

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

Ex.

public class Person {
  private String firstName;
  private String lastName;
  private Map<String, Object> anythingElse;

  //Getters and setters...
}

Если я загружаю документ, который выглядит так:

firstName: joe
lastName: smith
age: 30

Поскольку возраст не является свойством bean-компонента, я хотел бы, чтобы {age, 30} был добавлен к карте somethingElse.

Возможный?

Спасибо.


person kmachstang    schedule 27.07.2012    source источник


Ответы (3)


Нет, это было бы невозможно.

Из моего опыта и попыток это не работает. Если вы хотите загрузить файл в объект, то все атрибуты в этом объектном классе должны иметь геттер и сеттер (т.е. класс должен быть JavaBean, см. Википедию).

Я использовал ваш класс Person (см. вики-страницу для правильного JavaBeanClass) и этот код: http://codepaste.net/dbtzqb< /а>

Мое сообщение об ошибке было следующим: "Строка 3, столбец 4: Невозможно найти свойство "возраст" в классе: Человек", что доказывает, что эта простая программа не может иметь "непредвиденных" атрибутов. Это мой быстрый и легкий вывод. Я не пробовал много, так что это может быть возможно, но я не знаю такого способа (вам придется обойти методы чтения и JavaBean). Я использовал YamlBeans (https://code.google.com/p/yamlbeans/ ) так что это немного по-другому, но мне кажется, что это проще и работает;]

Надеюсь, это помогает!

Изменить

Извините, что вмешиваюсь, лучше поздно, чем никогда! Я не видел дату публикации, пока не опубликовал свой ответ. Но, надеюсь, это поможет другим, ищущим помощи: 3

person Lurvas777    schedule 11.04.2013
comment
Codepaste указывает на битую ссылку. Вот почему мы должны размещать код прямо здесь, а не на внешних веб-сайтах. - person Olivier Grégoire; 03.12.2018

Я не пробовал следующий (полу-клудный хак) с использованием SnakeYaml, но у меня он работает с YamlBeans:

В основном идея состоит в том, чтобы определить класс, который расширяет одну из конкретных реализаций java.util.Map. Затем определите геттеры, которые выбирают разные значения, и общий геттер, который возвращает все остальное:

public class Person extends HashMap<String, Object>
{
    public String getFirstName()
    {
        return (String)this.get("firstName");
    }

    public String getLastName()
    {
        return (String)this.get("lastName");
    }

    public Map<String, Object> getExtensions()
    {
        Map<String, Object> retVal = (Map<String, Object>)this.clone();

        retVal.remove("firstName");
        retVal.remove("lastName");

        return retVal;
    }
}

Я не уверен, как SnakeYaml или YamlBeans расставляют приоритеты для информации другого типа, которую вы видите при самоанализе этого класса, но YamlBeans (по крайней мере) доволен десериализацией информации в этот класс, как если бы это была любая другая карта, и, похоже, не запутаться в дополнительных геттерах (т.е. не спотыкаться на "getExtensions").

person gilbertpilz    schedule 29.04.2013
comment
Я пытался заставить это работать с помощью SnakeYaml, но потерпел неудачу. По какой-то причине с YamlBeans легче работать. - person gilbertpilz; 30.04.2013

Это возможно:

import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.representer.Representer;

public class YamlReader {
    public static <T> T readYaml(InputStream is, Class<T> clazz){
        Representer representer = new Representer();
        // Set null for missing values in the yaml
        representer.getPropertyUtils().setSkipMissingProperties(true);

        Yaml yaml = new Yaml(representer);
        T data = yaml.loadAs(is, clazz);

        return data;
    }
}
person kódfodrász    schedule 25.05.2016