Как позволить JAXB исключить пустой узел?
Я использую JAXB для сериализации объектов в XML. Теперь я понимаю, что это исключит естественные нулевые значения из ответа, но не исключит нулевые значения из настроенных адаптеров. Ниже мой код.
package com.model;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class JAXBTest {
public static void main(String[] args) throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(Thing.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Thing thing = new Thing();
thing.setName("popcorn ball");
thing.setAwesome(false);
marshaller.setAdapter(BooleanAdapter.class,new BooleanAdapter(true));
marshaller.marshal(thing, System.out);
}
@XmlRootElement
public static class Thing{
private String name;
private Boolean awesome;
private String empty;
public String getEmpty() {
return empty;
}
public void setEmpty(String empty) {
this.empty = empty;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAwesome(Boolean awesome) {
this.awesome = awesome;
}
public Boolean isAwesome() {
return this.awesome;
}
}
public static class BooleanAdapter extends XmlAdapter<String, Boolean> {
boolean flag;
public BooleanAdapter(boolean flag){
this.flag = flag;
}
public Boolean unmarshal(String v) throws Exception {
return Boolean.TRUE.equals(v);
}
public String marshal(Boolean v) throws Exception {
if(flag){
if(v) {
return v.toString();
}
return null;
}else{
return v.toString();
}
}
}
}
packageinfo.java:
@XmlJavaTypeAdapter(value=JAXBTest.BooleanAdapter.class, type=Boolean.class)
package com.model;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
Выход:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<thing>
<awesome/>
<name>popcorn ball</name>
</thing>
Как видите, даже я возвращаю ноль в адаптере, в ответе все еще есть пустой узел awesome /. Естественное нулевое поле "private String empty" полностью игнорируется. Итак, мой вопрос, как исключить эти пустые узлы из ответа?
1 ответ
Для элемента используйте пустой класс, а не String, только адаптируйте TRUE к вашему классу.
(Может быть new Object()
будет работать, но я не пробовал это.)
public class BooleanXmlElement {
public BooleanXmlElement() {
}
public static class Adapter extends XmlAdapter<BooleanXmlElement, Boolean> {
public Boolean unmarshal(BooleanXmlElement v) {
return Boolean.TRUE;
}
public BooleanXmlElement marshal(Boolean v) {
if (Boolean.TRUE.equals(v)) {
return new BooleanXmlElement();
}
return null;
}
}
}
Это не работает для атрибутов, однако, для них String кажется необходимым:
public class BooleanXmlAttribute extends XmlAdapter<String, Boolean> {
public Boolean unmarshal(String v) {
return Boolean.valueOf(v);
}
public String marshal(Boolean v) {
if (Boolean.TRUE.equals(v)) {
return Boolean.TRUE.toString();
}
return null;
}
}
Чтобы покрыть оба Boolean
а также boolean
Аннотируйте ваш пакет для обоих:
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(value=BooleanXmlElement.Adapter.class, type=boolean.class),
@XmlJavaTypeAdapter(value=BooleanXmlElement.Adapter.class, type=Boolean.class)
})
package com.model;
Редактировать: удалить строку:
marshaller.setAdapter(BooleanAdapter.class,new BooleanAdapter(true));
тебе это не нужно