jackson 用流的形式解析json

工作中有个需求,就是用流的形式解析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


你可能感兴趣的:(JavaSE)