理解异常的麻烦:“无法从 START_OBJECT 令牌中反序列化 `java.lang.String` 的实例”在 Jackson 中使用 ObjectMapper

Posted

技术标签:

【中文标题】理解异常的麻烦:“无法从 START_OBJECT 令牌中反序列化 `java.lang.String` 的实例”在 Jackson 中使用 ObjectMapper【英文标题】:Trouble with understanding exception: "Cannot deserialize instance of `java.lang.String` out of START_OBJECT token" using ObjectMapper in Jackson 【发布时间】:2021-04-07 11:20:22 【问题描述】:

我无法将JSON Object 正确转换为POJO。我有点明白问题出在哪里,但不知道如何处理。

以下是了解问题的所有具体数据:

JSONObject 我尝试反序列化(理解值名称不是理解问题的关键):

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

我的POJO 班级:

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;
    

最后是导致异常发生的代码行:

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

我也可以发布完整的异常消息:

com.fasterxml.jackson.databind.exc.MismatchedInputException:无法从 START_OBJECT 令牌中反序列化 java.lang.String 的实例 在 [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"]";行:1,列:92](通过引用链:java.lang.Object[][0]->com.example.loveterests.Users["interests"]->java.util.ArrayList[0])

如果我正确理解了问题,那么Jackson 需要一个String 对象列表才能正确地将JSON 转换为POJO,但是在“interests”键中有一个JSON Array,这可能就是都是问题。

【问题讨论】:

显然interests不是json中的字符串列表而是对象列表 .. 实际上列表包含一个对象,即字典/地图 【参考方案1】:

问题在于interests 属性。在POJO 中,它由List&lt;String&gt; 表示,在JSON Payload 中由JSON Array[JSON Object] 表示 - 带有对象的数组,而不是strings。你可以使用Map&lt;String, Object&gt; 类型来处理这个:

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;

【讨论】:

感谢您的回答。所以让我问你我是否正确:该列表将包含一个包含键值的字符串映射(在我的示例中为“0”、“1”、“2”和包含兴趣名称的对象? 没关系,想通了。您的回答确实解决了我的问题,非常感谢先生!

以上是关于理解异常的麻烦:“无法从 START_OBJECT 令牌中反序列化 `java.lang.String` 的实例”在 Jackson 中使用 ObjectMapper的主要内容,如果未能解决你的问题,请参考以下文章

无法读取文档:无法从 START_OBJECT 令牌中反序列化 java.lang.String 的实例

无法从 START_OBJECT 令牌中反序列化 `java.lang.Boolean` 的实例

JSON 解析错误:无法从 START_OBJECT 令牌中反序列化 `byte[]` 的实例

无法从 START_OBJECT 令牌中反序列化 java.util.ArrayList 的实例

JSON 解析错误:无法从 START_OBJECT 令牌中反序列化 java.util.ArrayList 的实例

无法从 START_OBJECT 令牌中反序列化 `java.lang.Long` 的实例;在 Spring Boot 帖子上