BeanUtils.copyProperties 忽略空值

发布于 2024-10-07 04:22:00 字数 1352 浏览 0 评论 0原文

我有以下类:

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 的非参数构造函数,以避免空指针错误 - 该 bean 实际上要复杂得多,而且我不想检查“is something ! = null ?”一百万次。

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

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

这是我希望构造函数执行的操作:

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

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

 name: "John"
 something: null

How can I copy beanFromXML'sproperties into this... 但忽略 null 属性而不是覆盖它们?

I have the following class:

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

It's a bean with ability to serialize and deserialize to/from XML using XStream.

I also added a non-args constructor that initializes something, to avoid null pointer errors - the bean is actually a lot more complex, and I don't want to be checking "is something != null?" a million times.

The problem arises when I use the XML-constructor. Lets say I've the following XML:

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

This is what I would like the constructor to do:

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

However, since there is no <something> element in the XML, BeanUtils.copyProperties makes something = null;, thus what I get is:

 name: "John"
 something: null

How can I copy beanFromXML's properties into this... but ignoring the null properties instead of overwriting them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

有深☉意 2024-10-14 04:22:00

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

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 被初始化了两次。不知道这是否可以...

顺便说一句,如果您想要对过程进行更细粒度的控制:请改用 BeanUtilsBean、PropertyUtilsBean 和 ConvertUtilsBean。

You can create a custom converter that creates a default value for null properties:

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

Then register it for bean classes you want default (empty) values:

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

Your code will now work. The only thing that might bug you, is that your Something gets initialized twice. Don't know if this is OK...

BTW, if you want a more fine grained control over the process: use BeanUtilsBean, PropertyUtilsBean, and ConvertUtilsBean instead.

森罗 2024-10-14 04:22:00

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

You have xstream alias methods to map a property name to class.
Following link will be much more helpful
http://x-stream.github.io/alias-tutorial.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文