BeanUtils.copyProperties ignorieren Nullwerte
-
08-10-2019 - |
Frage
Ich habe die folgende Klasse:
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...
}
Es ist eine Bohne mit der Fähigkeit zur Serialisierung und Deserialisierung zu / von XML mit XStream.
Ich habe auch eine nicht-args Konstruktor, initialisiert something
, zu vermeiden Null-Zeiger Fehler - die Bohne ist eigentlich viel komplexer, und ich will nicht, wird überprüft „? something != null
ist“ eine Million mal.
Das Problem entsteht, wenn ich den XML-Konstruktor verwenden. Lets sagen, dass ich das folgende XML haben:
<myBean>
<name>John</name>
</myBean>
Das ist, was ich den Konstruktor gerne tun:
name: "John";
something: new Something();
Da es jedoch kein <something>
Element in der XML ist, BeanUtils.copyProperties something = null;
macht, also das, was ich erhalte, ist:
name: "John"
something: null
Wie kann ich kopieren beanFromXML
Eigenschaften in this
... aber ignorieren die Null-Eigenschaften, anstatt sie zu überschreiben?
Lösung
Sie können einen benutzerdefinierten Konverter erstellen, die einen Standardwert für null Eigenschaften erzeugt:
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;
}
}
}
Dann registrieren Sie es für Bean-Klassen Sie Default (leer) Werte wollen:
ConvertUtils.register(new MyNullConverter(), Something.class);
wird Ihr Code jetzt arbeiten. Das einzige, was Macht Fehler, den Sie, ist, dass Ihr etwas zweimal initialisiert wird. Weiß nicht, ob das in Ordnung ist ...
BTW, wenn Sie eine feinkörnige Kontrolle über den Prozess wollen. Verwendung BeanUtilsBean, PropertyUtilsBean und ConvertUtilsBean statt
Andere Tipps
Sie haben xstream Methoden alias einen Eigenschaftsnamen zur Klasse zuzuordnen. Der Link wird viel hilfreicher http://x-stream.github.io/alias-tutorial.html