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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析DNS,个人版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 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>>>(){});,直接一步到位。



目录
相关文章
|
7天前
|
存储 算法 安全
Java面试题:Java内存模型及相关知识点深度解析,Java虚拟机的内存结构及各部分作用,详解Java的垃圾回收机制,谈谈你对Java内存溢出(OutOfMemoryError)的理解?
Java面试题:Java内存模型及相关知识点深度解析,Java虚拟机的内存结构及各部分作用,详解Java的垃圾回收机制,谈谈你对Java内存溢出(OutOfMemoryError)的理解?
13 0
|
1天前
|
Java
Java中的异常处理机制深度解析
本文旨在深入探讨Java语言中异常处理的机制,从基础概念到高级应用,全面剖析try-catch-finally语句、自定义异常以及异常链追踪等核心内容。通过实例演示和代码分析,揭示异常处理在Java程序设计中的重要性和应用技巧,帮助读者构建更为健壮和易于维护的程序。
|
3天前
|
监控 Java API
Java并发编程之线程池深度解析
【7月更文挑战第14天】在Java并发编程领域,线程池是提升性能、管理资源的关键工具。本文将深入探讨线程池的核心概念、内部工作原理以及如何有效使用线程池来处理并发任务,旨在为读者提供一套完整的线程池使用和优化策略。
|
7天前
|
安全 Java 开发者
Java面试题:Java内存模型解析,Java内存模型的基本概念和它的重要性,Java内存模型中的“可见性”和“有序性”,以及具体实现?
Java面试题:Java内存模型解析,Java内存模型的基本概念和它的重要性,Java内存模型中的“可见性”和“有序性”,以及具体实现?
12 1
|
7天前
|
存储 安全 Java
Java面试题:Java内存管理、多线程与并发框架:一道综合性面试题的深度解析,描述Java内存模型,并解释如何在应用中优化内存使用,阐述Java多线程的创建和管理方式,并讨论线程安全问题
Java面试题:Java内存管理、多线程与并发框架:一道综合性面试题的深度解析,描述Java内存模型,并解释如何在应用中优化内存使用,阐述Java多线程的创建和管理方式,并讨论线程安全问题
9 0
|
7天前
|
存储 并行计算 安全
Java面试题:Java内存管理、多线程与并发框架的面试题解析与知识点梳理,深入Java内存模型与垃圾回收机制,Java多线程机制与线程安全,Java并发工具包与框架的应用
Java面试题:Java内存管理、多线程与并发框架的面试题解析与知识点梳理,深入Java内存模型与垃圾回收机制,Java多线程机制与线程安全,Java并发工具包与框架的应用
12 0
|
7天前
|
安全 Java
Java多线程中的锁机制:深入解析synchronized与ReentrantLock
Java多线程中的锁机制:深入解析synchronized与ReentrantLock
10 0
|
28天前
|
XML Java 数据格式
深度解析 Spring 源码:从 BeanDefinition 源码探索 Bean 的本质
深度解析 Spring 源码:从 BeanDefinition 源码探索 Bean 的本质
29 3
|
13天前
|
存储 安全 Java
深度长文解析SpringWebFlux响应式框架15个核心组件源码
以上是Spring WebFlux 框架核心组件的全部介绍了,希望可以帮助你全面深入的理解 WebFlux的原理,关注【威哥爱编程】,主页里可查看V哥每天更新的原创技术内容,让我们一起成长。
|
14天前
|
关系型数据库 分布式数据库 数据库
PolarDB-X源码解析:揭秘分布式事务处理
【7月更文挑战第3天】**PolarDB-X源码解析:揭秘分布式事务处理** PolarDB-X,应对大规模分布式事务挑战,基于2PC协议确保ACID特性。通过预提交和提交阶段保证原子性与一致性,使用一致性快照隔离和乐观锁减少冲突,结合故障恢复机制确保高可用。源码中的事务管理逻辑展现了优化的分布式事务处理流程,为开发者提供了洞察分布式数据库核心技术的窗口。随着开源社区的发展,更多创新实践将促进数据库技术进步。
20 3