JAXB: игнорировать сериализацию элемента в случае специального значения (например, `null` или` Double.NaN`) - PullRequest
0 голосов
/ 02 июля 2019

Я хочу сериализовать объект Java с JAXB. Объект имеет переменные экземпляра, которые могут иметь специальные значения, например, null или в другом случае Double.NaN.

Как можно игнорировать только переменную экземпляра, если она имеет это специальное значение?

Возможно ли это?


MWE

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class MyClass {

   private double value;
   private Object object;

   public void setValue(double value){this.value = value;}
   public double getValue(){return value;}

   public void setObject(Object object){this.object = object;}
   public Object getObject(){return object;}

}

Так что в случае value, являющегося Double.NaN и object, не являющегося null, я бы хотел получить

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MyClass>
  <object>
    ...
  </object>
</MyClass>

и в другом случае, если value не Double.NaN и object null Я бы хотел получить

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MyClass>
  <value>1.0</value>
</MyClass>

1 Ответ

1 голос
/ 02 июля 2019

Нулевые значения по умолчанию не будут генерировать XML, поэтому ваше требование к свойству object уже обработано.

Что касается специального значения double, создайте специальный метод для создания значения XML value и подавьте нормальное отображение value или getValue() в XML.

Это можно сделать, добавив аннотации к @XmlTransient или отключив автоматический выбор свойств с помощью XmlAccessType.NONE, поэтому только аннотированные свойства отображаются в XML.

Вот пример использования второго подхода:

@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class MyClass {

    private double value;
    private Foo foo;

    public MyClass() {
    }
    public MyClass(double value, Foo foo) {
        this.value = value;
        this.foo = foo;
    }

    public void setValue(double value){this.value = value;}
    public double getValue(){return this.value;}

    public void setFoo(Foo foo){this.foo = foo;}
    @XmlElement() public Foo getFoo(){return this.foo;}

    @XmlElement(name = "value")
    public Double getXmlValue() {
        if (Double.isFinite(this.value))
            return this.value;
        return null;
    }
}

public class Foo {
    @XmlElement()
    public String getBar() { return "Test"; }
}

Test

JAXBContext jaxbContext = JAXBContext.newInstance(MyClass.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

marshaller.marshal(new MyClass(Math.PI, null), System.out);
marshaller.marshal(new MyClass(Double.NaN, new Foo()), System.out);

выход

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<myClass>
    <value>3.141592653589793</value>
</myClass>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<myClass>
    <foo>
        <bar>Test</bar>
    </foo>
</myClass>

Обратите внимание, что <foo> отсутствует в первом, потому что это null, а <value> отсутствует во втором, потому что значение NaN возвращается как значение null.

При обычном использовании MyClass при вызове getValue().

все равно будет получено значение NaN.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...