FastJson 泛型转换踩坑
一直用FastJson 做rest接口的序列化,FastJson对泛型的支持也非常好。经过一段时间使用后发现不定时的会报JsonObject can't covert to ****的错误,但是重启之后就好了。排查过程不赘述,直接上代码演示
String itemJsonStr = "{\"models\":{\"_defaultModel\":{\"id\":824,\"itemName\":\"【特惠】花王L54尿不湿\",\"itemStatus\":1,\"itemPrice\":null,\"itemStock\":1511,\"categoryId\":\"69aefe645dc0482dbced7a234f71e0a9\",\"brandId\":\"e096294ba3db4703972f26ce82d64692\",\"expand\":null,\"ytItemNo\":\"MDJPHW-L54TH\",\"remarks\":\"\",\"locality\":\"日本\",\"spec\":\"包装\",\"pictures\":[\"http://staticonline.hipac.cn/item/201511/11231324205997.jpg\",\"http://staticonline.hipac.cn/item/201511/11231324204657.jpg\"],\"otherPictures\":[\"http://staticonline.hipac.cn/item/201511/11231324200849.jpg\"],\"itemDescribe\":\"偏远地区不发货。日本销量No.1纸尿裤品牌,日本原装进口,海关监管,保税区直供!专利凹凸网状织物表面,3倍透气,牢牢锁住稀软便便,让小屁屁持久干爽舒适。表层纤维添加天然植物精华,温柔呵护宝宝娇嫩肌肤。适合体重在9-14kg的宝宝。\",\"netPrice\":null,\"transitFee\":null,\"minPrice\":0.1,\"taxRate\":0.1,\"taxAmount\":null,\"guidePrice\":null,\"specificationTOs\":[],\"createTime\":1448256261000,\"editTime\":1451300191000,\"itemChannel\":\"0\",\"specialShopId\":\"0\",\"prompt\":\"\",\"keyWord\":\"每周特惠,花王,L54,尿不湿\"}},\"message\":\"\",\"code\":\"200\",\"totalCount\":0,\"success\":true,\"defaultModel\":{\"id\":824,\"itemName\":\"【特惠】花王L54尿不湿\",\"itemStatus\":1,\"itemPrice\":null,\"itemStock\":1511,\"categoryId\":\"69aefe645dc0482dbced7a234f71e0a9\",\"brandId\":\"e096294ba3db4703972f26ce82d64692\",\"expand\":null,\"ytItemNo\":\"MDJPHW-L54TH\",\"remarks\":\"\",\"locality\":\"日本\",\"spec\":\"包装\",\"pictures\":[\"http://staticonline.hipac.cn/item/201511/11231324205997.jpg\",\"http://staticonline.hipac.cn/item/201511/11231324204657.jpg\"],\"otherPictures\":[\"http://staticonline.hipac.cn/item/201511/11231324200849.jpg\"],\"itemDescribe\":\"偏远地区不发货。日本销量No.1纸尿裤品牌,日本原装进口,海关监管,保税区直供!专利凹凸网状织物表面,3倍透气,牢牢锁住稀软便便,让小屁屁持久干爽舒适。表层纤维添加天然植物精华,温柔呵护宝宝娇嫩肌肤。适合体重在9-14kg的宝宝。\",\"netPrice\":null,\"transitFee\":null,\"minPrice\":0.1,\"taxRate\":0.1,\"taxAmount\":null,\"guidePrice\":null,\"specificationTOs\":[],\"createTime\":1448256261000,\"editTime\":1451300191000,\"itemChannel\":\"0\",\"specialShopId\":\"0\",\"prompt\":\"\",\"keyWord\":\"每周特惠,花王,L54,尿不湿\"}}";//下面这行注释掉第二打印出来就是trueResultData<?> resultFromClass = JSONObject.parseObject(itemJsonStr, new TypeReference<ResultData>() {});System.out.println(resultFromClass.getDefaultModel() instanceof JSONObject);ResultData<?> itemResult = JSONObject.parseObject(itemJsonStr, new TypeReference<ResultData<ItemTO>>() {}.getType());System.out.println(itemResult.getDefaultModel() instanceof ItemTO);
这样打印出来的结果是true,false。但是把第一个parseObject 注释掉,第二个就打印出true。大致debug了下FastJson的代码,大概定位到问题应该是出现对类解析的缓存上
ParserConfig.java,getDeserializer方法
if (type instanceof Class<?>) {return getDeserializer((Class<?>) type, type);}if (type instanceof ParameterizedType) {Type rawType = ((ParameterizedType) type).getRawType();if (rawType instanceof Class<?>) {return getDeserializer((Class<?>) rawType, type);} else {return getDeserializer(rawType);}}
第一个if 判断是否是class,第二个if是判断是否泛型类型,getRawType 是获取泛型的类型,然后进入getDeserializer 方法,这个方法里有一个缓存
if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) {derializer = derializers.get(clazz);}
缓存的放入是在putDeserializer 这个方法
public void putDeserializer(Type type, ObjectDeserializer deserializer) {derializers.put(type, deserializer);}
可以看到缓存的key是Type.
由此引发的问题:首先解析new TypeReference<ResultData>() ,走了getDeserializer 的第一个if,这样putDeserializer方法里放入的是ResultData。接着解析new TypeReference<ResultData<ItemTO>>(),这个时候走了getDeserializer 的第二个if,结果rawType是ResultData,所以直接从缓存中返回了第一次解析的结果。这样就相当于丢失了泛型类型ItemTO,导致最后类型转换失败。使用中偶现的原因是大部分ResultData都有泛型,只有非常少的ResultData没有泛型,因此当调用了没有泛型的ResultData之后,就会出现错误。
解决方案:统一使用泛型类型,项目中不允许没有泛型类型的ResultData,就不会存在这个问题。
FastJson 泛型转换踩坑相关推荐
- java fastjson 泛型_解决fastjson泛型转换报错的解决方法
错误信息 Exception in thread "main" java.lang.ClassCastException: com.alibaba.fastjson.JSONObj ...
- 从一道面试题说起—js隐式转换踩坑合集
前方提醒: 篇幅较长,点个赞或者收藏一下,可以在下一次阅读时方便查找 提到js的隐式转换,很多人第一反应都是:坑. 的确,对于不熟悉的人来说,js隐式转换存在着很多的让人无法预测的地方,相信很多人都深 ...
- 记一次fastJson使用的踩坑经历
他奶奶的,抱歉,不好意思,都要骂娘了.也许是自己第一次用第三方json解析库没啥经验吧,之前都是自己用官方提供的json api 来进行json解析,这次用了下阿里的fastjson,据说比Gson, ...
- lua 差值 日期_lua时间戳和日期转换及踩坑
lua时间戳和日期转换及踩坑 介绍lua的日期函数常用方法及我的一个踩坑. 时间戳转日期# Copyos.date("%Y%m%d%H",unixtime) --os.date(& ...
- 日常踩坑记录-汇总版
开发踩坑记录,不定时更新 心得 RTFM 严谨的去思考问题,处理问题 严格要求自己的代码编写习惯与风格 注意 单词拼写 20200207 mybatis plus 自带insert插入异常 sql i ...
- 【Java笔记+踩坑】SpringBoot基础3——开发。热部署+配置高级+整合NoSQL/缓存/任务/邮件/监控
导航: [黑马Java笔记+踩坑汇总]JavaSE+JavaWeb+SSM+SpringBoot+瑞吉外卖+SpringCloud/SpringCloudAlibaba+黑马旅游+谷粒商城 目录 ...
- 瑞吉外卖项目笔记+踩坑1——基础功能
导航: [黑马Java笔记+踩坑汇总]JavaSE+JavaWeb+SSM+SpringBoot+瑞吉外卖+SpringCloud/SpringCloudAlibaba+黑马旅游+谷粒商城 目录 1 ...
- Vue + TypeScript + Element 搭建简洁时尚的博客网站及踩坑记
前言 本文讲解如何在 Vue 项目中使用 TypeScript 来搭建并开发项目,并在此过程中踩过的坑 . TypeScript 具有类型系统,且是 JavaScript 的超集,TypeScript ...
- 「Java」基于Mirai的qq机器人开发踩坑笔记(其二)
目录 0. 配置机器人 1. onLoad方法 2. onEnable方法 3. 消息属性 4. 消息监听 I. 好友消息 II. 群聊消息 III. 无差别消息 5. 发送消息 I. 文本消息 II ...
最新文章
- 【运筹学】单纯形法总结 ( 单纯形法原理 | 单纯形法流程 | 单纯形表 | 计算检验数 | 最优解判定 | 入基变量 | 出基变量 | 方程组同解变换 ) ★★★
- Office Word 2007下管理参考文献(比2003版的交叉引用神马的轻松多拉)(转)
- 幕后常驻嘉宾配音小姐姐的2021年度总结
- C++ 内存基本构件 placement new
- mysql基础综述(四)
- x12arima季节调整方法_[方法]季节调整与hp滤波方法
- SpringBoot读取外部配置文件的方法
- lol峡谷之巅区服务器位置,LOL: 论峡谷之巅和艾欧尼亚哪个区水平更高?
- 20135202闫佳歆——信息安全系统设计基础第七周学习总结
- 【无标题】公众号引流进阶教程(公众号对接电影,影视资源)
- Premiere快捷键设置
- gstarcad 2021|gstarcad pro2021(浩辰CAD) 64位附安装教程
- Flask + vue 前后端分离的 二手书App
- Android之UiAutomator测试框架源码分析(第二十四篇:ByMatcher相关功能介绍)
- 香港特首到访阿里_她是来看几个年轻人的……
- UnRaid硬件直通的n种正确姿势
- .bat文件闪退,原因及解决
- WPS如何转换成图片?三种方法帮你实现
- Apache 的 X-sendfile
- jsp java 传值方法_JSP 页面传值方法总结(转)
热门文章
- Abaqus血管支架仿真
- 基于STM32开源:磁流体蓝牙音箱(包含源码+PCB)
- 梅尔加尼服务器状态,【搬运】 2区梅尔加尼服务器编年史---纪念离开的WOWER
- 你适合做程序员吗?一篇文章告诉你如何判断自己是否适合做程序员
- 如何上传html验证文件大小,input上传文件,前端判断文件的大小及类型
- idea提交项目到gitee
- css3样式总结--例如:颜色渐变、元素阴影、文字超长、transform、animation 和 keyframe动画的运用。
- 不是竞赛强省强校,没有教练的我如何保送清北?
- 找一个文件夹里面照片的名字,python转换为csv文件
- python 名片管理系统