1

I have a User class and a Json file containing an array of Users. When trying to deserialize those users and get a List I'm getting a JsonMappingException, I don't understand what's wrong.

This is my User class:

public class User {

private StringProperty username;
private StringProperty password;

private StringProperty name;
private StringProperty surname;
private StringProperty email;
private StringProperty company;
private StringProperty phone;

private BooleanProperty canMonitorize;
private BooleanProperty canCreateProject;
private BooleanProperty canOpenProject;
private BooleanProperty admin;

public User() {}

public User(String user, String pass, String name, String surname, String email, String company, String phone,
        boolean monitorize, boolean createP, boolean openP, boolean admin) {

    this.username = new SimpleStringProperty(user);
    this.password = new SimpleStringProperty(pass);

    this.name = new SimpleStringProperty(name);
    this.surname = new SimpleStringProperty(surname);
    this.email = new SimpleStringProperty(email);
    this.company = new SimpleStringProperty(company);
    this.phone = new SimpleStringProperty(phone);

    this.canMonitorize = new SimpleBooleanProperty(monitorize);
    this.canCreateProject = new SimpleBooleanProperty(createP);
    this.canOpenProject = new SimpleBooleanProperty(openP);
    this.admin =  new SimpleBooleanProperty(admin);

}

public String getUsername() {
    return username.get();
}

public void setUsername(String username) {
    this.username.set(username);
}

public String getPassword() {
    return password.get();
}

public void setPassword(String password) {
    this.password.set(password);
}

public String getName() {
    return name.get();
}

public void setName(String name) {
    this.name.set(name);
}

public String getSurname() {
    return surname.get();
}

public void setSurname(String surname) {
    this.surname.set(surname);
}

public String getEmail() {
    return email.get();
}

public void setEmail(String email) {
    this.email.set(email);
}

public String getCompany() {
    return company.get();
}

public void setCompany(String company) {
    this.company.set(company);
}

public String getPhone() {
    return phone.get();
}

public void setPhone(String phone) {
    this.phone.set(phone);
}

public boolean canMonitorize() {
    return canMonitorize.get();
}

public void setCanMonitorize(boolean canMonitorize) {
    this.canMonitorize.set(canMonitorize);
}

public boolean canCreateProject() {
    return canCreateProject.get();
}

public void setCanCreateProject(boolean canCreateProject) {
    this.canCreateProject.set(canCreateProject);
}

public boolean canOpenProject() {
    return canOpenProject.get();
}

public void setCanOpenProject(boolean canOpenProject) {
    this.canOpenProject.set(canOpenProject);
}

public boolean isAdmin() {
    return admin.get();
}

public void setAdmin(boolean isAdmin) {
    this.admin.set(isAdmin);
}
}

And this is an example of the Json file:

[{"username":"admin","password":"blablabla","name":"admin","surname":"admin","email":"admin@admin.com","company":"admin","phone":"admin","admin":true}]

This is the method that should obtain the list of users:

public static List<User> getUsers(String jsonArrayStr) {

    ObjectMapper mapper = new ObjectMapper();

    List<User> ret;
    try {

        User[] userArray = mapper.readValue(jsonArrayStr, User[].class);
        ret = new ArrayList<>(Arrays.asList(userArray));

    } catch (IOException e) {
        return new ArrayList<User>();
    }

    return ret;

}

The error I get when executing the code:

com.fasterxml.jackson.databind.JsonMappingException: N/A (through reference chain: object.User["username"])
AwesomeGuy
  • 537
  • 1
  • 6
  • 17
  • Possible duplicate of [JSON: JsonMappingException while try to deserialize object with null values](https://stackoverflow.com/questions/18096589/json-jsonmappingexception-while-try-to-deserialize-object-with-null-values) – Ahmed Emad Oct 07 '19 at 10:47

1 Answers1

2

When you have a public 0-args constructor it is used by default to create new POJO instance. But in your case you should not allow to create instance with default constructor because all internal fields are null and when Jackson tries to set first property, username, NullPointerException is thrown. Try to declare your constructor as below and remove default one:

@JsonCreator
public User(@JsonProperty("username") String user,
            @JsonProperty("password") String pass,
            @JsonProperty("name") String name,
            @JsonProperty("surname") String surname,
            @JsonProperty("email") String email,
            @JsonProperty("company") String company,
            @JsonProperty("phone") String phone,
            @JsonProperty("monitorize") boolean monitorize,
            @JsonProperty("createP") boolean createP,
            @JsonProperty("openP") boolean openP,
            @JsonProperty("admin") boolean admin) {
            //your code;
}

Also, your getUsers method could look like this:

public static List<User> getUsers(String json) {
    final ObjectMapper mapper = new ObjectMapper();

    try {
        final JavaType collectionType = mapper.getTypeFactory().constructCollectionType(List.class, User.class);
        return mapper.readValue(json, collectionType);
    } catch (IOException e) {
        //You should not hide exceptions. Try to log it at least.
        //But probably application should not start when app configuration is missing or wrong.
        e.printStackTrace();
        return Collections.emptyList();
    }
}
Michał Ziober
  • 37,175
  • 18
  • 99
  • 146