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

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



目录
相关文章
|
27天前
|
XML JavaScript Java
【JAVA XML 探秘】DOM、SAX、StAX:揭秘 Java 中 XML 解析技术的终极指南!
【8月更文挑战第25天】本文详细探讨了Java中三种主流的XML解析技术:DOM、SAX与StAX。DOM将XML文档转换为树状结构,便于全方位访问和修改;SAX采取事件驱动模式,适用于大型文件的顺序处理;StAX则兼具DOM和SAX的优点,支持流式处理和随机访问。文中提供了每种技术的示例代码,帮助读者理解如何在实际项目中应用这些解析方法。
65 1
|
6天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
|
4天前
|
Java 程序员 开发者
Java中的异常处理机制深度解析
本文旨在深入探讨Java中异常处理的核心概念与实际应用,通过剖析异常的本质、分类、捕获及处理方法,揭示其在程序设计中的关键作用。不同于常规摘要,本文将直接切入主题,以简明扼要的方式概述异常处理的重要性及其在Java编程中的应用策略,引导读者快速把握异常处理的精髓。
|
3天前
|
安全 Java 开发者
Java并发编程中的锁机制解析
本文深入探讨了Java中用于管理多线程同步的关键工具——锁机制。通过分析synchronized关键字和ReentrantLock类等核心概念,揭示了它们在构建线程安全应用中的重要性。同时,文章还讨论了锁机制的高级特性,如公平性、类锁和对象锁的区别,以及锁的优化技术如锁粗化和锁消除。此外,指出了在高并发环境下锁竞争可能导致的问题,并提出了减少锁持有时间和使用无锁编程等策略来优化性能的建议。最后,强调了理解和正确使用Java锁机制对于开发高效、可靠并发应用程序的重要性。
13 3
|
6天前
|
存储 监控 算法
Java中的内存管理与垃圾回收机制解析
本文深入探讨了Java编程语言中的内存管理策略和垃圾回收机制。首先介绍了Java内存模型的基本概念,包括堆、栈以及方法区的划分和各自的功能。进一步详细阐述了垃圾回收的基本原理、常见算法(如标记-清除、复制、标记-整理等),以及如何通过JVM参数调优垃圾回收器的性能。此外,还讨论了Java 9引入的接口变化对垃圾回收的影响,以及如何通过Shenandoah等现代垃圾回收器提升应用性能。最后,提供了一些编写高效Java代码的实践建议,帮助开发者更好地理解和管理Java应用的内存使用。
|
7天前
|
Java 开发者
深入解析Java中的异常处理机制
本文将深入探讨Java中异常处理的核心概念和实际应用,包括异常的分类、捕获、处理以及最佳实践。我们将通过具体示例展示如何有效使用try-catch块、throws关键字和自定义异常类,以帮助读者更好地理解和应用Java异常处理机制。
11 1
|
7天前
|
Java 程序员 开发者
Java中的异常处理机制深度解析
本文旨在深入探讨Java中异常处理的机制,包括异常的分类、如何捕获和处理异常,以及自定义异常的最佳实践。通过实例讲解,帮助读者更好地理解如何在Java编程中有效管理和利用异常处理来提高代码的健壮性和可维护性。
|
8天前
|
存储 负载均衡 Java
Jetty技术深度解析及其在Java中的实战应用
【9月更文挑战第3天】Jetty,作为一款开源的、轻量级、高性能的Java Web服务器和Servlet容器,自1995年问世以来,凭借其卓越的性能、灵活的配置和丰富的扩展功能,在Java Web应用开发中占据了举足轻重的地位。本文将详细介绍Jetty的背景、核心功能点以及在Java中的实战应用,帮助开发者更好地理解和利用Jetty构建高效、可靠的Web服务。
22 2
|
21天前
|
Java API
Java 8新特性:Lambda表达式与Stream API的深度解析
【7月更文挑战第61天】本文将深入探讨Java 8中的两个重要特性:Lambda表达式和Stream API。我们将首先介绍Lambda表达式的基本概念和语法,然后详细解析Stream API的使用和优势。最后,我们将通过实例代码演示如何结合使用Lambda表达式和Stream API,以提高Java编程的效率和可读性。
|
21天前
|
Java API
Java文件处理完全指南:创建、读取、写入和删除文件详细解析
Java的文件处理非常灵活和强大。通过上述代码示例,我们可以清楚地理解在Java中如何高效地进行文件的创建、读取、写入和删除操作。值得注意的是,文件操作时我们常常会用到一些流(Stream)和读写字符的类,在操作完成之后,应当及时关闭这些资源,这可以通过使用try-with-resources语句来自动完成。这种方法不仅代码简洁,还能有效防止资源泄漏。总体而言,熟练掌握Java文件处理对于开发实用、健壮的应用程序至关重要。
57 1

推荐镜像

更多