介绍
通过分词和形象语法树生成后,咱们就能够依据语法树生成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分支