美文网首页
fastjson 始终将 null 对象以 "null " 的

fastjson 始终将 null 对象以 "null " 的

作者: DJN_ | 来源:发表于2018-11-07 13:17 被阅读0次

    接上篇:fastjson 始终将 null 对象以 "null " 的形式返回到前端引发的源码解析 - 上:从 DispatcherServlet 出发

    终于来到了 fastjson 内部。

    FastJsonHttpMessageConverter

    内部又调用了一系列的方法,最终定位到了 JavaBeanSerializer#write 的 216 行。

    image.png

    在这里 fastjson 与 spring web 的连接主要是通过 GenericHttpMessageConverter 接口,FastJsonHttpMessageConverter 类实现了该接口,该接口继承于 HttpMessageConverter 接口,特定只对 HTTP 请求和响应数据进行转换处理。
    再回过头看下 RequestResponseBodyMethodProcessor#writeWithMessageConverters 方法是怎么关联上 FastJsonHttpMessageConverter的:

    image.png

    JavaBeanSerializer

    该类的 write 方法是最终输出 json 格式数据的地方,其中对 null 类型对象判断是否要以 "obj": null" 形式输出的关键代码如下:

    
                    if (propertyValue == null && !writeAsArray) {
                        if ((!fieldSerializer.writeNull) && (!out.isEnabled(SerializerFeature.WRITE_MAP_NULL_FEATURES))) {
                            continue;
                        }
                    }
    
    

    continue 执行时当前成员就会跳过,不进行处理,也就不会输出。

    SerializeWriter#isEnable 方法源码如下

        public boolean isEnabled(int feature) {
            return (this.features & feature) != 0;
        }
    

    该判断置于一个循环中,循环用于遍历目标类的成员,进行处理并输出。propertyValue 即为当前遍历到成员的值。fieldSerializer 则是专门序列化当前成员的处理者。

    1. 首先值为 null 并且 SerializerFeature.BeanToArray 特性未启用
    2. fieldSerializer 的 writeNull 为 false:writeNull 在其构造函数中赋值,构造函数中会借助 @JSONField注解初始化 FieldSerializer 的成员,其中如果 SerializerFeature.WRITE_MAP_NULL_FEATURES 特性(实体类成员上类似这样使用 @JSONField(serialzeFeatures = {SerializerFeature.WRITE_MAP_NULL_FEATURES} ) 注解)启用的话,writeNull 才为 true,否则 false
    3. 如果 fieldSerializer.writeNull 为 false,则需要进一步判断,out 是一个 SerializeWriter 对象,继承自 java.io.Writer,用于输出 json 字符串,out 中携带了我们最初的配置
    image.png

    out.isEnable() 会通过 FastJsonConfig 判断是否配置了某一特性,如上所示,并没有配置 SerializerFeature.WRITE_MAP_NULL_FEATURES 特性,那么为什么 “obj”: null 还是会输出呢 ?答案在 WRITE_MAP_NULL_FEATURES 内部

    拨云见日

    image.png

    可见 SerializerFeature.WRITE_MAP_NULL_FEATURES 是以下几个特性的组合:

    WriteMapNullValue
    WriteNullBooleanAsFalse
    WriteNullListAsEmpty
    WriteNullNumberAsZero
    WriteNullStringAsEmpty

    fastjson 特性的处理采用的是 二进制状态叠加 的方式,这里的意思是 WRITE_MAP_NULL_FEATURES 特性是其它这几个特性的集合,
    举个栗子:

    如果
    0001 -> WriteNullListAsEmpty
    0010 -> WriteNullBooleanAsFalse
    WRITE_MAP_NULL_FEATURES = WriteNullBooleanAsFalse.getMask() | WriteNullListAsEmpty.getMask()
    则
    0011 -> WRITE_MAP_NULL_FEATURES
    
    假设配置了 WriteNullListAsEmpty
    0001 -> features
    调用 out.isEnabled(SerializerFeature.WRITE_MAP_NULL_FEATURES) 
       0001
    &  0011
       0001 != 0 
    结果为 true  
    
    

    即这几个特性任意一个配置了,那么相当于 WRITE_MAP_NULL_FEATURES 也就配置了,这种情况下 会把 null 以 "obj": null 的形式输出。

    相关文章

      网友评论

          本文标题:fastjson 始终将 null 对象以 "null " 的

          本文链接:https://www.haomeiwen.com/subject/hammxqtx.html