解决Jackson反序列化map,set等复杂类型问题

 更新时间:2020年09月28日 09:30:27   作者:MrHamster  
这篇文章主要介绍了解决Jackson反序列化map,set等复杂类型问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

工作中遇到了这个问题,我简单的用代码复现一下,就是一个map,value又为一个set,导致反序列化报错

@Test
  public void test10() throws Exception {
    //准备一下数据
    Map<String, Set<String>> map = new HashMap<>();
    map.put("aaa",new HashSet<String>(){{add("111");add("222");}});
    ObjectMapper om = new ObjectMapper();
    String str01 = om.writeValueAsString(map);
    //System.out.println(str01); // {"aaa":["111","222"]}
    // 正常反序列化,未报错
    Map<String, Set<String>> map01 = om.readValue(str01, Map.class);
    // 取值的时候就会报错了
    Set<String> aaa = map01.get("aaa");
  }

报错:

java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.Set

报错信息:无法将list转为set。

再拓展开来,其实当你的Map里面的对象如果是object类型的自定义类型,其实都会报错,无法被强转,那么我们就需要指定jackson反序列化为什么类型,而不是让它自主决定反序列化成什么类型,需要用到TypeReference,直接上代码。

@Test
public void test10() throws Exception {
  //准备一下数据
  Map<String, Set<String>> map = new HashMap<>();
  map.put("aaa",new HashSet<String>(){{add("111");add("222");}});
  ObjectMapper om = new ObjectMapper();
  String str01 = om.writeValueAsString(map);
  //System.out.println(str01); // {"aaa":["111","222"]}
  Map<String, Set<String>> m = om.readValue(str01, new TypeReference<HashMap<String, Set<String>>>() {});
  Set<String> aaa = m.get("aaa");
  System.out.println(aaa instanceof HashSet); // true
}

补充知识:Jackson 处理复杂类型(List,map)两种方法

方法一

String jsonString="[{'id':'1'},{'id':'2'}]"; 
ObjectMapper mapper = new ObjectMapper(); 
JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, Bean.class); 
//如果是Map类型 mapper.getTypeFactory().constructParametricType(HashMap.class,String.class, Bean.class); 
List<Bean> lst = (List<Bean>)mapper.readValue(jsonString, javaType);  

当转换完成时一定要用这个转换对象,如果不用这个对象是没有值的.如下,当我打印时这个projects对象才有值,否则projects无值 .

List<AlertProjectInfo> projects = mapper.readValue(subProject, mapper.getTypeFactory().constructCollectionType(List.class, AlertProjectInfo.class));
System.out.println(projects.size());

方法二

String jsonString="[{'id':'1'},{'id':'2'}]"; 
ObjectMapper mapper = new ObjectMapper(); 
List<Bean> beanList = mapper.readValue(jsonString, new TypeReference<List<Bean>>() {}); 

以上这篇解决Jackson反序列化map,set等复杂类型问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring Cloud 服务网关Zuul的实现

    Spring Cloud 服务网关Zuul的实现

    这篇文章主要介绍了Spring Cloud 服务网关Zuul的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • Java使用泛型实现栈结构的示例代码

    Java使用泛型实现栈结构的示例代码

    泛型是JAVA重要的特性,使用泛型编程,可以使代码复用率提高。本文将利用泛型实现简单的栈结构,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-08-08
  • SpringBoot如何配置MySQL和Oracl双数据源(Mybatis)

    SpringBoot如何配置MySQL和Oracl双数据源(Mybatis)

    这篇文章主要介绍了SpringBoot如何配置MySQL和Oracl双数据源(Mybatis)问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • mybatis 加载配置文件的方法(两种方式)

    mybatis 加载配置文件的方法(两种方式)

    这篇文章主要介绍了mybatis 加载配置文件的方法,通过实例代码给大家介绍了mybatis 加载配置文件的两种方式,需要的朋友可以参考下
    2017-12-12
  • 学习在一台新电脑上配置JAVA开发环境

    学习在一台新电脑上配置JAVA开发环境

    本文主要介绍了如何在一台新电脑上配置JAVA开发环境,每一个步骤都有对应的截图和文字说明,需要的朋友可以参考下
    2015-07-07
  • 关于Java整合RabbitMQ实现生产消费的7种通讯方式

    关于Java整合RabbitMQ实现生产消费的7种通讯方式

    这篇文章主要介绍了关于Java整合RabbitMQ实现生产消费的7种通讯方式,消息中间件是基于队列与消息传递技术,在网络环境中为应用系统提供同步或异步、可靠的消息传输的支撑性软件系统,需要的朋友可以参考下
    2023-05-05
  • 浅谈Java中的final关键字与C#中的const, readonly关键字

    浅谈Java中的final关键字与C#中的const, readonly关键字

    下面小编就为大家带来一篇浅谈Java中的final关键字与C#中的const, readonly关键字。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10
  • Java Web最近面试题汇总

    Java Web最近面试题汇总

    在本篇文章里小编给大家整理的是一篇关于Java Web最近面试题汇总内容,需要的朋友们可以学习下。
    2020-02-02
  • Java编程枚举类实战代码分享

    Java编程枚举类实战代码分享

    这篇文章主要介绍了Java编程枚举类实战代码分享,具有一定借鉴价值,需要的朋友可以了解下。
    2017-11-11
  • springboot 运行 jar 包读取外部配置文件的问题

    springboot 运行 jar 包读取外部配置文件的问题

    这篇文章主要介绍了springboot 运行 jar 包读取外部配置文件,本文主要描述linux系统执行jar包读取jar包同级目录的外部配置文件,主要分为两种方法,每种方法通过实例代码介绍的非常详细,需要的朋友可以参考下
    2021-07-07

最新评论