Home > Software design >  Jackson XML deserialization fails on no String-argument constructor/factory method to deserialize fr
Jackson XML deserialization fails on no String-argument constructor/factory method to deserialize fr

Time:11-15

I try to parse XML with Jackson. I have generated java DTO from XSD, so no camel case is used and the naming convention would not make sense there.

Beans:

FINSTABean bean = xmlMapper.readValue(file, FINSTABean.class);

@JsonIgnoreProperties(ignoreUnknown = true)
@Getter @Setter @NoArgsConstructor
public class FINSTABean {
    @JsonProperty("STA_VER")
    String STA_VER;
    @JsonProperty("FINSTA03")
    List<FINSTA03Bean> FINSTA03BeanList;
}


@JsonIgnoreProperties(ignoreUnknown = true)
@Getter @Setter @NoArgsConstructor
public class FINSTA03Bean {
    @JsonProperty("S28_CISLO_VYPISU")
    String S28_CISLO_VYPISU;
    String S25_CISLO_UCTU;

XML:

<?xml version="1.0" encoding="windows-1250"?>
<FINSTA>
    <STA_VER>01.0000</STA_VER>
    <FINSTA03>
        <S28_CISLO_VYPISU>10</S28_CISLO_VYPISU>

Error:

Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.lelifin.alfa.parsers.csob_xml.FINSTA03Bean` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('10')
 at [Source: (File); line: 5, column: 29] (through reference chain: com.lelifin.alfa.parsers.csob_xml.FINSTABean["FINSTA03"]->java.util.ArrayList[0])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1728) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1353) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer._deserializeFromString(StdDeserializer.java:311) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1495) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:197) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:187) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:355) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:28) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:314) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.dataformat.xml.deser.XmlDeserializationContext.readRootValue(XmlDeserializationContext.java:91) ~[jackson-dataformat-xml-2.14.0.jar:2.14.0]

Why does it says that it cannot deserialize "10"? Is it some Lombok setter or constructor incompatibility?

If I remove <FINSTA03> sub element, I am able to properly load that FINSTABean.

CodePudding user response:

The main problem here is about the FINSTA03BeanList list because you are not annotating it with the specific JacksonXmlElementWrapper annotation causing the error due to the fact that jackson library misinterpretes your list as a single property. You can also use the xml specific JacksonXmlProperty annotation instead of JsonProperty for properties:

@Getter
@Setter
@NoArgsConstructor
public class FINSTABean {
    @JacksonXmlProperty
    String STA_VER;
    @JacksonXmlProperty(localName = "FINSTA03")
    @JacksonXmlElementWrapper(useWrapping = false)
    List<FINSTA03Bean> FINSTA03BeanList;
}

@Getter
@Setter
@NoArgsConstructor
public class FINSTA03Bean {
    @JacksonXmlProperty
    String S28_CISLO_VYPISU;
}
  • Related