如何在对象列表场景使用@JsonUnwrapped解决Jackson反序列化问题
Jackson反序列化嵌套数组对象失败的解决方案
问题根源
- 错误使用
@JsonUnwrapped注解:该注解仅支持普通POJO对象的扁平化展开,不支持List等集合类型,加在集合属性上会导致反序列化逻辑异常。 - JSON结构与类定义不匹配:目标JSON中
depositos数组的每一项不是直接的Deposito对象,而是外层包裹了一层仅包含deposito字段的对象,原有类定义没有对应这层包装结构。 @JsonRootName注解作用范围不符:该注解默认仅作用于整个JSON的根对象,需要配合全局配置DeserializationFeature.UNWRAP_ROOT_VALUE才会生效,且不会自动作用于集合内的元素。
解决方案
方案1:新增中间包装类(最稳妥,无需额外配置)
新增一个类承接数组元素的外层包装:
public class DepositoWrapper { private Deposito deposito; // 补充Getter、Setter方法 public Deposito getDeposito() { return deposito; } public void setDeposito(Deposito deposito) { this.deposito = deposito; } }
修改外层类的属性定义,删掉错误的@JsonUnwrapped注解:
@JsonProperty(value ="depositos") private List<DepositoWrapper> depositos;
后续使用时遍历depositos列表,调用getDeposito()即可拿到目标对象。
方案2:不新增类,开启集合元素包装识别
如果不想新增包装类,且使用的Jackson版本在2.7以上,可以给Deposito类保留@JsonRootName注解,同时给外层的集合属性添加@JsonFormat注解指定元素为包装对象:
修改外层类属性:
@JsonProperty(value ="depositos") @JsonFormat(shape = JsonFormat.Shape.WRAPPER_OBJECT) private List<Deposito> depositos;
额外优化建议
JSON中saldo、saldoVirtual字段是高精度字符串数值,反序列化为Double可能存在精度丢失问题,建议将这两个字段的类型修改为BigDecimal,匹配高精度场景的使用需求。
内容的提问来源于stack exchange,提问作者Rodrigo Vidal
相关产品推荐
相关产品推荐

