Why fasterxml lost the "xsi:type" attribute with JaxbAnnotationModule but JAXB Marshaller is fine

1.1k views Asked by At

The original JAXB Marshaller works fine when I add the @XmlSeeAlso annotation to the abstract xsd classes.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Service xmlns="http://www.a.com">
    <animal xsi:type="Dog" holder="Apache" name="Tomcat" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
</Service>

When I turn to jackson(registered the JaxbAnnotationModule), however I got a different serialized string whose "xsi:type" tag is lost.

<Service xmlns="">
    <animal holder="Apache" name="Tomcat"></animal>
</Service>

I've tried the @JsonTypeInfo annotation, but it doesn't work. How to fix Here comes my example xsd entities,

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"animal"})
@XmlRootElement(name = "Service")
public class Service {

    @XmlElement(name = "animal")
    private Animal animal;

    public Animal getAnimal() {
        return animal;
    }

    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Animal", propOrder = {"name"})
@XmlSeeAlso({Dog.class})
public abstract class Animal {

    @XmlAttribute(name = "name", required = true)
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Dog", propOrder = {"holder"})
public class Dog extends Animal {

    @XmlAttribute(name = "holder", required = true)
    private String holder;

    public String getHolder() {
        return holder;
    }

    public void setHolder(String holder) {
        this.holder = holder;
    }
}

Test case,

@Test
public void testXsiType() throws Exception {
    Service service = new Service();
    Dog dog = new Dog();
    service.setAnimal(dog);
    dog.setName("Tomcat");
    dog.setHolder("Apache");

    JAXBContext jaxb = JAXBContext.newInstance(Service.class, Dog.class);
    Marshaller marshaller = jaxb.createMarshaller();
    StringWriter writer = new StringWriter();
    marshaller.marshal(service, writer);
    System.out.println(writer.toString());

    ObjectMapper serializer = new XmlMapper();
    serializer.registerModule(new JaxbAnnotationModule());
    serializer.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    serializer.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);

    System.out.println(serializer.writeValueAsString(service));

}

lib I used,

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.4.5</version>
</dependency>
0

There are 0 answers