别了,阿里巴巴fastjson!企业项目迁移Gson全攻略

前言大家好,又双叒叕见面了,我是天天放大家鸽子的蛮三刀 。
在被大家取关之前,我立下一个“远大的理想”,一定要在这周更新文章 。现在看来,flag有用了 。。。
本篇文章是我这一个多月来帮助组内废弃fastjson框架的总结,我们将大部分JAVA仓库从fastjson迁移至了Gson 。
这么做的主要的原因是公司受够了fastjson频繁的安全漏洞问题,每一次出现漏洞都要推一次全公司的fastjson强制版本升级,很令公司头疼 。
文章的前半部分,我会简单分析各种json解析框架的优劣,并给出企业级项目迁移json框架的几种解决方案 。
在文章的后半部分,我会结合这一个月的经验,总结下Gson的使用问题,以及fastjson迁移到Gson踩过的深坑 。
文章目录:

  • 为何要放弃fastjson?
  • fastjson替代方案 三种json框架的特点性能对比最终选择方案
  • 替换依赖时的注意事项 谨慎,谨慎,再谨慎做好开发团队和测试团队的沟通做好回归/接口测试考虑迁移前后的性能差异
  • 使用Gson替换fastjson Json反序列化范型处理List/Map写入驼峰与下划线转换
  • 迁移常见问题踩坑 Date序列化方式不同SpringBoot异常Swagger异常@MApping JsonObject作为入参异常
注意:是否使用fastjson是近年来一个争议性很大的话题,本文无意讨论框架选型的对错,只关注迁移这件事中遇到的问题进行反思和思考 。大家如果有想发表的看法,可以在评论区 理 性 讨论 。
本文阅读大概需要:5分钟
码字不易,欢迎关注我的个人公众号:后端技术漫谈
为何要放弃fastjson?究其原因,是fastjson漏洞频发,导致了公司内部需要频繁的督促各业务线升级fastjson版本,来防止安全问题 。
fastjson在2020年频繁暴露安全漏洞,此漏洞可以绕过autoType开关来实现反序列化远程代码执行并获取服务器访问权限 。
从2019年7月份发布的v1.2.59一直到2020年6月份发布的 v1.2.71,每个版本的升级中都有关于AutoType的升级,涉及13个正式版本 。
fastjson中与AutoType相关的版本历史:
1.2.59发布,增强AutoType打开时的安全性 fastjson1.2.60发布,增加了AutoType黑名单,修复拒绝服务安全问题 fastjson1.2.61发布,增加AutoType安全黑名单 fastjson1.2.62发布,增加AutoType黑名单、增强日期反序列化和JSONPath fastjson1.2.66发布,Bug修复安全加固,并且做安全加固,补充了AutoType黑名单 fastjson1.2.67发布,Bug修复安全加固,补充了AutoType黑名单 fastjson1.2.68发布,支持GEOJSON,补充了AutoType黑名单1.2.69发布,修复新发现高危AutoType开关绕过安全漏洞,补充了AutoType黑名单1.2.70发布,提升兼容性,补充了AutoType黑名单1.2.71发布,补充安全黑名单,无新增利用,预防性补充相比之下,其他的json框架,如Gson和Jackson,漏洞数量少很多,高危漏洞也比较少,这是公司想要替换框架的主要原因 。
fastjson替代方案本文主要讨论Gson替换fastjson框架的实战问题,所以在这里不展开详细讨论各种json框架的优劣,只给出结论 。
经过评估,主要有Jackson和Gson两种json框架放入考虑范围内,与fastjson进行对比 。
三种json框架的特点FastJson
速度快
fastjson相对其他JSON库的特点是快,从2011年fastjson发布1.1.x版本之后,其性能从未被其他Java实现的JSON库超越 。
使用广泛
fastjson在阿里巴巴大规模使用,在数万台服务器上部署,fastjson在业界被广泛接受 。在2012年被开源中国评选为最受欢迎的国产开源软件之一 。
测试完备
fastjson有非常多的testcase,在1.2.11版本中,testcase超过3321个 。每次发布都会进行回归测试,保证质量稳定 。
使用简单
fastjson的API十分简洁 。
Jackson
容易使用 - jackson API提供了一个高层次外观,以简化常用的用例 。
无需创建映射 - API提供了默认的映射大部分对象序列化 。
性能高 - 快速,低内存占用,适合大型对象图表或系统 。
干净的JSON - jackson创建一个干净和紧凑的JSON结果,这是让人很容易阅读 。
不依赖 - 库不需要任何其他的库,除了JDK 。
Gson
提供一种机制,使得将Java对象转换为JSON或相反如使用toString()以及构造器(工厂方法)一样简单 。
允许预先存在的不可变的对象转换为JSON或与之相反 。
允许自定义对象的表现形式
支持任意复杂的对象
输出轻量易读的JSON


推荐阅读