alibaba fastjson的JsonObject有序的实现和源码分析

介绍

FastJson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。在使用的过程中,因为有序性问题导致踩了坑,看一下其底层源码,了解其有序性上的实现。

分析1:

JSONObject inputInfo = manifestDraftObj.getJSONObject("inputInfo");

这里在使用的时候,以为get出来的数据是引用关系的,修改会影响到原先Object里面的数据,但实际情况并不是这样子通过get拿到的object,对这个object的修改不会影响到原先那个object,get到的object是复制出来的,可以在JSON类里面的toJSON(Object javaObject, SerializeConfig config)方法看到,新new了个JSONObject,且内部是linkedHasMap,最终返回的是这个拷贝出来的Map。

image-20231102101426157

通过上述代码拿到的object,其实其内部已经linkedHashMap的有序Map了

至于为什么默认是有序的LinkedHashMap,追源码看一看

image-20231102105225169

当一个请求进来,我们的系统会使用反射去调用url下指定的controller的method,同时会对参数进行初始化,会根据参数指定的类型进行初始化,这里会进入MapDeserializer类,并且在这里面执行deserialize()方法,生成我们当前需要的JSONObject,且是LinkedHashMap的,如下图:

image-20231102105621588

在这里,调用了_readAndBindStringKeyMap后,会将我们需要的JSONObject存到result里面,并返回,进入这个方法看一看,这个方法会在valueDes.deserialize(p,ctxt)进行map的生成和组装。

image-20231102105710760

进入valueDes.deserialize(p,ctxt)方法,可以看到LinkedHashMap的创建和赋值

image-20231102105842205

自此参数生成完毕,回到我们最开始的jsonobject的getObject方法,现在我们明白为什么会是LinkdedHashMap了,在这里(map instanceof LinkedHashMap)条件会成立,进入赋值和创建。

image-20231102101426157

分析2:

JSON.parseObject(manifestDraft.getInputDraft() , Feature.OrderedField)

parseObject默认返回的是无序的map,要得到有序需要加Feature.OrderedField

部分源码上的分析:

使用上述代码,会进入到DefaultJSONParser,在这里创建有序的JSONObject

image-20231102110843244

在new JSONObject的时候,会进入JSONObject的构造方法,最后创建出个LinkedHashMap

image-20231102110915994

最后来到parseObject方法,完成填值

image-20231102111157557

posted @ 2023-11-02 11:23  scottyzh  阅读(480)  评论(0编辑  收藏  举报