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

Jackson反序列化含大量动态节点的JSON时结果为空如何解决

方案1:无需自定义反序列化器(更简洁)

你的JSON结构本身就是标准键值对结构,Jackson原生支持直接反序列化为Map<String, Language>,完全不需要自己开发自定义反序列化逻辑:

  1. 首先定义基础Language实体类:
public class Language {
    // 存储动态的语言名称(比如English、Spanish)
    private String name;
    // 对应JSON里的hex字段
    private String hex;

    // 补全getter、setter、无参构造方法即可
}
  1. 直接执行反序列化再转List即可:
ObjectMapper objectMapper = new ObjectMapper();
// 第一步直接把JSON反序列为Map
Map<String, Language> langMap = objectMapper.readValue(
    new ClassPathResource("data/languages.json").getFile(),
    new TypeReference<Map<String, Language>>() {}
);
// 第二步把Map的键作为语言名赋值,直接转为目标List
List<Language> languages = langMap.entrySet().stream()
    .map(entry -> {
        Language lang = entry.getValue();
        lang.setName(entry.getKey());
        return lang;
    })
    .toList();

该方案代码量少、出错概率低,几千条数据的处理性能完全达标。


方案2:修复现有自定义反序列化器

你当前代码返回空列表的核心原因有两个:

  • @JsonDeserialize标注位置错误:你把注解加在了LanguageWrapper的languages字段上,但你的JSON根节点并没有languages字段,反序列化器拿到的节点为空,自然没有数据
  • 反序列化逻辑没有给Language对象赋值字段,空构建的对象当然没有有效数据

修复步骤:

  1. 完善反序列化器逻辑:
static class LanguageDeserializer extends StdDeserializer<ArrayList<Language>> {
    // 必须补全无参构造,指定反序列化目标类型
    public LanguageDeserializer() {
        super(ArrayList.class);
    }

    @Override
    public ArrayList<Language> deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException {
        final JsonNode node = jp.getCodec().readTree(jp);
        final Iterator<Map.Entry<String, JsonNode>> nodes = node.fields();
        final ArrayList<Language> results = new ArrayList<>();
        while (nodes.hasNext()) {
            Map.Entry<String, JsonNode> entry = nodes.next();
            // 取动态键作为语言名,取子节点的hex属性赋值
            Language lang = new Language();
            lang.setName(entry.getKey());
            lang.setHex(entry.getValue().get("hex").asText());
            results.add(lang);
        }
        return results;
    }
}
  1. 调整LanguageWrapper的注解位置:
// 注解加在类上,因为整个JSON根节点就是要反序列化的内容
@JsonDeserialize(using = Language.LanguageDeserializer.class)
public class LanguageWrapper extends ArrayList<Language> {
    // 直接继承ArrayList即可,不需要额外定义languages字段
}
  1. 原有反序列化调用代码无需修改,执行后就能拿到正常填充的列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 09:24:03