JAXB:在特殊值的情况下忽略元素序列化(例如“null”或“Double.NaN”)
JAXB: ignore element serialization in case of special value (e.g. `null` or `Double.NaN`)
我想用 JAXB
序列化一个 Java 对象。该对象具有可能具有特殊值的实例变量,例如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>
默认情况下不会生成空值 XML,因此您对 object
属性 的要求已得到处理。
对于特殊的double
值,创建一个专门的方法来产生XMLvalue
值,并抑制value
或[=17的法线贴图=] 到 XML.
这可以通过使用 @XmlTransient
, or by disabling automatic property selection using 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"; }
}
测试
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
值。
我想用 JAXB
序列化一个 Java 对象。该对象具有可能具有特殊值的实例变量,例如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>
默认情况下不会生成空值 XML,因此您对 object
属性 的要求已得到处理。
对于特殊的double
值,创建一个专门的方法来产生XMLvalue
值,并抑制value
或[=17的法线贴图=] 到 XML.
这可以通过使用 @XmlTransient
, or by disabling automatic property selection using 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"; }
}
测试
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
值。