jackson解析泛型的正确写法 | Java Debug 笔记

简介: jackson解析泛型的正确写法本期 4ye 又带来了一个小 bug 啦,如下,小伙伴们是否见过这个异常呢?in unnamed module of loader 'app'bug描述上次使用jackson进行数据转换的时候发生了下面这个错误。java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class com.example.demo.model.User (java.util.LinkedHashMap is in module java.base of loader 'bo

jackson解析泛型的正确写法



本期 4ye 又带来了一个小 bug 啦,如下,小伙伴们是否见过这个异常呢?


in unnamed module of loader 'app'


bug描述


上次使用jackson进行数据转换的时候发生了下面这个错误。


java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class com.example.demo.model.User (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; com.example.demo.model.User is in unnamed module of loader 'app')
复制代码


网络异常,图片无法展示
|


错误代码如下:


  1. 第一种写法


ObjectMapper objectMapper = new ObjectMapper();
  ResultDTO<Object> resultDTO = objectMapper.readValue(body, ResultDTO.class);
  List<String> data = (List<String>)resultDTO.getData();
  List<User> list = objectMapper.convertValue(data, new TypeReference<List<User>>() { });
  System.out.println(data);  
  System.out.println(list);
  System.out.println(list.get(0)); *//这里报错了* 
复制代码


  1. 第二种写法


ObjectMapper objectMapper = new ObjectMapper();
  Map<String, List<User>> map = objectMapper.readValue(body, Map.class);
  List<User> data = map.get("data");
  User user = data.get(0);
复制代码


代码上body是从服务器获取到的数据,格式是{"data": [{},{}]}


转换成resultDTO也是正常的,可以拿到对应的data, 转换成list也是正常的!


然后bug来了!😱 去获取list中的一个元素就报错上面那个错了🙃🙄 两种写法都会报这个错误。。


整个人都懵了,无奈开启了 debug 之路~


ResultDTO代码如下:


*/***
 *** *@author* *RYZEYANG*
 ** @date 2020/10/24 14:50*
 **/*
@Data
public class ResultDTO<T> {
  */***
   ** 描述*
   **/*
  private String msg;
  */***
   ** 状态码*
   **/*
  private String code;
  */***
   ** 数据*
   **/*
  private T data;
}
复制代码


解决办法


突然想到自己之前也做过json的解析呀,那会都很顺利地解决的🐖


想着不用一步到位,先拿到那个节点的数据,再去转换看看。结果真的成功了!


方案一


代码如下:


ObjectMapper objectMapper = new ObjectMapper();
  JsonNode jsonNode = objectMapper.readTree(body);
  System.out.println(jsonNode);
  JsonNode data = jsonNode.get("data");
  System.out.println(data);
  JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, User.class);
  List<User> users = objectMapper.readValue(data.toString(), javaType);
复制代码


错误分析之错误代码的第一种写法


因为前面ojectMapper.readValue(body, ResultDTO.class);这里没法定义泛型T


的类型。。所以jackson使用了这个LinkedHashMap来存解析的数据🐖


网络异常,图片无法展示
|


错误分析之错误代码的第二种写法


objectMapper.readValue(body, Map.class); 这里也是,没办法指定泛型🐖,

所以jackson还是使用了这个LinkedHashMap来存解析的数据


网络异常,图片无法展示
|


分析到这里有点悟出来了!怎么才能将泛型加上去啊!🐖


方案二:使用泛型的正确写法如下:


ResultDTO<List<User>> listResultDTO = objectMapper.readValue(body, new TypeReference<ResultDTO<List<User>>>(){});
复制代码


debug看一下,终于正确了!!😁


网络异常,图片无法展示
|


结论


jaskson 解析使用泛型类的时候,有两种做法


  1. 局部解析🐖:


  • 通过readTree()去获取对应的jsonnode节点: JsonNode jsonNode = objectMapper.readTree(body);


  • 再获取到对应节点的数据jsonNode.get("data");


  • 最后通过readValue():objectMapper.readValue(data.toString(), new TypeReference<List<User>>(){}); 解析得到对应的数据


  1. 直接解析🐖:


  • objectMapper.readValue(body, new TypeReference<ResultDTO<List<User>>>(){});,直接一步到位。



目录
相关文章
|
3月前
|
机器学习/深度学习 JSON Java
Java调用Python的5种实用方案:从简单到进阶的全场景解析
在机器学习与大数据融合背景下,Java与Python协同开发成为企业常见需求。本文通过真实案例解析5种主流调用方案,涵盖脚本调用到微服务架构,助力开发者根据业务场景选择最优方案,提升开发效率与系统性能。
906 0
|
3月前
|
Java
Java的CAS机制深度解析
CAS(Compare-And-Swap)是并发编程中的原子操作,用于实现多线程环境下的无锁数据同步。它通过比较内存值与预期值,决定是否更新值,从而避免锁的使用。CAS广泛应用于Java的原子类和并发包中,如AtomicInteger和ConcurrentHashMap,提升了并发性能。尽管CAS具有高性能、无死锁等优点,但也存在ABA问题、循环开销大及仅支持单变量原子操作等缺点。合理使用CAS,结合实际场景选择同步机制,能有效提升程序性能。
|
3月前
|
Java 开发者
Java并发编程:CountDownLatch实战解析
Java并发编程:CountDownLatch实战解析
471 100
|
4月前
|
存储 缓存 Java
Java数组全解析:一维、多维与内存模型
本文深入解析Java数组的内存布局与操作技巧,涵盖一维及多维数组的声明、初始化、内存模型,以及数组常见陷阱和性能优化。通过图文结合的方式帮助开发者彻底理解数组本质,并提供Arrays工具类的实用方法与面试高频问题解析,助你掌握数组核心知识,避免常见错误。
|
2月前
|
存储 安全 Java
《数据之美》:Java集合框架全景解析
Java集合框架是数据管理的核心工具,涵盖List、Set、Map等体系,提供丰富接口与实现类,支持高效的数据操作与算法处理。
|
3月前
|
安全 Java
Java之泛型使用教程
Java之泛型使用教程
286 10
|
3月前
|
Java 开发者
Java 函数式编程全解析:静态方法引用、实例方法引用、特定类型方法引用与构造器引用实战教程
本文介绍Java 8函数式编程中的四种方法引用:静态、实例、特定类型及构造器引用,通过简洁示例演示其用法,帮助开发者提升代码可读性与简洁性。
|
2月前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
3月前
|
安全 Java API
Java SE 与 Java EE 区别解析及应用场景对比
在Java编程世界中,Java SE(Java Standard Edition)和Java EE(Java Enterprise Edition)是两个重要的平台版本,它们各自有着独特的定位和应用场景。理解它们之间的差异,对于开发者选择合适的技术栈进行项目开发至关重要。
468 1
|
4月前
|
存储 缓存 算法
Java数据类型与运算符深度解析
本文深入解析Java中容易混淆的基础知识,包括八大基本数据类型(如int、Integer)、自动装箱与拆箱机制,以及运算符(如&与&&)的使用区别。通过代码示例剖析内存布局、取值范围及常见陷阱,帮助开发者写出更高效、健壮的代码,并附有面试高频问题解析,夯实基础。

推荐镜像

更多
  • DNS