Json字符串解析原理、超大json对象的解析

 

概述

附上完整的代码:

public class JsonObject extends HashMap<String,Object> {  }  public class JsonArray extends ArrayList<Object> {  }
复制代码

 

JSON字符串的解析

以这个字符串为例:

{“success”:true,”id”:-10.5,”employees”:[{“firstName”:”Bill”,”lastName”:”Gates”},{“firstName”:”George”,”lastName”:”Bush”},{“firstName”:”Thomas”,”lastName”:”Carter”}]}

我们保证在只扫描一次整个的情况下,就将json结构解析成功。

 

传统的解析策略通常是通过词法分析,将json分为一个个的token,而这些token有着自己的类型和值;再通过语法分析构建一棵抽象语法树,进一步处理。比如""是一种,true/false又是一种。

其实根本不需要这么复杂。依我看来,json的token只有五种:true/false/null(归为一种,因为它们是固定值)、number、string、object、array。也不用特别在意start和end的Token区分,比如 { 符号和 } 符号。从一个 { 符号开始,到下一个它对应的 } 符号都是属于同一个json object的。这里的 { 与 } 、[ 与 ] 符号都是一一对应的。
我设计了一个nextObject()方法,它可以解析出json字符串中的下一个对象,然后在适当的时候装配即可。

 

nextObject方法的实现

提取字符

 

复制代码
    public static boolean isSpace(char c){         return c == ' ' || c == '\r' || c == '\n';     }      //方法得到当前字符,忽略空格、换行符    private char getChar(){         char c = json.charAt(pos);         while(isSpace(c)){             pos++;             c = getCurrentChar();         }         return c;     }
复制代码

 

上面方法是消耗掉所有空白字符,直到读取到一个非空白字符,isSpace方法用于判断一个字符是否属于空白字符,pos表示当前指针指向的那个字符。也就是说,DFA从起始状态开始,若读到一个空字符,会在起始状态不断循环,直到遇到非空字符,状态转移情况如下:

 

解析

 

根据提取到的字符,转入不同的解析方法中,

例如字符是t,说明值可能是true,只需检查后面三个字符,如果是r、u、e,则可以直接返回true。

字符是f,说明值可能是false,只需检查后面四个字符,如果是a、l、s、e,则可以直接返回false。

碰到 \”,说明是字符串,在下一个\”出现之前,把扫描出来的字符都当成字符串中的字符,放到一个StringBuilder中去。

碰到 [ 符号,说明是数组了,就需要new一个JsonArray,在下一个 ] 符号出现之前,调用nextObject方法,把解析到的对象都放到这个JsonArray里面去。

碰到 { 符号,说明是JsonObject,就new一个JsonObject,这里每次需要连续调用两次nextObject,第一次结果作为key,第二次结果作为value。放到JsonObject中去。

解析boolean、null值

这类值的字符串只有固定的三种true、false、null,是最好解析的。在扫描到第一个字符为t、f、n时,只需检测后续字符是否符合固定值就可以了。checkChars方法实现了这个功能,chars是固定的序列,如果检测通过则返回true,否则返回false。

复制代码
private boolean checkChars(char ...chars){         for(char ch : chars){             char c = getCurrentCharNext();   //得到当前字符,包括空格、换行符。将指针指向下一个字符            if(Character.toLowerCase(ch) != Character.toLowerCase(c)){                 return false;             }         }         return true;     }
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信