如何使用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
相关产品推荐
相关产品推荐

