将缺少的xml属性解组为可选的java对象

时间:2018-06-13 09:04:54

标签: java jaxb optional unmarshalling

我正在尝试解组具有一些可选属性的xml文件(该属性可以包含在元素中,但有时会丢失)。 如何从这些属性创建可选的java对象?

XML:

...
<example a="s"
     b="2.0"
/>
<example a="z"
/>
...

爪哇:

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

适配器:

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

当我运行此代码时,我获得了ExampleDTO的2个对象。在第一个中,我获得具有“2.0”值的Optional对象。在第二个中,b的值是“null”。 如何将值设为空的Optional对象?

1 个答案:

答案 0 :(得分:2)

首先,不要将Optional<T>字段留在 null 状态,因为它完全违背了使用Optional<T>类型的全部目的。

确保,他们有一个  非null 值,然后允许API的用户访问它并对其执行操作,例如private Optional<Float> b;被宣布为private Optional<Float> b = Optional.empty()会更好(实际上可以解决您当前的问题)。

此外,我不喜欢使用Optional&#39;作为方法参数(see here)。

您的setB消费Optional<T>意味着任何人都可以为b字段分配任何值,这意味着您甚至可以setB(null),oops。 ..

如理想情况所述,您应该避免使用可选的&#39;作为参数,但如果您想保持原样,那么我建议您执行一些验证以防止null传递给{{1方法再次失败了使用Optional的目的。

最后,将setB(...)的默认值设为b并阻止Optional.empty()传递给null方法,这意味着setB(...)可以永远不会是b,为了利用null类型,总是应该如此。