Daxforcel
Daxforcel

Reputation: 35

Java - cant deserialize xml

Cant wrap my head around this. This is my xml file

<?xml version="1.0" encoding="UTF-8"?>
<users>
    <user>
        <username>Tom</username>
        <password>123</password>
    </user>
    <user>
        <username>Moc</username>
        <password>1234</password>
    </user>
</users>

And these are my classes in Java:

Users.java

@Data
public class Users {
    private List<User> user;
}

User.java

@Data
public class User {
    private String username;
    private String password;
}

For some reason I am constantly getting error: "com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "user"

My loading method is here:

            ClassLoader classLoader = getClass().getClassLoader();
            File file = new File(classLoader.getResource("Users.xml").getFile());
            String xmlContent = XMLReader(new FileInputStream(file));
            XmlMapper xmlMapper = new XmlMapper();
            Users users = xmlMapper.readValue(xmlContent, Users.class);

XMLReader is just method which reads xml file line by line. Thanks for help in advance.

Upvotes: 1

Views: 133

Answers (1)

Roberto Mozzicato
Roberto Mozzicato

Reputation: 94

There are some issues in your code:

  1. You are trying to parse the Users class using a <users> tag (lowercase). This will not work unless you annotate the class with @JacksonXmlRootElement(localName = "users")
  2. in the line String xmlContent = XMLReader(new FileInputStream(file)) I don't know what XMLReader is (maybe a misnamed method), anyway you don't need to load your entire xml in a string in memory, this is inefficient, just pass to readValue() you file's inputstream.
  3. By default Jackson tries to create a wrapper element for the lists, so it expect your xml to have this structure:
<users>
  <user>   <--- this is the list element wrapper
    <user>   <--- this is the actual "user"
      <username>
      <password>
    </user>
  </user>
</users>

If you want to avoid the wrapper, you have to annotate the user list with @JacksonXmlElementWrapper(useWrapping = false)

Below a working example for class Users working for your xml example

@JacksonXmlRootElement(localName = "users")
@Data
public class Users {
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<User> user;
}

And this is a working snippet to parse the file:

ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("Users.xml").getFile());
XmlMapper xmlMapper = new XmlMapper();
Users users = xmlMapper.readValue(new FileInputStream(file), Users.class);

Upvotes: 1

Related Questions