作者:贺子江

  1. 背景介绍
    本篇文章是在我的项目迭代的过程中,发现了的一个乏味的bug所引发进去的源码剖析,在这里以点破面,钻研一下fastjson的源码
  2. 案例剖析
    2.1 发现问题的过程
    在我的项目应用中,发现对于Timestamp的类型进行toJSONString()办法调用的时候,输入构造并没有依照料想的接果进行展现,后续独自拆出demo来进行钻研

public static void main(String[] args) {

    Timestamp timestamp = new Timestamp(System.currentTimeMillis());    JSONObject jsonObject = new JSONObject();    jsonObject.put("timestamp",timestamp);    System.out.println(jsonObject.toJSONString());}

预期:输入Timestamp类的tostring信息

理论:输入的是Timestamp的工夫戳long值

2.2 debug过程和代码剖析
当咱们遇到和咱们想法不一样的时候,就要去看源码到底是怎么实现的。在这里我的第一反馈是fastjson的bug,而后咱们要去验证这是fastjson的bug还是说这是它本人的策略
调用栈追踪

public String toJSONString() {

    SerializeWriter out = new SerializeWriter();    String var2;    try {        (new JSONSerializer(out)).write(this);        var2 = out.toString();    } finally {        out.close();    }    return var2;}

这里间接new啦一个序列化writer对象来进行write操作,点进去持续看

public final void write(Object object) {

    if (object == null) {        this.out.writeNull();    } else {        Class<?> clazz = object.getClass();        ObjectSerializer writer = this.getObjectWriter(clazz);        try {            writer.write(this, object, (Object)null, (Type)null, 0);        } catch (IOException var5) {            throw new JSONException(var5.getMessage(), var5);        }    }}

这里有一个ObjectSerializer对象是比拟重要的,这里也是开始进入到了外围办法

这里能够发现ObjectSerializer接口有很多的实现类,通过debug发现咱们Timestamp对应的是序列化类是DateCodec

点击去持续看,发现真正的实现逻辑一些很显著啦

这里有几个if else的判断来实现一些继承了Date类的一些类的序列化的操作,其中WriteDateUseDateFormat WriteClassName UseISO8601DateFormat 这些SerializerFeature枚举类占据了很重要的角色,此时咱们终于发现原来fastjson对于date的实现类有非凡的序列化操作,这里须要咱们进行一些非凡配置来实现toJSONString的实现。

2.3 解决方案钻研
1.遇到date的实现类,本人业务应用相干的tostring办法,不要应用原生类型,应用string代替

2.配置相干的SerializerFeature应用fastjson的类进行解决

  1. 两种计划的比照
    3.1 遇到date的实现类,本人业务应用相干的tostring办法,不要应用原生类型,应用string代替

执行后果:

运行工夫: 98ms

3.2 配置相干的SerializerFeature应用fastjson的类进行解决

执行后果:

运行工夫:113ms

  1. 论断
    fastjson在解决工夫类型的时候其实并没有什么劣势,咱们在应用fastjson进行打印工夫类型的时候要留神,在业务过程中,如果对工夫类型有要求最好本人进行工夫类型的转换,这样输入既直观又易于控制,时区的解决也更加灵便,门槛还低。当然这也只是我的集体意见,有不同的意见能够交换意见。