本文介绍在 jackson 中仅通过注解(不使用 typereference、自定义反序列化器或显式集合类型)将顶层为 json 数组(如 [{“name”:”a”},{“name”:”b”}])反序列化为含 list 字段的 java 封装类(如 getpersonsresponsedto)的可靠方案。核心在于合理使用 @jsoncreator 构造器注解。
Jackson 默认要求 JSON 结构与目标类结构严格匹配:若 JSON 以 [(START_ARRAY)开头,而目标类是普通 POJO(非集合类型),则会抛出 JsonMappingException: Can not deserialize instance of … out of START_ARRAY token 异常。这是因为 Jackson 期望顶层 JSON 是一个对象 {},而非数组 []。
要解决此问题且仅使用注解(不依赖 TypeReference> 或 Person[].class),关键在于告诉 Jackson:该类可通过一个接收 List 的构造器完成反序列化——即让 Jackson 将整个 JSON 数组直接绑定到该构造参数上。此时需配合 @JsonCreator 和 @JsonProperty(可选,但推荐显式声明)实现语义明确的映射。
以下是完整可行的实现:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
public class GetPersonsResponseDto {
public final List persons;
// ✅ 必须标注 @JsonCreator,且参数类型需与 JSON 数组元素类型一致(此处为 List)
@JsonCreator
public GetPersonsResponseDto(@JsonProperty("persons") List persons) {
this.persons = persons;
}
// 提供无参构造器(部分 Jackson 版本或配置下仍可能需要)
public GetPersonsResponseDto() {
this.persons = null;
}
}
public class Person {
public String name;
}
? 原理说明:当 Jackson 遇到顶层数组时,若目标类存在唯一带 @JsonCreator 的构造器,且其参数为 List(T 为可被自动解析的类型),它会尝试将整个 JSON 数组作为该参数值传入——无需额外配置,也无需 @JsonUnwrapped 或 @JsonValue 等干扰性注解。
✅ 使用方式保持简洁: