点击登录,精彩内容等着你

Fastjson1与Fastjson2的差别,深入简化的分析

全栈侠客

2022-10-20
Fastjson2相对Fastjson1版本可以说是一次完全的重构,这里从代码的角度,分析两者的一些区别,并总结一些新的,让小伙伴们使用Fastjson2或者进行功能扩展的时候,能更加顺畅。
关联类名: JSONFuncs.javaJSONWebMvcConfigurer.java

一、使用Fastjson的感受

精益编程系统,大部分都是采用Fastjson作为数据的传输,包括:参数传输与结果返回;
这样的好处相当明显:

  • 大大减少了系统的中间封装类的数量,并对json属性的增加与减少提供灵活的载体;
  • 统一数据格式的返回,降低对中间类的依赖;

当然…也会产生一些坏处:

  • 对参数的结构,或者中间传输数据属性,标识不明显,必须要依赖说明才能知道传输有哪些属性;
  • 但这个只是针对参数而言,毕竟一般的方法传参,不会太多,所以这个缺点,本人认为可以忽略

对于结果的返回,使用json输出,已经是springboot请求响应的标配,所以方法直接使用json包装结果数据,并直接返回,作为响应json直接输出到请求方,是效率非常高的,避免了中间的【中间类的序列化】过程。

二、1跟2版本的比较

今天看了一下两个版本的重要两个类:JSONObject与JSONArray的源码,用完全重构Fastjson2来形容,一点都不过分..

1. Fastjson1继承父类定义

  1. //1.Fastjson 1 JSONObject类定义
  2. public class JSONObject extends JSON implements Map<String, Object> ...{
  3. }
  4. //2.Fastjson 1 JSONArray类定义
  5. public class JSONArray extends JSON implements List<Object>... {
  6. }

2. Fastjson2继承父类定义

  1. //1.Fastjson2 JSONObject类定义
  2. public class JSONObject extends LinkedHashMap<String, Object> implements InvocationHandler{
  3. }
  4. //2.Fastjson2 JSONArray类定义
  5. public class JSONArray extends ArrayList<Object> {
  6. }

分析(1)

  • Fastjson1 的JSONObject 只是简单实现Map接口,是无序的map容器
  • Fastjson2 的JSONObject 实现了链结构的Map,是有序的Map容器
  • 无论是JSONObject或者JSONArray都摆脱了JSON的类,而且JSON由抽象类——>接口

三、优化Springboot默认的json序列化与反序列化

作为springboot默认的jackson,还是号称最快的json工具fastjson,对于springboot来说,都只是一个序列化的工具而已,作为一个json成熟工具,对于数据的序列与反序列,其实都有一套默认转换规则。

今天就这个换换规则来进行扩展,扩展成符合自己业务规范的转换器,最典型的就是对于Date时间的转换

1.Fastjson2对springboot的支持

详情请移步查看:Fastjson2让springboot的json序列化飞起来
文中对springboot的数据经过json序列化后的输出,制定了一个转换器规则,注意:这个是针对springboot的输出格式规则的修改,但是不是fastjson本身的转换规则的设置

2.Fastjson2的序列化分析

JSONWriter是fastjson2序列化的底层实现,针对toJSONString和toJSONByte两种场景..

Fastjson2对实体类,集合类型等数据的序列化转换(Object->JSONObject or JSONArray),是通过JSON来完成,过程:

  1. String JSON.toJSONString(Object),先把对象转化为字符串..
  2. Object JSON.parse(String text),再把字符串的json,转为为对应的json对象

为此,我封装了一下parse的这个方法,用于转化Object->json对象(文档jSONFuncs.java

  1. //1.有点小问题的转换方法
  2. public static Object parse(Object obj){
  3. if(obj == null) {
  4. return JSONObject.builder();
  5. }
  6. if(obj instanceof JSONObject) {
  7. return (JSONObject)obj;
  8. }
  9. if(obj instanceof JSONArray) {
  10. return (JSONArray)obj;
  11. }
  12. if(obj instanceof String) {
  13. return JSON.parse(obj.toString());
  14. }
  15. if(obj instanceof Boolean) {
  16. return JSONObject.builder();
  17. }
  18. //这一步使用json默认的转换器(有点小问题的)
  19. String objStr = JSON.toJSONString(obj,JSONWriter.Feature.PrettyFormat);
  20. if(obj instanceof Collection) {
  21. return (JSONArray)JSON.parseObject(objStr,JSONArray.class);
  22. }
  23. return JSON.parseObject(objStr,JSONObject.class);
  24. }

以上的方法,对于转换javaBean或者集合数据的时候,对Date的转换,就默认输出:ms的格式
这个时候,经过分析,是由于JSON.toJSONObject的时候,已经使用了默认转换器,已经发生点问题了


经过研究源码,可以修改为:

  1. //这里是转换重点:JSONWriter是fastjson2序列化的底层实现,针对toJSONString和toJSONByte两种场景
  2. JSONWriter.Context context = new JSONWriter.Context(new ObjectWriterProvider(),JSONWriter.Feature.PrettyFormat);
  3. context.setDateFormat("yyyy-MM-dd HH:mm:ss");
  4. String objStr = JSON.toJSONString(obj,context);

经过这样设定JSONWriter,就能对实时转换Date的使用需要的输出格式。

精益编程框架,对Fastjson2进行了不少的扩展,尽量让其发挥其功能到极致,请参考文档:Springboot使用Fastjson2转换器

阅读 23413     最后编辑 2022-10-23 07:33
文章补充
评论(0) 发表新评论
  • ...暂无评论...

我是有底线的 评论与点赞5分钟更新一次
回复评论
取消关闭

请先登录