gorąco polecam reprezentujący null
albo z braku węzła lub z atrybutem xsi:nil="true"
. To działa najlepiej z walidacji schematu (tzn <age/>
lub <age></age>
nie jest poprawnym elementem typu xsd:int
Jednak jeśli nie tutaj może to w jaki sposób można osiągnąć swój przypadek użycia.
STANDARD JAXB ZACHOWANIA
Używanie standardowe interfejsy API, które można kontrolować, czy wartość null jest reprezentowana jako nieobecnego węzła lub xsi:nil="true"
z dopiskiem @XmlElement
(patrz: http://blog.bdoughan.com/2012/04/binding-to-json-xml-handling-null.html)
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Address {
private String street;
@XmlElement(nillable=true)
private String city;
}
Poniżej outpu XML. t jeśli wartości obu pól są zerowe.
<?xml version="1.0" encoding="UTF-8"?>
<address>
<city xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</address>
Moxy - Nadrzędny Takie zachowanie w klasie
Moxy nie zapewnia adnotację określić politykę zerowej dla wszystkich właściwości na klasy. Można jednak wykorzystać wartość DescriptorCustomizer
za pomocą adnotacji @XmlCustomizer
i dostosować natywne metadane odwzorowania MOXy, aby uzyskać tę samą funkcję.
DescriptorCustomizer (AddressCustomizer)
import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.oxm.mappings.nullpolicy.XMLNullRepresentationType;
public class AddressCustomizer implements DescriptorCustomizer {
@Override
public void customize(ClassDescriptor descriptor) throws Exception {
for(DatabaseMapping mapping : descriptor.getMappings()) {
if(mapping.isAbstractDirectMapping()) {
XMLDirectMapping xmlDirectMapping = (XMLDirectMapping) mapping;
xmlDirectMapping.getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.EMPTY_NODE);
xmlDirectMapping.getNullPolicy().setNullRepresentedByEmptyNode(true);
}
}
}
}
model domeny (adresu)
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlCustomizer;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlCustomizer(AddressCustomizer.class)
public class Address {
private String street;
@XmlElement(nillable=true)
private String city;
}
Wyjście
<?xml version="1.0" encoding="UTF-8"?>
<address>
<street/>
<city/>
</address>
Moxy - Nadrzędny to zachowanie dla wszystkich klas
Jeśli zamiast tego chcesz nadpisać zerowej obsługę dla wszystkich odwzorowanych klas Polecam przy użyciu SessionEventListener
zamiast. Jeśli wolisz, możesz również użyć tego podejścia do aktualizacji metadanych dla pojedynczej klasy.
SessionEventListener (NullPolicySessionEventListener)
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.oxm.mappings.nullpolicy.XMLNullRepresentationType;
import org.eclipse.persistence.sessions.*;
public class NullPolicySessionEventListener extends SessionEventAdapter {
@Override
public void preLogin(SessionEvent event) {
Project project = event.getSession().getProject();
for(ClassDescriptor descriptor : project.getOrderedDescriptors()) {
for(DatabaseMapping mapping : descriptor.getMappings()) {
if(mapping.isAbstractDirectMapping()) {
XMLDirectMapping xmlDirectMapping = (XMLDirectMapping) mapping;
xmlDirectMapping.getNullPolicy().setMarshalNullRepresentation(XMLNullRepresentationType.EMPTY_NODE);
xmlDirectMapping.getNullPolicy().setNullRepresentedByEmptyNode(true);
}
}
}
}
}
Demo Code
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.eclipse.persistence.sessions.SessionEventListener;
public class Demo {
public static void main(String[] args) throws Exception {
Map<String, Object> properties = new HashMap<String, Object>(1);
SessionEventListener sessionEventListener = new NullPolicySessionEventListener();
properties.put(JAXBContextProperties.SESSION_EVENT_LISTENER, sessionEventListener);
JAXBContext jc = JAXBContext.newInstance(new Class[] {Address.class}, properties);
Address address = new Address();
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(address, System.out);
}
}
Wyjście
<?xml version="1.0" encoding="UTF-8"?>
<address>
<street/>
<city/>
</address>