欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

正确使用Jackson处理Java泛型的方法 - Java调试笔记实例指南

最编程 2024-02-17 16:30:35
...

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>>>(){});,直接一步到位。