使用Jackson与@JsonCreator反序列化无字段名数组行至POJO的问题
解决Jackson反序列化数组形式row到Java对象的问题
首先,我们来拆解你遇到的错误原因:
你用@JsonCreator注解的多参数构造函数来处理rows里的数组元素,但Jackson默认认为这种构造函数是用来解析带字段名的键值对JSON的,它期望每个构造函数参数都对应一个JSON字段名。但你的rows是纯数组结构,没有字段名,所以Jackson找不到数组元素和构造函数参数的对应关系——这就是报错的核心原因。另外,@JsonPropertyOrder是用来控制序列化时的属性顺序,或是处理键值对JSON的反序列化顺序,对数组转对象的场景并不生效。
接下来给你两种无需自定义反序列化器的简单解决方案:
方案一:给构造函数参数添加索引注解
给PojoVariant构造函数的每个参数加上@JsonProperty注解,并指定对应的数组索引(数组从0开始计数),明确告诉Jackson每个数组元素对应哪个构造参数:
@JsonCreator public PojoVariant( @JsonProperty(index = 0) String chr, @JsonProperty(index = 1) int pos, @JsonProperty(index = 2) String id, @JsonProperty(index = 3) String ref, @JsonProperty(index = 4) String alt, @JsonProperty(index = 5) int quality, @JsonProperty(index = 6) String filter, @JsonProperty(index = 7) String type, @JsonProperty(index = 8) String genotype, @JsonProperty(index = 9) int alignPos, @JsonProperty(index = 10) int basePos, @JsonProperty(index = 11) int signalPos ) { this.chr = chr; this.pos = pos; this.id = id; this.ref = ref; this.alt = alt; this.quality = quality; this.filter = filter; this.type = type; this.genotype = genotype; this.alignPos = alignPos; this.basePos = basePos; this.signalPos = signalPos; }
方案二:用@JsonFormat配合@JsonPropertyOrder(更简洁)
这种方式更贴合你原本的思路,不需要依赖构造函数的@JsonCreator注解:
- 在
PojoVariant类上添加@JsonFormat(shape = JsonFormat.Shape.ARRAY),告诉Jackson这个类需要以数组形式进行反序列化; - 保留你原来的
@JsonPropertyOrder,指定数组元素对应的属性顺序; - 添加无参构造函数(Jackson需要先实例化对象,再按顺序赋值),并确保所有属性都有getter和setter。
修改后的PojoVariant类:
@JsonFormat(shape = JsonFormat.Shape.ARRAY) @JsonPropertyOrder({ "chr", "pos", "id", "ref", "alt", "quality", "filter", "type", "genotype", "alignPos", "basePos", "signalPos" }) public class PojoVariant { private String chr; private int pos; private String id; private String ref; private String alt; private int quality; private String filter; private String type; private String genotype; private int alignPos; private int basePos; private int signalPos; // 必须添加无参构造函数 public PojoVariant() {} // 所有属性的getter和setter public String getChr() { return chr; } public void setChr(String chr) { this.chr = chr; } public int getPos() { return pos; } public void setPos(int pos) { this.pos = pos; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getRef() { return ref; } public void setRef(String ref) { this.ref = ref; } public String getAlt() { return alt; } public void setAlt(String alt) { this.alt = alt; } public int getQuality() { return quality; } public void setQuality(int quality) { this.quality = quality; } public String getFilter() { return filter; } public void setFilter(String filter) { this.filter = filter; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getGenotype() { return genotype; } public void setGenotype(String genotype) { this.genotype = genotype; } public int getAlignPos() { return alignPos; } public void setAlignPos(int alignPos) { this.alignPos = alignPos; } public int getBasePos() { return basePos; } public void setBasePos(int basePos) { this.basePos = basePos; } public int getSignalPos() { return signalPos; } public void setSignalPos(int signalPos) { this.signalPos = signalPos; } }
这样修改后,Jackson会自动按照@JsonPropertyOrder指定的顺序,把rows中的每个子数组元素依次赋值给PojoVariant的对应属性,完全匹配你的需求,而且不需要维护复杂的自定义反序列化逻辑。
内容的提问来源于stack exchange,提问作者Uwe
相关产品推荐
相关产品推荐

