Jackson XML serialization with the root tag for an abstract class

Asked

Viewed 14 times

-1

I have an application and need to serialize an XML with different tags at the root.

I implemented a test case with the following password, through the same input I can insert two types of XML

<ClassTypeA>
    <fieldA>a</fieldA>
</ClassTypeA>

and

<ClassTypeB>
    <fieldB>b</fieldB>
</ClassTypeB>

To serialize them I implemented these three classes:


@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({
        @JsonSubTypes.Type(value = TestConcreteDisconnectXML.class, name = "ClassTypeA"),
        @JsonSubTypes.Type(value = TestConcreteConnectXML.class, name = "ClassTypeB"),
})
abstract class TestXml{

}

@Getter
@Setter
class TestConcreteDisconnectXML extends TestXml{
    private String fieldA;
}

@Getter
@Setter
class TestConcreteConnectXML extends TestXml{
    private String fieldB;
}

Using the test below the following error is obtained:

    public void testDeserializeXML() throws Exception {

        objectMapper = new XmlMapper();
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        
        
        String message = "<ClassTypeA>\n" +
                "\t<fieldA>a</fieldA>\n" +
                "</ClassTypeA>";

        TestXml cxml =   this.objectMapper.readValue(message, TestXml.class);

        message = "<ClassTypeB>\n" +
                "\t<fieldB>b</fieldB>\n" +
                "</ClassTypeB>";

        cxml =   this.objectMapper.readValue(message, TestXml.class);


    }
com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'fieldA' as a subtype of `br.com.eletra.filemode.uaa.converter.TestXml`: known type ids = [ClassTypeA, ClassTypeB]
 at [Source: (StringReader); line: 2, column: 2]

However, when I enter any tag at the beginning of the structure, the serialization is successful.

enter image description here

I performed another test with Jackson 2.12 and Jsontypeinfo as DEDUCTION.

@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
@JsonSubTypes({
        @JsonSubTypes.Type(ClassTypeA.class),
        @JsonSubTypes.Type(ClassTypeB.class),
        @JsonSubTypes.Type(DefaultClass.class),
})
abstract class TestXml{

}

@NoArgsConstructor
@Getter
@Setter
class ClassTypeA extends TestXml{
    private String fieldA;
}

@NoArgsConstructor
@Getter
@Setter
class ClassTypeB extends TestXml{
    private String fieldB;
}

@NoArgsConstructor
@Getter
@Setter
class DefaultClass extends TestXml{

}

But a Nullexception error without many details is triggered:

java.lang.NullPointerException
    at com.fasterxml.jackson.dataformat.xml.util.StaxUtil.sanitizeXmlTypeName(StaxUtil.java:81)
    at com.fasterxml.jackson.dataformat.xml.XmlTypeResolverBuilder.typeProperty(XmlTypeResolverBuilder.java:45)
    at com.fasterxml.jackson.dataformat.xml.XmlTypeResolverBuilder.typeProperty(XmlTypeResolverBuilder.java:25)
    at com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector._findTypeResolver(JacksonAnnotationIntrospector.java:1517)
    at com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector.findTypeResolver(JacksonAnnotationIntrospector.java:572)
    at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.findTypeResolver(AnnotationIntrospectorPair.java:236)
    at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findTypeDeserializer(BasicDeserializerFactory.java:1754)
    at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:597)
    at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4731)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4592)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3546)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3514)
    at br.com.eletra.filemode.uaa.converter.XmlConvertTest.testDeserializeXML(XmlConvertTest.java:36)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at junit.framework.TestCase.runTest(TestCase.java:177)
    at junit.framework.TestCase.runBare(TestCase.java:142)
    at junit.framework.TestResult$1.protect(TestResult.java:122)
    at junit.framework.TestResult.runProtected(TestResult.java:142)
    at junit.framework.TestResult.run(TestResult.java:125)
    at junit.framework.TestCase.run(TestCase.java:130)
    at junit.framework.TestSuite.runTest(TestSuite.java:241)
    at junit.framework.TestSuite.run(TestSuite.java:236)
    at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:90)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:221)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)


Process finished with exit code -1

Any suggestions to implement something like this without having to insert the tag at runtime?

  • Please edit the question to limit it to a specific problem with sufficient detail to identify an appropriate answer.

  • what was not clear? the problem is very well specified

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.