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[]数组的转换。