Jackson XML parsing MismatchedInputException

784 Views Asked by At

I want to parse Below XML file into Java Object using Jackson. But it shows MismatchedInputException message is become null. I specified feild that I need in Employee class. And using these fields I need to create Employee objects.

d.xml -> the input xml file

<Messages>
    <Message>
        <Uumid>45</Uumid>
        <UumidSuffix>ER.79</UumidSuffix>
        <CreationDate>20-05-2020</CreationDate>
        <Data>FRHF#%^G</Data>
    </Message>
    <Message>
        <Uumid>89</Uumid>
        <UumidSuffix>RT.12</UumidSuffix>
        <CreationDate>26-05-2020</CreationDate>
        <Data>FGRH#%^</Data>
    </Message>
</Messages>

Messages.java

package org.example;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

import java.lang.annotation.Documented;
import java.util.Arrays;


@JacksonXmlRootElement(localName ="Messages")
public final class Messages {
    @JacksonXmlElementWrapper(localName = "Message",useWrapping = true)
    private Message[] message;
    public Messages(){}
    public Messages(Message[] message){
        this.message=message;
    }

    public Message[] getMessage() {
        return message;
    }
    public void setMessage(Message[] message) {
        this.message = message;
    }


    @Override
    public String toString() {
        return "Messages{" +
                "message=" + Arrays.toString(message) +
                '}';
    }
}

Message.java

package org.example;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

import javax.xml.bind.annotation.XmlAccessorOrder;


public class Message {
    @JacksonXmlProperty(localName = "Uumid")
    private String uumid;
    @JacksonXmlProperty(localName = "UumidSuffix")
    private String uumidSuffix;
    @JacksonXmlProperty(localName = "CreationDate")
    private String creationDate;

    public Message() {}
    public Message(String uumid,String uumidSuffix,String creationDate){
        this.uumid=uumid;
        this.uumidSuffix=uumidSuffix;
        this.creationDate=creationDate;
    }

    public String getUumid() {
        return uumid;
    }

    public void setUumid(String uumid) {
        this.uumid = uumid;
    }

    public String getUumidSuffix() {
        return uumidSuffix;
    }

    public void setUumidSuffix(String uumidSuffix) {
        this.uumidSuffix = uumidSuffix;
    }

    public String getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(String creationDate) {
        this.creationDate = creationDate;
    }

    @Override
    public String toString() {
        return "Message{" +
                "uumid='" + uumid + '\'' +
                ", uumidSuffix='" + uumidSuffix + '\'' +
                ", CreationDate='" + creationDate + '\'' +
                '}';
    }
}

Parser.java

package org.example;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

public class Parser {
    public static void main(String[] args) throws IOException {
        ObjectMapper objectMapper=new XmlMapper();

        Messages messages=objectMapper.readValue(StringUtils.toEncodedString(Files.readAllBytes(Paths.get("disk/d.xml")), StandardCharsets.UTF_8),Messages.class);
        System.out.println(messages);
    }
}

when executes this error shows

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `org.example.Message` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('asdf')
 at [Source: (StringReader); line: 3, column: 20] (through reference chain: org.example.Messages["Message"]->java.lang.Object[][0])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1455)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1081)
    at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:371)
    at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:323)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1408)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:176)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:166)
    at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:195)
    at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:21)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:293)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:156)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4524)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3466)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3434)
    at org.example.Parser.main(Parser.java:17)

Process finished with exit code 1

maven dependencies

<dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>com.fasterxml.jackson.dataformat</groupId>
          <artifactId>jackson-dataformat-xml</artifactId>
          <version>2.11.2</version>
        </dependency>
        <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-core</artifactId>
          <version>2.11.2</version>
        </dependency>
        <dependency>
          <groupId>org.apache.commons</groupId>
          <artifactId>commons-lang3</artifactId>
          <version>3.5</version>
        </dependency>
        <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.11.2</version>
        </dependency>
        <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-annotations</artifactId>
          <version>2.11.2</version>
        </dependency>
      </dependencies>
1

There are 1 best solutions below

0
On

Your current code tells Jackson that your messages should be wrapped into a wrapper tag, so it expects XML that looks something like this:

<Messages>
    <Message> <!-- this is the wrapper -->
        <Message>
            <Uumid>...</Uumid>
            ...
         </Message>
         <Message>
             ...
         </Message>
    </Message>
</Messages>

To fix this, you'll have to tell Jaskcon to not use the wrapper, and that the children are called "Message". In your Messages class you have to update annotations on the message field to the following:

@JacksonXmlElementWrapper(useWrapping = false)
@JacksonXmlProperty(localName = "Message")
private Message[] message;

(BTW, why not call this field messages?)