Search code examples
javajackson-dataformat-xml

UnrecognizedPropertyException when using XmlMapper


XML String

A profilesBatch contains 1 profilesList
A profilesList contains one or more profile
A profile contains 1 useRestrictions

<profilesBatch version="1.0" id="745" date="2012-12-13" transportKeyLabel="str1234">
  <profilesList>
    <profile iccid="str1234" profileType="str1234">
      <useRestrictions>
        <maximumDownloadAttempts>745</maximumDownloadAttempts>
        <maximumConfirmationAttempts>745</maximumConfirmationAttempts>
        <maximumNumberEIDs>745</maximumNumberEIDs>
        <maximumDownloadsPerEID>745</maximumDownloadsPerEID>
        <allowDownloadForDownloaded>true</allowDownloadForDownloaded>
        <allowDownloadForInstalled>true</allowDownloadForInstalled>
        <allowDownloadForError>true</allowDownloadForError>
      </useRestrictions>
    </profile>
  </profilesList>
</profilesBatch>

Class ProfilesBatch

@Getter
@Setter
@XmlRootElement(name = "ProfilesBatch")
public class ProfilesBatch
{
    @JacksonXmlProperty(isAttribute = true)
    private String date;

    @JacksonXmlElementWrapper(localName="profilesList")
    @JacksonXmlProperty(localName="profilesList")
    private ProfilesList profilesList;

    @JacksonXmlProperty(isAttribute = true)
    private String transportKeyLabel;

    @JacksonXmlProperty(isAttribute = true)
    private Header header;

    @JacksonXmlProperty(isAttribute = true)
    private String id;

    @JacksonXmlProperty(isAttribute = true)
    private String version;

}

Class ProfileList

@Getter
@Setter
@XmlRootElement(name = "ProfilesList")
public class ProfilesList
{
    @JacksonXmlElementWrapper(localName="profile")
    @JacksonXmlProperty(localName="profile")
    private List<Profile> profile;
}

Class Profile

@Getter
@Setter
@XmlRootElement(name = "Profile")
public class Profile
{
    @JacksonXmlProperty(isAttribute = true)
    private String iccid;

    @JacksonXmlProperty(isAttribute = true)
    private String profileType;

    @JacksonXmlElementWrapper(localName="useRestrictions")
    private UseRestrictions useRestrictions;

}

Class UseRestrictions

@Getter
@Setter
@XmlRootElement(name = "useRestrictions")
public class UseRestrictions {

    @JacksonXmlProperty(localName = "maximumDownloadAttempts")
    private int maximumDownloadAttempts;

    @JacksonXmlProperty(localName = "maximumNumberEIDs")
    private int maximumNumberEIDs;

    @JacksonXmlProperty(localName = "maximumConfirmationAttempts")
    private int maximumConfirmationAttempts;

    @JacksonXmlProperty(localName = "maximumDownloadsPerEID")
    private int maximumDownloadsPerEID;

    @JacksonXmlProperty(localName = "allowDownloadForInstalled")
    private boolean allowDownloadForInstalled;

    @JacksonXmlProperty(localName = "allowDownloadForDownloaded")
    private boolean allowDownloadForDownloaded;

    @JacksonXmlProperty(localName = "allowDownloadForError")
    private boolean allowDownloadForError;

}

I am using spring-boot with jackson-dataformat-xml. When doing

XmlMapper xmlMapper = new XmlMapper();
ProfilesBatch profilesBatch = xmlMapper.readValue(data, ProfilesBatch.class);

Where data is the xml string

Am getting

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:Unrecognized field "maximumDownloadAttempts" (class sm.movasim.sftp.service.espgmodel.Profile), not marked as ignorable

Is there anything wrong with the classes and annotations? Note that all classes got setters and getters


Solution

  • Modify your ProfilesList class

        @Getter
        @Setter
        @XmlRootElement(name = "ProfilesList")
        public static class ProfilesList {
            @JacksonXmlElementWrapper(localName = "profile", useWrapping = false)
            @JacksonXmlProperty(localName = "profile")
            private List<Profile> profile;
        }
    

    Reason: Default @JacksonXmlElementWrapper requires a wrapper tag => Your <profile> list need to wrapped in another <profile></profile> level, set useWrapping = false to avoid it.