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

如何使用Jackson ObjectMapper反序列化双层嵌套JSON列表

嘿,我来帮你解决这个Jackson反序列化的问题!你遇到的问题大概率是实体类的层级结构没和JSON完全对应上,毕竟这个嵌套结构确实容易踩坑。先给你拆解清楚解决方案:

1. 先明确你的JSON结构

先把你给出的JSON结构标清楚,方便对应实体类:

{
  "results": {
    "Assessments": {
      "Assessment": [
        {
          "assessor": "",
          "buildingName": "Emerald Palace Project",
          "certBody": "",
          ...
        }
      ]
    }
  }
}

注意这里的层级是:results → 包含Assessments对象 → Assessments对象里包含Assessment数组,三层嵌套,很多人会跳过中间的Assessments对象层,直接把数组挂在results下面,这就是核心错误!

2. 创建完全匹配的Java实体类

你需要创建对应层级的实体类(可以用Lombok简化代码),每个类的属性要和JSON的键严格对应,大小写不一致时用@JsonProperty注解指定:

顶层响应类(ApiResponse)

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;

// 不用Lombok就手动写无参构造、getter、setter
@Data
@NoArgsConstructor
public class ApiResponse {
    @JsonProperty("results")
    private Results results;
}

Results类

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class Results {
    @JsonProperty("Assessments")
    private AssessmentsData assessments;
}

AssessmentsData类(中间层,别漏了!)

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;

@Data
@NoArgsConstructor
public class AssessmentsData {
    @JsonProperty("Assessment")
    private List<Assessment> assessmentList;
}

Assessment实体类(最终数据类)

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class Assessment {
    @JsonProperty("assessor")
    private String assessor;
    
    @JsonProperty("buildingName")
    private String buildingName;
    
    @JsonProperty("certBody")
    private String certBody;
    
    // 其他字段根据JSON补充
}

3. 正确配置ObjectMapper并执行反序列化

你的配置已经开启了忽略未知属性,这没问题,再补充一些常用配置确保兼容性:

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;

public class DeserializeExample {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        // 忽略未知属性,你已经加了,很好
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 允许空字符串转成null,避免空字符串导致的类型错误
        mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
        
        // 你的JSON字符串
        String json = "{\"results\":{ \"Assessments\":{ \"Assessment\":[{ \"assessor\":\"\", \"buildingName\":\"Emerald Palace Project\", \"certBody\":\"\" }]}}}";
        
        // 反序列化
        ApiResponse response = mapper.readValue(json, ApiResponse.class);
        
        // 获取Assessment列表
        List<Assessment> assessments = response.getResults().getAssessments().getAssessmentList();
        System.out.println(assessments.get(0).getBuildingName()); // 输出Emerald Palace Project
    }
}

常见踩坑点提醒

  • 漏了中间的AssessmentsData层:直接把List<Assessment>放在Results里,会导致Jackson找不到对应节点,直接返回null;
  • 字段名大小写不匹配:比如Java里写assessments但JSON是Assessments,必须用@JsonProperty指定;
  • 忘记用List接收数组:把Assessment写成单个对象而不是List<Assessment>,会抛出数组转对象的异常;
  • 实体类没有无参构造:Jackson必须通过无参构造实例化对象,所以每个实体类都要有public无参构造(Lombok的@NoArgsConstructor会自动生成);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:32:43