工作中有个需求,就是用流的形式解析json文档。 我们采用了jackson框架来处理json文件。
业务逻辑里有个特殊的需求,就是当解析到一个FIELD_NAME时,要得到他的完整名字(嵌套在很多层里) 而且还要知道这个FILED_NAME的类型,是object还是array还是基本类型等等。 但是用流解析时,parser过去之后就回不来了,而当我的parser在FIELD_NAME时,我需要知道parser的下一项是什么,而且我有要parser停留在FILED_NAME上,这样的话一个parser是做不到了 于是我用了两个parser,相当于两个指针,一前一后的遍历json文件。
可能表述的不是很清楚,还是直接看看代码吧
package com.nothing.jackson;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
public class Better {
@SuppressWarnings("boxing")
public static void main(String[] args) throws IOException, Exception {
JsonFactory f = new JsonFactory();
JsonParser p = f.createJsonParser(new File("c:/countries222.json"));
JsonParser q = f.createJsonParser(new File("c:/countries222.json"));
final String TOP_ARRAY = "[TopArray]";
final String TOP_OBJECT = "TopObj";
List fatherList = new ArrayList();
List nameList = new ArrayList();
Map map = new HashMap();
q.nextToken();// q is the next token of p
while (p.nextToken() != null) {
q.nextToken();
// System.out.println("p--->" + p.getCurrentToken());
// System.out.println("q--->" + q.getCurrentToken());
if (p.getCurrentToken() == JsonToken.START_OBJECT) {
if (p.getCurrentName() != null) {// 非数组中的obj
fatherList.add(p.getCurrentName());
} else if (p.getCurrentName() == null ) {// 数组中的obj或者TopObj
if(fatherList.size()==0){//TopObj
fatherList.add(TOP_OBJECT);
}else if (fatherList.size()!=0){//数组中的Obj
String father = StringUtils.join(fatherList, '.');
map.put(father, map.get(father)+1);
}
}
}
if (p.getCurrentToken() == JsonToken.END_OBJECT) {
if (!"".equals(fatherList) && p.getCurrentName() != null) fatherList.remove(fatherList.size() - 1);
}
if (p.getCurrentToken() == JsonToken.START_ARRAY) {
if (p.getCurrentName() != null) {
fatherList.add("[" + p.getCurrentName() + "]");
String father = StringUtils.join(fatherList, ".");
map.put(father, 0);
} else if (p.getCurrentName() == null) {//即这个array是topArray
fatherList.add(TOP_ARRAY);
String father = StringUtils.join(fatherList, '.');
map.put(father, 0);
}
}
if (p.getCurrentToken() == JsonToken.END_ARRAY) {
String father = StringUtils.join(fatherList, ".");
if (fatherList.size() == 0) {
father = TOP_ARRAY;
}
System.out.println(father + " size : \t" + map.get(father));
fatherList.remove("[" + p.getCurrentName() + "]");
}
if (p.getCurrentToken() == JsonToken.FIELD_NAME) {
if (q.getCurrentToken() == JsonToken.START_ARRAY) {
// 如果p指向的是个数组,名字为father+[text]
nameList.addAll(fatherList);
nameList.add("[" + p.getText() + "]");
String name = StringUtils.join(nameList, '.');
System.out.println("Enconter: \t" + p.getText());
System.out.println("propertyName: \t" + name);
System.out.println("Type: \t\t" + q.getCurrentToken());// 当p指向的是FIELD_NAME时,要用q来获得类型
nameList.removeAll(nameList);
System.out.println("--------------------------------------");
} else if (p.getCurrentToken() == JsonToken.FIELD_NAME
&& (q.getCurrentToken() == JsonToken.START_OBJECT || Pattern.matches("VALUE_\\w+", q.getCurrentToken().toString()))) {
// 如果p指向的不是数组,名字为 father+text
nameList.addAll(fatherList);
nameList.add(p.getText());
String name = StringUtils.join(nameList, '.');
System.out.println("Enconter: \t" + p.getText());
System.out.println("propertyName: \t" + name);
System.out.println("Type: \t\t" + q.getCurrentToken());// 当p指向的是FIELD_NAME时,要用q来获得类型
nameList.removeAll(nameList);
System.out.println("--------------------------------------");
}
}
if (Pattern.matches("VALUE_\\w+", p.getCurrentToken().toString())) {
if (p.getCurrentName() != null) {// 非数组中的value
nameList.addAll(fatherList);
nameList.add(p.getCurrentName());
String name = StringUtils.join(nameList, '.');
System.out.println("Enconter: \t" + p.getText());
System.out.println("propertyName: \t" + name);
nameList.removeAll(nameList);
System.out.println("Type: \t\t" + p.getCurrentToken());// 当p指向VALUE_*时,通过p自己可以获得类型
System.out.println("--------------------------------------");
} else if (p.getCurrentName() == null) {// 数组中的value
String father = StringUtils.join(fatherList, '.');
if (fatherList.size() == 0) {
father = TOP_ARRAY;
}
System.out.println("Enconter: \t" + p.getText());
System.out.println("propertyName: \t" + father);
map.put(father, map.get(father) + 1);
System.out.println("Type: \t\t" + p.getCurrentToken());
System.out.println("--------------------------------------");
}
}
}
p.close();
}
}
c:/coutries222.json文档如下:
{
"国家": {
"中国": {
"省份": [
{
"名称": "浙江",
"城市": [
"杭州",
"宁波"
]
},
{
"名称": "江苏",
"城市": [
"苏州",
"南京",
"无锡",
"徐州"
]
}
],
"area" : 9600
},
"其他国家": [
"英国",
"德国",
"日本"
]
}
}
Enconter: 国家
propertyName: TopObj.国家
Type: START_OBJECT
--------------------------------------
Enconter: 中国
propertyName: TopObj.国家.中国
Type: START_OBJECT
--------------------------------------
Enconter: 省份
propertyName: TopObj.国家.中国.[省份]
Type: START_ARRAY
--------------------------------------
Enconter: 名称
propertyName: TopObj.国家.中国.[省份].名称
Type: VALUE_STRING
--------------------------------------
Enconter: 浙江
propertyName: TopObj.国家.中国.[省份].名称
Type: VALUE_STRING
--------------------------------------
Enconter: 城市
propertyName: TopObj.国家.中国.[省份].[城市]
Type: START_ARRAY
--------------------------------------
Enconter: 杭州
propertyName: TopObj.国家.中国.[省份].[城市]
Type: VALUE_STRING
--------------------------------------
Enconter: 宁波
propertyName: TopObj.国家.中国.[省份].[城市]
Type: VALUE_STRING
--------------------------------------
TopObj.国家.中国.[省份].[城市] size : 2
Enconter: 名称
propertyName: TopObj.国家.中国.[省份].名称
Type: VALUE_STRING
--------------------------------------
Enconter: 江苏
propertyName: TopObj.国家.中国.[省份].名称
Type: VALUE_STRING
--------------------------------------
Enconter: 城市
propertyName: TopObj.国家.中国.[省份].[城市]
Type: START_ARRAY
--------------------------------------
Enconter: 苏州
propertyName: TopObj.国家.中国.[省份].[城市]
Type: VALUE_STRING
--------------------------------------
Enconter: 南京
propertyName: TopObj.国家.中国.[省份].[城市]
Type: VALUE_STRING
--------------------------------------
Enconter: 无锡
propertyName: TopObj.国家.中国.[省份].[城市]
Type: VALUE_STRING
--------------------------------------
Enconter: 徐州
propertyName: TopObj.国家.中国.[省份].[城市]
Type: VALUE_STRING
--------------------------------------
TopObj.国家.中国.[省份].[城市] size : 4
TopObj.国家.中国.[省份] size : 2
Enconter: area
propertyName: TopObj.国家.中国.area
Type: VALUE_NUMBER_INT
--------------------------------------
Enconter: 9600
propertyName: TopObj.国家.中国.area
Type: VALUE_NUMBER_INT
--------------------------------------
Enconter: 其他国家
propertyName: TopObj.国家.[其他国家]
Type: START_ARRAY
--------------------------------------
Enconter: 英国
propertyName: TopObj.国家.[其他国家]
Type: VALUE_STRING
--------------------------------------
Enconter: 德国
propertyName: TopObj.国家.[其他国家]
Type: VALUE_STRING
--------------------------------------
Enconter: 日本
propertyName: TopObj.国家.[其他国家]
Type: VALUE_STRING
--------------------------------------
TopObj.国家.[其他国家] size : 3