本文共 2827 字,大约阅读时间需要 9 分钟。
对于一个多层嵌套泛型(深度泛型)的对象进行序列化是容易的,但是反序列化却往往不是很顺利。
//调用jackson对象ObjectMapper mapper = new ObjectMapper();mapper.setSerializationInclusion(Include.NON_NULL); //封装用户对象AlUsers alUsers1 = new AlUsers();alUsers1.setUsername("WOW");AlUsers alUsers2 = new AlUsers();alUsers2.setUsername("SC2");ListusersList = Lists.newArrayList(alUsers1, alUsers2);//设计的多泛型嵌套mapMap > map = Maps.newHashMap();map.put("L", usersList);//序列化String json = mapper.writeValueAsString(map)
我们设计了一个多层泛型嵌套的对象map,对其进行序列化,是没有问题的
//打印{ "L":[{ "username":"WOW"},{ "username":"SC2"}]}
我们现在使用反序列化处理
Map> map1 = mapper.readValue(json, Map.class);List users = map1.get("L");for (AlUsers user : users) { System.out.println(mapper.writeValueAsString(user));}
结果抛出了异常
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.flight.carryprice.entity.AlUsers
Jackson是不支持多泛型深度嵌套反序列化的,强转后的结果就是默认将AlUsers对象变成了LinkedHashMap,所以在循环的时候强转AlUsers对象就会报错
即使我在每一层都序列化一次,最后还是报错
String listStr = mapper.writeValueAsString(usersList); //内层序列化Mapmap = Maps.newHashMap();map.put("L", listStr);String json = mapper.writeValueAsString(map); //外层序列化//异常java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.flight.carryprice.entity.AlUsers
这里提供两种解决思路
1、既然问题出在循环过程中对象的强转,那么我们可以使用普通的for循环,使用get(index)方法获取对象的时候先转为json,再反序列化为AlUsers,中间倒腾一手
Map> map1 = mapper.readValue(json, Map.class);List users = map1.get("L");for (int i = 0; i < users.size(); i++) { //序列化再反序列化 AlUsers alUsers = mapper.readValue(mapper.writeValueAsString(users.get(i)), AlUsers.class); System.out.println(mapper.writeValueAsString(alUsers));}//打印{ "username":"WOW"}{ "username":"SC2"}
2、我们使用TypeReference对象
//源码 protected TypeReference() { Type superClass = getClass().getGenericSuperclass(); if (superClass instanceof Class ) { // sanity check, should never happen throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information"); } /* 22-Dec-2008, tatu: Not sure if this case is safe -- I suspect * it is possible to make it fail? * But let's deal with specific * case when we know an actual use case, and thereby suitable * workarounds for valid case(s) and/or error to throw * on invalid one(s). */ _type = ((ParameterizedType) superClass).getActualTypeArguments()[0]; }
TypeReference对象就是通过java反省机制,获取所指定的泛型的类型,在反序列中根据指定的泛型类型进行反序列化
//通过TypeReference指定反序列化的类型Map> map1 = mapper.readValue(json, new TypeReference
转载地址:http://ftgzi.baihongyu.com/