Reputation: 55
I'm trying to unmarshal xml file which have some optional attributes (the attribute can be included in an element, but sometimes it's missing). How can I create an optional java objects from those attributes?
XML:
...
<example a="s"
b="2.0"
/>
<example a="z"
/>
...
Java:
@XmlRootElement(name = "example")
public class ExampleDTO {
private String a;
private Optional<Float> b;
public String getA() {
return a;
}
@XmlAttribute
public void setA(String a) {
this.a = a;
}
public Optional<Float> getB() {
return b;
}
@XmlAttribute
@XmlJavaTypeAdapter(FloatOptionalAdapter.class)
public void setB(Optional<Float> b) {
this.b= b;
}
Adapter:
public class FloatOptionalAdapter extends XmlAdapter<Float, Optional<Float>> {
@Override
public Optional<Float> unmarshal(Float v) throws Exception {
return Optional.ofNullable(v);
}
@Override
public Float marshal(Optional<Float> v) throws Exception {
if (v == null || !v.isPresent()) {
return null;
} else {
return v.get();
}
}
}
When I run this code I get 2 objects of ExampleDTO. In the first one, I get Optional object with "2.0" value. In the second one, the value of b is "null". How can I make the value to be an empty Optional object?
Upvotes: 2
Views: 812
Reputation: 56413
Firstly, don't ever leave Optional<T>
fields in a null state as it simply defeats the whole purpose of using the Optional<T>
type.
Ensure, they have a
non-null value before allowing users of the API to access it and perform operations upon it, e.g. private Optional<Float> b;
would be much better being declared as private Optional<Float> b = Optional.empty()
(which actually might solve your current issue).
Further, I am not a fan of using Optional's as method parameters (see here).
The fact that your setB
consumes an Optional<T>
means that anyone can assign any value to the b
field, and that means one can even do setB(null)
, oops...
As mentioned ideally you should avoid using optional's as parameters but if you want to keep it as is then I'd suggest performing some validation to prevent null
being passed to the setB(...)
method as again it defeats the purpose of using Optional.
Finally, by having the default value of b
be Optional.empty()
as well as preventing null
being passed to the setB(...)
method, it means b
can never be null
which should always be the case anyway in order to leverage the Optional<T>
type.
Upvotes: 2