基于动态字节码编译技术的codejson框架的制作方法_3

文档序号:9810288阅读:来源:国知局
3]13.1f(cache.1sCommaLast())
[0094]14.{
[0095]15.cache.deleteLast();
[0096]16.}
[0097]17.cache.append(,},);
[0098]18.}
[0099]反序列化:
[0100]反序列化首先是解析json字符串。在这一步,框架设计了一种无回退的单次字符读取方式。大致原理是依次读取每一个字符,如果遇到一些特殊的表示字符,比如{,},:,[,]等等。在遇到这些字符的时候生成jsonOb ject或者jsonArray来进行相应的读取处理。使用两个堆桟,一个堆桟存储jsonKey,一个堆桟存储当前待处理的json对象(jsonOb ject或者jsonArray)。这样子在处理的过程中就可以达到顺序处理的效果。解析的速度非常快,可以达到数倍于fast json的性能。将一个json对象反序列化成po jo,原理上和序列化大致相同。通过将对象的所有set方法得到。动态编译一个设置类,该类中对于每一个set方法,都生成类似:
[0101]if(j sonOb ject.containsKey( ^ name ^)) {entity.setName(jsonObject.getString( "name"))}这样的代码。由于是动态编译,所以事先知道需要进行哪些判断,而且判断完之后是原生代码的set操作,节省了判断时间和调用反射时间,故而反序列化的性能也是非常的优秀,其性能是fastjson性能的好几倍。
[0102]因为json是一个kv结构。所以算法设计了两个堆栈结构。堆栈结构,在数据顺序上和算法要求的一遍读取无回溯是相吻合的。
[0?03]键堆桟用来压入待处理的jsonkey,值堆桟用来压入每次发现的jsonOb ject或者jsonArrayο
[0104]解析json字符串的算法的思路大致可以描述为:
[0105]1.创建两个堆栈结构用来存储数据;
[0106]2.逐个字符的读取数据,如果遇到标志字符,比如{,},:,[,],,,’〃 ’等进行特别处理,记录发现位置,根据发现位置决定是否创建新的jsonOb ject或者jsonArray进行嵌套等;
[0107]3.重复过程2,直到字符读取完毕。如果全部读取完毕则返回值堆栈最上方的json(此时键堆栈应该为空,值堆栈只有一个数据),如果json字符串不符合规范,则在解析过程中会被发现,程序抛出异常。
[0108]将一个json对象反序列化成Pojo,和序列化的流程相似,算法的大致思路如下:
[0109]1.获取po jo的所有set方法;
[0??0] 2.编译动态代码,在动态代码的开始处,仓Il建类似代码EntityClass entity =newEntityClassO ;。使用pojo的类创建一个Po jo对象供后面使用;
[0111 ] 3.针对第一步获得的每一个set方法,根据javabean规范取得该set方法对应的属性名,构建类似这样
[0112]if(json.containsKey(〃name〃)){entity.setName(json.getString(〃name〃))}的代码,其中name就是根据set方法计算出来的属性名;
[0113]4.所有set方法完成后就将这份代码编译生成一个针对特定对象的转换类,将这个读取类放入一个Map中管理,key为需要转换的类,value为生成的转换类。如果在第3步分析的过程中,发现了非基本属性,也就是嵌套对象。则嵌套执行1-4的步骤。并且针对这个属性,生成类似if (json.containsKey ("another0b ject")) {entity.setAnotherOb ject(readContext.read(AnotherOb ject.class , json.getString(〃name〃)))}的代码,其中代8(1(:011丨611:就是一个保存?0」0和转换类映射关系的1&1?容器。
[0114]经过以上的四个步骤,就完成了一个输出类的代码生成,使用这个输出类对特定的对象进行反序列化就可以达到非常高的性能。
[0115]具体地,如图2所示,所述反序列化方法是基于以上思想来实现的,所述反序列化方法包括如下步骤:
[0116]步骤B1、创建两个堆栈结构用来存储数据,两个堆栈分别为键堆栈和值堆栈,所述键堆桟用来存储j son结构中的j sonkey (j son是一个键-值结构,j sonkey就是键),所述值堆桟用来存储 json 对象、json0bject( jsonObject 的结构为{ “a”:,,b” })或 jsonArray(jsonArray的结构是{ “a”: [ I,2,3]});
[ΟΙ17] 步骤Β2、读取index (设定一个index用来表示当前读取字符的位置,初始为O,逐步前进)位置的字符,并进行分析;
[0118]若字符为{,则创建一个新的」801101^601:,压入值堆桟中,再判断jsonkey是否为空,如果jsonkey不为空,则将jsonkey压入键堆桟中,并设置jsonkey为空且flag(flag为上一次解析的位置,初始值也为O)为O,进入步骤B3;如果jsonkey为空,则直接进入步骤B3;
[0?19]若字符为},则判断flag是否为O,如果flag不为O,则将index到flag之间的内容解析为value( value为一个临时值,用来表示flag到index之间的内容),再判断value是否为空,如果value不为空,则将jsonkey和value设置到值堆桟最上方的jsonObject中,并设置jsonkey为空且flag为O,如果value为空,则直接设置j sonkey为空且flag为O ;接着判断值堆栈的大小,如果flag为O,则直接判断值堆栈的大小,如果值堆栈的大小是小于或等于I,则将值堆桟最上方的jsonOb ject弹出,并返回该jsonOb ject后,结束流程,如果值堆桟的大小是大于I,则值堆桟弹出为jsonObject,然后判断值堆桟最上方是否为jsonObject,如果值堆桟最上方为jsonObject,则键堆桟弹出为jsonkey,并和jsonObject—起设置到值堆桟最上方的jsonObject中,进入步骤B3;如果值堆桟最上方不为jsonObject,则将jsonObject加入到值堆桟最上方的jsonArray中,进入步骤B3;
[0? 20]若字符为[,则创建一个新的jsonArray,压入值堆桟中,判断jsonkey是否为空,如果jsonkey不为空,则将jsonkey压入键堆桟,并设置jsonkey为空,接着将flag设置为index+1,进入步骤B3;如果jsonkey为空,则不进行任何操作;
[°121 ] 若字符为],则判断flag的值,如果flag不为O且flag不为index,则读取index到flag的字符,解析为value,接着判断value是否为空,如果value不为空,则将value压入值堆桟最上方的jsonArray中,再将flag设置为O,如果value为空,则直接将flag设置为O,然后判断值堆桟的大小,如果flag为O或flag为index,则直接判断值堆桟的大小,如果值堆桟的大小是不大于I,则将值堆桟最上方的jsonArray弹出并且返回该jsonArray后,结束流程,如果值堆栈的大小是大于1,则将值堆栈弹出为jsonArray,然后判断值堆栈最上方是否为jsonObject,如果值堆桟最上方是jsonObject,则将键堆桟弹出为key,并和jsonArray—起设置到值堆桟最上方的jsonObject,进入步骤B3;如果值堆桟最上方不是jsonObject,贝Ij将jsonArray加入到值堆桟最上方的jsonArray中(这个是可以嵌套的,比如[[I,2], [3,4]]这最外面是jsonArray,里面每一个元素也是jsonArray),进入步骤B3;
[0122]若字符为“,则判断之前是否有遇到“字符,如果之前没有遇到,则将flag设置为index+Ι后,进入步骤B3 ;如果之前有遇到,则接着判断值堆桟最上方是否为jsonObject,如果值堆桟最上方是jsonObject,则继续判断jsonkey是否为空,如果jsonkey为空,则读取flag到index的字符,成为jsonkey后,将flag设置为O,然后进入步骤B3;如果jsonkey不为空,则读取flag到index的字符为value,将j sonkey和value放入值堆桟最上方的jsonObject,设置jsonkey为空,接着将flag设置为O,然后进入步骤B3;如果值堆桟最上方不是jsonObject,则读取flag到index部分的值成为value,添加到值堆桟最上方的jsonArray后,将flag设置为O,然后进入步骤B3 ;
[0123]若字符为:,则判断flag是否为O,如果flag为O,则将flag设置为index+Ι,然后进入步骤B3 ;如果flag不为O,则进入步骤B3 ;
[0? 24]若字符为,,则判断flag是否为O,如果flag不为O,则读取index到flag位置的值为value,接着判断值堆桟最上方是否为jsonObject,如果值堆桟最上方不为jsonObject,贝Ij判断value是否为空,如果value不为空,则将value添加到值堆桟最上方的jsonArray,再将flag设置为index+Ι,然后进入步骤B3;如果value为空,则直接将flag设置为index+
当前第3页1 2 3 4 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1