介绍
经过分词和抽象语法树生成后,我们就可以根据语法树生成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分支
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。