BeanUtils.copyProperties игнорирует нулевые значения - PullRequest
2 голосов
/ 10 декабря 2010

У меня есть следующий класс:

import org.apache.commons.beanutils.BeanUtils;
import com.thoughtworks.xstream.XStream;
...

public class MyBean {
    protected static final XStream XSTREAM = new XStream(new DomDriver());

    protected String name;
    protected Something something;

    public MyBean() {
        something = new Something();
    }

    public MyBean(String xml) {
        this();
        MyBean beanFromXML = (MyBean) XSTREAM.fromXML(new StringReader(xml));
        BeanUtils.copyProperties(this, beanFromXML);
    }

    public String toString() {
        return XSTREAM.toXML(this);
    }

    // Getters and setters...
}

Это bean-компонент с возможностью сериализации и десериализации в / из XML с использованием XStream.

Я также добавил конструктор без аргументов, который инициализируетsomething, чтобы избежать ошибок нулевого указателя - боб на самом деле намного сложнее, и я не хочу проверять "is something != null?"миллион раз.

Проблема возникает, когда я использую XML-конструктор.Допустим, у меня есть следующий XML:

<myBean>
    <name>John</name>
</myBean>

Это то, что я хотел бы сделать конструктором:

name: "John";
something: new Something();

Однако, поскольку в элементе нет элемента <something>XML, BeanUtils.copyProperties составляет something = null;, поэтому я получаю:

 name: "John"
 something: null

Как я могу скопировать свойства beanFromXML в this ... но игнорируя нулевые свойства вместо перезаписиих

Ответы [ 2 ]

3 голосов
/ 10 декабря 2010

Вы можете создать собственный конвертер, который создает значение по умолчанию для нулевых свойств:

public class MyNullConverter implements Converter {
  @Override
  public Object convert(final Class type, final Object value) {
    try {
      return value == null ? type.newInstance() : value;
    } catch (final InstantiationException e) {
      return null;
    } catch (final IllegalAccessException e) {
      return null;
    }
  }
}

Затем зарегистрируйте его для классов бинов, которые вы хотите использовать по умолчанию (пусто):

ConvertUtils.register(new MyNullConverter(), Something.class);

Ваш код теперь будет работать. Единственное, что может вас беспокоить, это то, что что-то инициализируется дважды. Не знаю, нормально ли это ...

Кстати, если вам нужен более точный контроль над процессом: используйте взамен BeanUtilsBean, PropertyUtilsBean и ConvertUtilsBean.

0 голосов
/ 10 декабря 2010

У вас есть методы псевдонима xstream для сопоставления имени свойства с классом. Следующая ссылка будет намного полезнее http://x -stream.github.io / псевдоним tutorial.html

...