fastjson源码分析-toJSONBytes分析

2021SC@SDUSC

简介

本篇博客主要分析一下fastjson的toJSONBytes方法

简单使用

public static byte[] toJSONBytes(Object object, SerializerFeature... features) {
        return toJSONBytes(object, DEFAULT_GENERATE_FEATURE, features);
    }

这是我们去调用的方法,来看看简单使用:

 Season season = new Season();
        season.setColor(Color.GREEN);
        season.setSeason("Spring");
        season.setDate(new Date());
        season.setList(null);
        System.out.println(JSON.toJSONBytes(season));
        System.out.println(JSON.parse(JSON.toJSONBytes(season)));

输出:
在这里插入图片描述
该方法将对象序列化为Byte[]数组,通过反序列化的方式又可以转回来

源码分析

 public static byte[] toJSONBytes(Charset charset, //
                                     Object object, //
                                     SerializeConfig config, //
                                     SerializeFilter[] filters, //
                                     String dateFormat, //
                                     int defaultFeatures, //
                                     SerializerFeature... features) {
        SerializeWriter out = new SerializeWriter(null, defaultFeatures, features);

        try {
            JSONSerializer serializer = new JSONSerializer(out, config);

            if (dateFormat != null && dateFormat.length() != 0) {
                serializer.setDateFormat(dateFormat);
                serializer.config(SerializerFeature.WriteDateUseDateFormat, true);
            }

            if (filters != null) {
                for (SerializeFilter filter : filters) {
                    serializer.addFilter(filter);
                }
            }

            serializer.write(object);
            return out.toBytes(charset);
        } finally {
            out.close();
        }
    }

这是经过层层调用后,该方法最终使用的方法源码;
其中的参数SerializeFilter我们将在下一篇博客中进行分析;我们本次着重来看toJSONBytes方法的实现。
与toJSONString相似,还是通过JSONSerializer的write方法来实现的;

Class<?> clazz = object.getClass();
ObjectSerializer writer = getObjectWriter(clazz);

在write方法中,关键就是获得了writer对象,这里调用的getObjectWriter方法实际深入到了SerializerConfig中,大致上是先检测该类是否为基本java基本类型,如果不是则通过反射的方式来获取该类的相关信息,并将类名与对应的信息存入SerializerConfig类维护的IdentityHashMap中;
由于最终获得的writer对象是ObjectSerializer,这是个接口,有很多的类实现了这个接口,我们假设要转换的Object是String,以StringCodec类为例,那么此处调用的write方法就是StringCodec的write方法:

 public void write(JSONSerializer serializer, String value) {
        SerializeWriter out = serializer.out;

        if (value == null) {
            out.writeNull(SerializerFeature.WriteNullStringAsEmpty);
            return;
        }

        out.writeString(value);
    }

其中的关键就是writeString方法,我们再点开看:
发现里面的writeStringWithDoubleQuote方法用了很多if来判断不同的输出,如:

if (isEnabled(SerializerFeature.BrowserSecure)) {
                       if (ch == '(' || ch == ')' || ch == '<' || ch == '>') {
                            write('\\');
                            write('u');
                            write(IOUtils.DIGITS[(ch >>> 12) & 15]);
                            write(IOUtils.DIGITS[(ch >>> 8 ) & 15]);
                            write(IOUtils.DIGITS[(ch >>> 4 ) & 15]);
                            write(IOUtils.DIGITS[ch & 15]);
                            continue;
                        }
                    }

再里面的write方法:

public void write(int c) {
        int newcount = count + 1;
        if (newcount > buf.length) {
            if (writer == null) {
                expandCapacity(newcount);
            } else {
                flush();
                newcount = 1;
            }
        }
        buf[count] = (char) c;
        count = newcount;
    }

将最终的结果写到buf[]这个数组里面,完成了向bytes[]数组的转换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值