- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
记者:大爷您有什么特长呀? fastjson:我很快。 记者:23423乘以4534等于多少? fastjson:等于2343. 记者:?? fastjson:你就说快不快吧! 。
这个略显马丽苏的标题,各位看官将就着看吧。主要是怕被喷。fastjson真的很好,我用不用的我喜不喜欢的,太不重要了,我只是觉得不适合我而已.
话说以前GSON用得好好的,同事极力推荐我使用Fastjson,说很快云云。尽管我们的系统根本感知不出来这点速度差异。 之前也听说Fastjson爆出来什么重大漏洞,但对我们基本没什么影响,所以这一点倒是没什么偏见.
然后在一个新项目上,脑抽抽,把gson换成了fastjson,还把spring boot默认支持的jackson换成了fastjson。 然后就开始遇到了一些问题。先声明,这真不是尬黑,为了文章效果,故意网上扒些黑料拼凑起来,本文所提到的问题,都来源于本人最近项目的真实经历.
本来是一个风和日丽的下午,一个非常简单的改动需求。接口返回的时间只需要年月日日期类型不需要时分秒。 因为我配置全局时间格式化为 yyyy-MM-dd HH:mmss ,于是我愉快的在javabean的属性上加了个注解.
@JSONField(format="yyyy-MM-dd")
本地测试一下,没问题,提交到测试环境,搞定,完美.
然后就接到产品的疑问,改动呢?
我登上去看了一下,唉,没改到啊,日期还是带了时分秒。 我大意了啊,这么小的改动,又是在测试环境,就没加验证.
那么现在的直接问题是:fastjson关于时间配置在局部的配置没有生效,使用的还是全局配置.
现象是,开发环境windows上没有问题,测试环境linux上出现了问题。两者有什么区别呢?系统问题?
既然怀疑是两个系统导致的问题,那么就在idea里模拟一下linux系统。在 VM options 添加 -Dos.name=linux 。
这不能完全模拟linux系统,只针对通过 System.getproperty("os.name") 来判断当前系统做某些操作的时候有用.
通过这种方式没复现.
我又想到了远程调试。 一阵操作猛如虎,远程调试倒是能进断点,只是断点进不了第三方jar包的源码。等于白搞.
得,还是回到源码吧。拉下源码,断点,观察JSONSerializer类,主要是 writeWithFormat 方法。没有发现问题。 因为怀疑是系统导致的,在源码中搜索'linux''unix'关键字,没有发现。断点整个流程重点观察了一下这部份也没有发现问题.
突然在 JSONSerializer.dateFormatPattern上发现了这段注释.
这部份涉及到了调整dateformat的问题,重点在这个 #1868 ,这通常是github的问题编号.
对于开源项目来说,解决BUG,通常会把问题编号放到注释里面去。前提是注释有必要。通过问题编号可以看到问题的前因后果。 通常来说,对于github开源项目都有issue区,拿着这个到编号直接到issue一搜就能搜到。 但也有一些项级项目,如spark,flink是没有issue区的,它们的类型问题发现描述追踪都使用jira平台。如: https://issues.apache.org/jira/browse/SPARK-38349, 在提交PR的时候标题也严格按照[jira 编号][spark 子模块(如core/sql) title]的规则来.
所以拿着这个编号到 issue 区,不管有没有 issue 区,也都可以直接到 pullrequest 区直接搜索,就算PR标题里没有问题编号,PR描述肯定也是有的,只要是有严格PR流程的开源项目.
所以这个问题在这里 。
https://github.com/alibaba/fastjson/issues/1868 。
相应的PR在这里 。
https://github.com/alibaba/fastjson/pull/2706 。
通过ISSUES描述的已知信息,可以看出他遇到的问题跟我是一样的,而这个问题早在2018年就提出了。但问题描述不太专业,没有涉及到环境以及最重要的fastjson的版本问题。 而通过PR可知,这个问题最终在2020才解决,期间仅在ISSUES区提出的相同问题就有 #1868 #1968 #2029 #2452 4个。 解决问题的版本为:1.2.72. 。
这个信息很关键。我对照了我开发环境的版本,是高于1.2.72的,所以没有出现测试环境的问题。 所以,柯南告诉我们,排除了所有可能性,剩下的哪怕再可笑,也是最终问题所在。 那就是,测试环境所用的fastjson版本是低于1.2.72的。 这种可能性是存在的,因为我们用的是maven打代码包,依赖包单独存在。 我最终在测试环境的依赖包目录下发现了两个Fastjson包,果然不出所料,有一个1.2.53的低版本,它就是罪魁祸首。 所以,最终这个问题有相当大的程度是由于我们团队自身问题引发的。但通过解决这个问题的过程也发现了一些有意思的情况.
首先,Fastjson在某一个版本为什么会引发这个问题。它肯定是某个PR改出问题的,rv,testcase覆盖没有到位.
其次,从试图解决这个问题的3个PR的时间线,分别在2018年,2019年,2020年。说明,fastjson这个项目的contributor看起来有百来人,但其中过于依赖其中某1个或者某些主力人员。精力有限,某些优先级不那么高的BUG只能放任.
同时这个项目的荣誉感并没有那么高(或者叫并没有那么吸引高手),它并不是apache顶级项目,要是其它诸如spark/flink,spring,哪怕是dubbo呢,很想象这些项目会有一个并不算复杂的BUG悬而未决长达3年时间。在这些顶级开源项目,大家都是拼了老命的想找些BUG来提交PR.
当然,以上只是我个人的一点猜测.
复盘,遇到Fastjson的问题,一开始就应该奔着github的issues区,它大概率已经被前人踩坑了.
public ResultBody test () {
List<Person> list = new ArrayList<>();
Person obj1 = new Person("张三", 48);
list.add(obj1);
Person obj2 = new Person("李四", 23);
list.add(obj2);
Person obj3 = new Person("王麻子", 17);
list.add(obj3);
List<Person> young = list.stream().filter(e -> e.getAge() <= 45).collect(Collectors.toList());
List<Person> children = list.stream().filter(e -> e.getAge()< 18).collect(Collectors.toList());
HashMap map = new HashMap();
map.put("young", young);
map.put("children", children);
return ResultBody.success(map);
}
{
"code":"200",
"message":"成功!",
"result":{
"young":[
{
"age":23,
"name":"李四"
},
{
"age":17,
"name":"王麻子"
}
],
"children":[
{"$ref":"$.result.young[1]"}
]
}
}
我现在并不知道什么循环引用检测,这时候它是我的知识盲区。 此时,我观察到的现象是, young 和 children 两个list对象中均引用指向了 王麻子 这个对象。然后,在第2次 children 引用的时候它在序列化的时候直接指向了第1个 young 里相应对象引用。 当然遇到这个问题的时候,我在仔细观察排除了非fastjson的问题以后,这次我学聪明了,我直接来到了github的issues区,搜索 $ref .
果然有很多同道中人,近150个问题,从时间上来看还挺新鲜。我点击了closed,既然关闭了,那肯定解决了吧.
我点进了closed区第一个问题,然后作者让升级到fastjson2。 ???
如果我没有理解错,fastjson和fastjson2可不是两个版本的区别,是两个项目也!据说API也有兼容性问题。直接这样升级过去,谈何容易! 。
我觉得这也是个槽点,Fastjson好像并没有一个稳定维护的版本,遇到问题总是在升级,升级的过程中也没做好质量控制,又引入了新的问题.
还是在当前项目寻求解决方法吧,哪怕升版本也好啊。 终于在另一个问题下面找到了问题所在以及解决方案.
https://github.com/alibaba/fastjson/issues/3643 。
我现在知道这是由于循环引用检测引起的。通过设置 SerializerFeature.DisableCircularReferenceDetect 可以避免这个问题.
但是,我的代码其实并没有循环引用啊,只是两个子对象引用了同一个对象而已。这算什么?误伤吗? 更重要的,一些控制权应该在使用者手里?
比如,当前这个循环引用在序列化会出的问题,应该是用户手动去开启,而不是默认给用户开启。 在优先级上,全局应该关闭,在有循环引用的地方,让用户选择局部开启.
现在我的前端并没有使用Fastjson,面对 "$ref":"$.result.young[1]" 这种文本,它能解析吗?它不能呀。 我测试了一下,好像使用fastjson也并不能解析回来:
更可怕的问题是,刚好在测试环节有两个子对象引用了同一个对象,被我提前发现了。如果测试环境没有这样的情况,在生产环境刚好遇到了呢?那就是生产事故了呀.
本来是一个挺好的设计点,能起到锦上添花的作用,但它却可能暴雷,这是好心办坏事.
同样的,还有 SerializerFeature.WriteMapNullValue 。 如果一个字段值为 null ,fastjson默认就不返回该字段了。本来前后端约定好,如果为 null 就怎样处理的逻辑,可能在生产环境中突然暴雷啊.
就像 WriteNullListAsEmpty 就很好,不错的设计点,如果返回的list为 null 的时候,用户可以选择让它序列化为 [] ,但它也不是默认开启的呀,给了用户额外的选择权,对吧.
写到这里的时候,我是真心觉得fastjson有比竞品有些特色的地方。这真不是为了所谓的客观公正,非要负面写多点,再搞点正面的.
为了写文章,那肯定要去试验,得把竞品也拿出来测试一下,一测试发现并不是fastjson独有的,尴尬! 。
但我还是那句话,不管你信不信,对于开源项目,特别是这样一个广泛使用的开源项目,肯定有非常值得学习的地方。一个开源项目,如果整天拿着显微镜去观察,那肯定能找出不少毛病.
这里稍微总结一下本文的信息点。 并不一定是某个具体BUG,而是通过这个BUG,解决这个BUG背后所展现出来的fastjson的信息或趋势.
1.review,testcase覆盖不是很到位 2.contributor看起来很多,但严重依赖主力人员。而主力精力有限,某些优先级不那么高的BUG只能放任。 3.这个项目的荣誉感并没有那么高,或者叫并没有那么吸引高手)。 4.有些功能点应该把控制主动权交给用户,如DisableCircularReferenceDetect,WriteMapNullValue等。默认开启非常容易导致线上暴雷。 5.作者已经全面转向fastjosn2,而且哪怕在这之前,对于fastjson没有一个稳定维护的版本,不断升级,不断引入新问题.
祝愿fastjson2越来越好,不要步struts2的后尘.
最后此篇关于fastjson很好,但不适合我的文章就讲到这里了,如果你想了解更多关于fastjson很好,但不适合我的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
Fastjson介绍 Fastjson是一个Java语言编写的JSON处理器。 1、遵循http://json.org标准,为其官方网站收录的参考实现之一。 2、功能qiang打,支持JDK的
1、介绍 2、Maven依赖 3、JSON 3.1、String转JSON 1、JSON对象字符串 转为 JSON对象 2、JSON数组字符串 转为 JSON数组 3、JSON对象字符串 转为 Jav
所以有点像我之前的问题的基础。我正在尝试保存蓝图,它只是游戏对象/实体的一堆设置。我现在将组件(及其设置)存储为 List (IEntityComponent 是任何组件的接口(interface))
我已经开始使用 FastJSON,但在使用过程中遇到了一些问题。我在 Internet 上找不到任何指南或文档,只能在 CodeProject 中找到一些摘录。 例如:我有这门课: [Serializ
Fastjson是一个Java语言编写的高性能功能完善的JSON库。将解析json的性能提升到极致,是目前Java语言中最快的JSON库。Fastjson接口简单易用,已经被广泛使用在缓存序列化、协
实际项目中,我们经常需要使用序列化工具来存储和传输对象。目前用得比较多的序列化工具有:jackson、fastjson、kryo、protostuff、fst 等,本文将简单对比这几款工具序列化和反序
我想要使用 fastJSON 反序列化部分数据失败。 class A { public String a; } 数据 {"a": "a", "b": "b" } 使用 A objectA =
我就废话不多说了,大家还是直接看代码吧~ ? 1
基础部分 1. fastjson 简介 fastjson是一个java库,可用于将java对象转换为json表示。它也可以被用来将一个json字符串转换成一个等效的java对象。在转换速度上应该
第一种情况是从后台拿到数据,进行反序列化,反序列化格式时间:试了一下很多网上的方法,最后发现还是在实体类上面的日期字段加上如下注解,可以完成格式化操作,否则默认就都是时间戳的格式: @JSONFi
一:hibernate-validator 基础 1. 简介: 通过使用注解annotations 给类或者类的属性加上约束(constraint),在运行期检查属性值的合法性. 2. 作用:
===== UPDATED 8/20/2016 ===== latest version of fastjson can now handle Dictionary type correctly, m
我正在尝试在 Kotlin 代码中使用 fastjson 解析对象。但是当我使用 JSON.parseObject 时发生异常,以下是详细信息: 我的数据类: import com.aliba
我无法在现有线程中找到我的问题的答案。我有这个 JSON 字符串: { "Count": 4, "Result:000": { "Score": 4.571,
我正在使用 fastJSON我遇到了一个问题。我无法将 JSON 字符串转换为对象集合。 我认为它可以解决这个问题,但也许我做错了或被误解了。 Handles polymorphic collecti
为了将空字符串转换为“”,引入了FastJsonHttpMessageConverter。 Controller 定义为: 定义的请求模型为:enter image description here
我是一名优秀的程序员,十分优秀!