Jackson反序列化JSON为自定义对象列表时得到LinkedHashMap问题
问题根因
反序列化得到LinkedHashMap而非自定义Accounts对象的核心原因是Java泛型擦除:调用mapper.readValue(accounts, Result.class)时,Jackson运行时无法获取Result携带的泛型参数List<Accounts>,对未知结构的JSON对象,默认会反序列化为LinkedHashMap类型存入Map。
另外贴出的代码存在两处结构错误,即使解决泛型问题也无法正常解析:
Result类中定义的属性为data,但getter方法命名为getAccounts(),返回的是未定义的accounts变量,存在语法错误Accounts类未定义accountDetails属性,和JSON结构不匹配,无法映射对应字段
修复步骤
1. 对齐实体类与JSON结构
修正两个实体类的字段、方法定义,保证和JSON字段一一对应:
// 修正后的Result泛型类 public class Result<T>{ private Map<String, T> data = new LinkedHashMap<>(); public Map<String, T> getData() { return data; } public void setData(Map<String, T> data) { this.data = data; } }
// 修正后的Accounts类 @Getter @Setter @ToString public class Accounts{ // 匹配JSON中数组元素的accountDetails字段 private AccountDetails accountDetails; @Getter @Setter public static class AccountDetails{ private String accountId; private String accountType; } }
2. 传入完整泛型类型解决擦除问题
使用Jackson提供的TypeReference携带完整嵌套泛型信息,修改反序列化代码如下:
String content = Resources.asByteSource(Resources.getResource("account.json")) .asCharSource(Charsets.UTF_8) .read(); ObjectMapper mapper = new ObjectMapper(); // 传入完整泛型类型,和JSON结构完全匹配 Result<Map<String, List<Accounts>>> finalResult = mapper.readValue( content, new TypeReference<Result<Map<String, List<Accounts>>>>() {} ); // 直接获取解析完成的账号对象列表 List<Accounts> accountList = finalResult.getData().get("account");
补充说明
如果反序列化时只传入裸的Result.class,Jackson仅能识别外层Result类型,内部data属性Map的value泛型参数T没有具体类型指向,遇到JSON对象就会默认用LinkedHashMap存储键值对,这就是出现LinkedHashMap列表的根本原因。通过TypeReference传入完整的嵌套泛型定义后,Jackson就能按照指定类型递归完成全量反序列化,得到预期的自定义对象。
内容的提问来源于stack exchange,提问作者Nishant
相关产品推荐
相关产品推荐

