当前位置: 首页 > 后端技术 > Java

fastjson的toJSONString()时间类特殊处理的源码分析——《DEEPNOVA开发者社区》

时间:2023-04-01 23:07:44 Java

作者:何子江背景介绍本文是项目迭代过程中发现的一个有趣的bug引起的源码分析,这里看看fastjson2.1源码案例分析发现问题的过程。项目使用过程中,发现Timestamp类型调用toJSONString()方法时,输出结构没有按预期显示。publicstaticvoidmain(String[]args){时间戳timestamp=newTimestamp(System.currentTimeMillis());JSONObjectjsonObject=newJSONObject();jsonObject.put("时间戳",时间戳);系统。out.println(jsonObject.toJSONString());}预期:输出Timestamp类的tostring信息实际:输出的是Timestamp的timestamplong值2.2调试过程及代码分析当遇到和我们想法不一样的时候,我们会看看源码是如何实现的。这里我第一反应是fastjson的bug,然后我们要验证这是fastjson的bug还是它自己的策略调用栈tracepublicStringtoJSONString(){SerializeWriterout=newSerializeWriter();字符串var2;尝试{(newJSONSerializer(out)).write(this);var2=out.toString();}最后{out.close();}returnvar2;}这里直接新建一个序列化的writer对象进行写操作,点击继续阅读publicfinalvoidwrite(Objectobject){if(object==null){this.out.writeNull();}else{Classclazz=object.getClass();ObjectSerializer作者=这个。getObjectWriter(克拉兹);尝试{writer.write(this,object,(Object)null,(Type)null,0);}catch(IOExceptionvar5){thrownewJSONException(var5.getMessage(),var5);}}}这里是一个比较重要的ObjectSerializer对象,这里也是进入核心方法的开始这里可以发现ObjectSerializer接口有很多实现类。经过调试,我们发现我们的Timestamp对应的序列化类是DateCodec。单击以继续并找到真实的。实现逻辑显而易见。下面是几个ifelse判断实现一些继承Date类的类的序列化操作,其中WriteDateUseDateFormatWriteClassNameUseISO8601DateFormat这些SerializerFeature枚举类占据了非常重要的作用。这个时候我们终于发现fastjson对date的实现类有专门的序列化操作。这里我们需要做一些特殊的配置来完成toJSONString的实现。2.3方案研究1.遇到date的实现类,自己业务使用相关的tostring方法。不使用native类型,使用string代替2.配置相关SerializerFeature,使用fastjson类处理两种方案对比使用相关tostring方法,不使用native类型,使用string代替执行结果:运行时间:98ms3.2配置相关SerializerFeature使用fastjson类处理执行结果:运行时间:113ms没有优势。使用fastjson打印时间类型时要注意。在业务过程中,如果对时间类型有要求,最好自己转换时间类型,这样输出直观易控制,时区处理起来也更容易。灵活,门槛还是很低的。当然,这只是我个人的看法,有不同的意见可以交流。