You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将JSON值数组转换为Java对象及解决Jackson反序列化不匹配异常

解决Jackson反序列化JSON数组到Java对象的踩坑经历

最近我在把一段特定结构的JSON数组转换成Java对象时,遇到了Jackson的反序列化错误,折腾了好一会儿才搞定,这里把问题和解决方法分享给大家。

首先看一下我要处理的JSON结构:

[ 
  { "Dummy": { "attr": "PRIMITIVE", "value": { "Initial": "M", "Name": "Potato" } } }, 
  { "Dummy": { "attr": "PRIMITIVE", "value": { "Initial": "A", "Name": "Potatoo1" } } } 
]

最开始我写的反序列化代码是这样的:

ObjectMapper mapper = new ObjectMapper();
Dummy[] myObjects = mapper.readValue(resultStr, Dummy[].class);

对应的Java类定义是:

public class Dummy{
  public String attr;
  public value val;
}
public class value {
  public String Initial;
  public String Name;
}

结果一运行就炸了,抛出了这个错误:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type com.example.demo.Dummy from Array value

问题分析

仔细对比JSON和Java类的结构,发现两个核心问题:

  1. 结构不匹配:JSON数组里的每个元素并不是直接的Dummy对象,而是一个包含"Dummy"键的对象,这个键的值才是真正的Dummy结构。Jackson找不到对应的映射,自然报错。
  2. 字段名不匹配:Java类里的字段叫val,但JSON里对应的键是value,默认情况下Jackson会严格按字段名匹配,这也会导致反序列化失败。

解决方案

找到了问题根源,就有两种靠谱的解决办法:

方法一:用包装类适配JSON结构

先创建一个包装类,用来对应数组里的每个元素:

public class DummyWrapper {
    private Dummy Dummy; // 字段名要和JSON里的键完全一致,包括大小写

    // 必须添加getter和setter,Jackson依赖它们完成序列化/反序列化
    public Dummy getDummy() {
        return Dummy;
    }

    public void setDummy(Dummy dummy) {
        Dummy = dummy;
    }
}

然后修正原来的Dummy类,把val改成value,同时把类名value改成Value(符合Java命名规范):

public class Dummy {
    public String attr;
    public Value value;
}

public class Value {
    public String Initial;
    public String Name;
}

最后修改反序列化代码,先转换成包装类数组,再提取出Dummy对象:

ObjectMapper mapper = new ObjectMapper();
DummyWrapper[] wrappers = mapper.readValue(resultStr, DummyWrapper[].class);
// 转成List方便后续操作
List<Dummy> dummyList = Arrays.stream(wrappers)
                              .map(DummyWrapper::getDummy)
                              .collect(Collectors.toList());

方法二:用Jackson注解解包根值

如果不想额外创建包装类,可以用@JsonRootName注解配合配置来解决:

先给Dummy类加上注解,指定它对应的根键名称:

import com.fasterxml.jackson.annotation.JsonRootName;

@JsonRootName("Dummy") // 对应JSON里的外层键名
public class Dummy {
    public String attr;
    public Value value;
}

public class Value {
    public String Initial;
    public String Name;
}

然后给ObjectMapper开启解包根值的配置,再进行反序列化:

ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE); // 开启自动解包根节点
Dummy[] myObjects = mapper.readValue(resultStr, Dummy[].class);

这样Jackson就会自动把每个数组元素里的"Dummy"键对应的内容,解包成Dummy对象,完美适配结构。

两种方法都能解决问题,大家可以根据自己的项目场景选择合适的方式。

内容的提问来源于stack exchange,提问作者PotatoGod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 17:07:38