lenivius
lenivius

Reputation: 13

Trouble with understanding exception: "Cannot deserialize instance of `java.lang.String` out of START_OBJECT token" using ObjectMapper in Jackson

I cannot properly convert a JSON Object into POJO. I kind of understand where is the problem, but can't figure out, how to deal with it.

Here's all specific data to understand the issue:

JSONObject which I try to deserialize (understanding the values names isn't key to understand the problem):

[{"name":"Rafał","description":"Przykładowy opis profilu","location":"Lublin","interests":[{"0":"Gry komputerowe","1":"Muzyka","2":"Siłownia"}],"age":24,"rowid":2,"username":"lenivius"}]

My POJO class:

public class Users {
    private int rowid = 0, age;
    private String name, username, e_mail, password, description, location;
    private List<String> interests;

    public Users() {

    }

    public Users(int rowid, int age, String name, String username, String e_mail, String password, String description, String location, List<String> interests) {
        this.setRowid(rowid);
        this.setAge(age);
        this.setName(name);
        this.setUsername(username);
        this.setE_mail(e_mail);
        this.setPassword(password);
        this.setDescription(description);
        this.setLocation(location);
        this.setInterests(interests);
    }

    public int getRowid() {
        return rowid;
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public String getUsername() {
        return username;
    }

    public String getE_mail() {
        return e_mail;
    }

    public String getPassword() {
        return password;
    }

    public String getDescription() {
        return description;
    }

    public String getLocation() {
        return location;
    }

    public void setRowid(int rowid) {
        this.rowid = rowid;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

    public void setUsername(String username) {
        this.username = username;
    }
    public void setE_mail(String e_mail) {
        this.e_mail = e_mail;
    }

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

    public void setDescription(String description) {
        this.description = description;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public List<String> getInterests() {
        return interests;
    }

    public void setInterests(List<String> interests) {
        this.interests = interests;
    }
}

And lastly code line which causes the exception to happen:

resultUsers = objectMapper.readValue(responseString, Users[].class);

I can also post full exception message:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.lang.String out of START_OBJECT token at [Source: (String)"[{"name":"Rafał","description":"Przykładowy opis profilu","location":"Lublin","interests":[{"0":"Gry komputerowe","1":"Muzyka","2":"Siłownia"}],"age":24,"rowid":2,"username":"lenivius"}]"; line: 1, column: 92] (through reference chain: java.lang.Object[][0]->com.example.loveterests.Users["interests"]->java.util.ArrayList[0])

If I understand the problem correctly, then Jackson needs a list of String objects to properly convert JSON into POJO, but inside "interests" key there is a JSON Array, and that's probably where all the is the problem.

Upvotes: 0

Views: 5886

Answers (1)

Michał Ziober
Michał Ziober

Reputation: 38625

Problem is with interests property. In POJO it is represented by List<String> and in JSON Payload by JSON Array[JSON Object] - array with objects, not strings. You can use Map<String, Object> type to handle this:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
class Users {
    private int rowid = 0, age;
    private String name, username, e_mail, password, description, location;
    private List<Map<String, Object>> interests;
}

Upvotes: 1

Related Questions