【问题标题】:How to deserialize json empty array如何反序列化json空数组
【发布时间】:2022-01-13 07:41:47
【问题描述】:

我的 JSON 如下所示:

{
  "name": "John",
  "age": 20,
  "skills": [
  ]
}

skills 如果不为空,则如下所示:

{
   "skills": [
       "skill_1": {
   }, 
   "skill_2": {
   }]
}

我需要将此 JSON 反序列化为 POJO:

public class Profile {
    public String name;
    public int age;
    @JsonDeserialize(using = SkillsMapDeserializer.class)
    public Map<String, Skill> skills;
}
public class Skill {
    public String skillName;
    public int age;
}

我的SkillsMapDeserializer 如下所示:

public class SkillsMapDeserializer extends JsonDeserializer<Map<String, Skill>> {
    @Override
    public Map<String, Skill> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        final Map<String, Skill> map = jsonParser.readValueAs(new TypeReference<Map<String, Skill>>() {
        });
        if (map == null) {
            return new HashMap<>();
        }
        return map;
    }
}

如果skills 不是空的,一切正常,但如果skills 是一个空数组,我会收到如下所示的异常:

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.LinkedHashMap<java.lang.Object,java.lang.Object>` out of START_ARRAY token

我该如何解决这个问题?

【问题讨论】:

  • 解决方法:使用 2 个步骤:首先将值作为技能列表读取,检查是否为空,如果不是,将值添加到地图中

标签: java json jackson jackson-databind


【解决方案1】:

从您的 json 数据来看,技能似乎是一个对象数组。

"skills": [],
 "skills": [
   "skill_1": {}, 
   "skill_2": {}
 ]

但是你的 java 将它定义为 Map

public Map<String, Skill> skills;

这就是为什么在尝试将数组直接转换为映射时出现异常的原因。 如果您无法更改 POJO 配置文件,您应该有一个将列表转换为 Map 的中间步骤。

public class SkillsMapDeserializer extends JsonDeserializer<Map<String, Skill>> {
    @Override
    public Map<String, Skill> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        final List<Map<String,Skill>> skills = jsonParser.readValueAs(new TypeReference<List<Map<String,Skill>>>>() {
        });
        return functionConvertListToMapWithParam(skills);
    }
}

【讨论】:

    【解决方案2】:

    技能不是地图。它应该是对象列表。尝试修改您的 POJO,如下所示:-

    public class Profile {
    
        @JsonProperty("name")
        private String name;
        @JsonProperty("age")
        private Integer age;
        @JsonProperty("skills")
        private List < Object > skills = null;
    
        @JsonProperty("name")
        public String getName() {
            return name;
        }
    
        @JsonProperty("name")
        public void setName(String name) {
            this.name = name;
        }
    
        @JsonProperty("age")
        public Integer getAge() {
            return age;
        }
    
        @JsonProperty("age")
        public void setAge(Integer age) {
            this.age = age;
        }
    
        @JsonProperty("skills")
        public List < Object > getSkills() {
            return skills;
        }
    
        @JsonProperty("skills")
        public void setSkills(List < Object > skills) {
            this.skills = skills;
        }
    
    }
    

    【讨论】:

    • skills 这是一张地图。而且这种方法不适合我。
    猜你喜欢
    • 2021-09-10
    • 2012-06-21
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 2015-10-23
    • 2015-10-18
    • 1970-01-01
    相关资源
    最近更新 更多