jackson解析泛型的正确写法,解决 in unnamed module of loader ‘app‘

博主的公众号:Java4y
《《《《《《《《《
一个努力提高工作效率(增加摸鱼时间)的小白博主
》》》》》》》》》》
关注有惊喜哦
《《《《《《《《《
2021一起好好加油! (ง •_•)ง

内容概览
解决1024当天遗留的bug:in unnamed module of loader 'app'

wechat

20201027223716

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')

20201024190656

错误代码如下:

  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中的一个元素就报错上面那个错了🙃🙄 两种写法都会报这个错误。。
整个人都懵了,找了好久都不知道咋回事。。

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);

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

因为前面bjectMapper.readValue(body, ResultDTO.class);这里没法定义泛型T的类型。。所以jackson使用了这个LinkedHashMap来存解析的数据🐖
20201027082329

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

objectMapper.readValue(body, Map.class); 这里也是,没办法指定泛型🐖,所以jackson还是使用了这个LinkedHashMap来存解析的数据
20201027082937

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

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

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

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

结论

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

  1. 局部解析🐖:
    • 通过readTree()去获取对应的jsonnode节点:JsonNode jsonNode = objectMapper.readTree(body);
    • 再获取到对应节点的数据jsonNode.get("data");
    • 最后通过readValue():objectMapper.readValue(data.toString(), new TypeReference<List<User>>(){}); 解析得到对应的数据
  2. 直接解析🐖:
    • objectMapper.readValue(body, new TypeReference<ResultDTO<List<User>>>(){});,直接一步到位。

"( ̄y▽, ̄)╭ " 😄

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值