BeanUtils.copyProperties忽略空值

时间:2010-12-10 13:32:53

标签: java xstream apache-commons-beanutils

我有以下课程:

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...
}

它是一个能够使用XStream对XML进行序列化和反序列化的bean。

我还添加了一个初始化something的非args构造函数,以避免空指针错误 - bean实际上要复杂得多,而且我不想检查“是something != null ?”一百万次。

当我使用XML构造函数时出现问题。假设我有以下XML:

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

这就是我希望构造函数做的事情:

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

但是,由于XML中没有<something>元素,因此BeanUtils.copyProperties生成something = null;,因此我得到的是:

 name: "John"
 something: null

如何将beanFromXML的属性复制到this ...但是忽略null属性而不是覆盖它们?

2 个答案:

答案 0 :(得分:3)

您可以创建一个自定义转换器,为null属性创建默认值:

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;
    }
  }
}

然后将其注册为您想要默认(空)值的bean类:

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

您的代码现在可以使用了。唯一可能会让你感到烦恼的是你的Something被初始化了两次。不知道这是否可以......

BTW,如果你想对进程进行更细粒度的控制:改用BeanUtilsBean,PropertyUtilsBean和ConvertUtilsBean。

答案 1 :(得分:0)

您有xstream别名方法将属性名称映射到类。 以下链接将更有帮助 http://x-stream.github.io/alias-tutorial.html