介绍

通过分词和形象语法树生成后,咱们就能够依据语法树生成java对象,为了让程序尽量简略,object用Map返回,array用List<Map>返回,根本类型间接返回value

实现

语法树到对象的生成绝对还是比较简单,首先咱们定义了一个总的入口函数

/** * 将json生成java对象 * * @param item * @return */public Object generate(Ast item) {    if ("array".equals(item.getType())) {        //返回数组对象        return generateList(item);    } else if ("object".equals(item.getType())) {        //返回object对象        return generateObject(item);    } else if ("value".equals(item.getType())) {        //根本类型json对象,比方"100"也是一个json对象        return item.getValue();    }    return null;}

对应三种类型的解决形式

generateObject

/** * 生成object对象 * * @param astItem * @return */public Map generateObject(Ast astItem) {    //object对象以Map模式返回    Map<String, Object> object = new HashMap<>();    for (Ast ast : astItem.getItems()) {        Object value = null;        if ("object".equals(ast.getType()) || "array".equals(ast.getType())) {            value = generate(ast);        } else if ("value".equals(ast.getType())) {            value = ast.getValue();        }        object.put(ast.getName(), value);    }    return object;}
  • 遍历object的字段
  • 如果是object或者array,那么通过入口函数进行递归
  • 如果是value间接取value值就行

generateList

/** * 生成object对象数组 * * @param item * @return */public List<Object> generateList(Ast item) {    //数组对象以List<Object>模式返回    List<Object> result = new ArrayList<>();    for (Ast child : item.getItems()) {        if ("object".equals(child.getType())) {            result.add(generateObject(child));        } else if ("value".equals(child.getType())) {            result.add(child.getValue());        } else if ("array".equals(child.getType())) {            result.add(generateList(child));        }    }    return result;}
  • 遍历数组列表
  • 如果是object进入对象处理函数
  • 如果是value间接取值
  • 如果是array递归进入数组处理函数

测试

咱们将生成的对象从新用fastjson变成json比照后果

public class Main {    public static void main(String[] args) throws Exception {        InputStream fin = Main.class.getResourceAsStream("/example.json");        byte[] buf = new byte[fin.available()];        fin.read(buf);        fin.close();        String json = new String(buf, "utf-8");        JSONParser parser = new JSONParser();        List<Token> tokens = parser.tokenizer(json);        tokens = parser.tokenClean(tokens);        List<Ast> astItems = parser.generateAST();        Ast ast = astItems.get(0);        Object object = parser.generate(ast);        System.out.println(String.format("|%-12s|%-12s|%-15s|", "type", "valueType", "value"));        System.out.println("-------------------------------------------");        for (Token t : tokens) {            System.out.println(String.format("|%-12s|%-12s|%-15s|",                    t.getType(),                    t.getValueType(),                    t.getValue()));        }        System.out.println("-------------------------------------------");        System.out.println(JSON.toJSONString(ast, true));        System.out.println(JSON.toJSONString(object, true));    }}

后果

{    "birthday":"1992-02-08",    "name":"asan",    "description":"a \"hudsom\" man",    "location":{        "area":"晋江市",        "province":"福建省",        "city":"泉州市"    },    "salary":1234.56,    "family":[        {            "name":"Helen",            "relation":"couple"        },        {            "name":"XiaoMan",            "relation":"daughter"        }    ],    "married":true,    "age":32,    "tags":[        "coder",        "mid-age"    ]}

除了字段程序外其余数据都和原始的示例json一样,阐明后果是正确的,至此咱们实现了一个json解析器全副的工作。

代码

残缺代码请参考我的项目https://github.com/wls1036/tiny-json-parser的0x04分支