解析多层嵌套json模板的JsonUtil类

公司让开发一个解析现有模板的的json类。
  json模板是这样样子的多层嵌套json对象,本来要解决jsonObect和jsonArray两种类型的对象,但是仔细核对过后发现,在业务中并没有使用到jsonArray这种类型的对象。所以我先做了解析多层嵌套JsonObject的JsonObject对象。
  先开看一下我们要使用到的Json模版

	{
	"一班":{
		"座位2":{
			"studentAge":13,
			"studentName":"李四"
		},
		"座位1":{
			"studentAge":12,
			"studentName":"张三"
		}
	},
	"二班":{
		"座位3":{
			"studentAge":14,
			"studentName":"王五"
		},
		"座位4":{
			"studentAge":15,
			"studentName":"赵六"
		}
	}
}

那么这里我使用的嵌套是两层嵌套 第一级是班,第二级是座位但是在实际生产过程中,并不知道有多少级Json嵌套。那么就需要自动的来确定Json嵌套的层数。先来看我的Util类吧。

package com.kx.www;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;

public class JsonUtils {
	private String jsonMode="";
	/**
	 * 单个key 修改 json模版 
	 * @param jsonMode
	 *            jsonString模板
	 * @param key
	 *            传入XX.XX.XX.AA(标识要修改那个字段)
	 * @param value
	 *            json模版 String 字符串
	 * @return
	 * 			  json模版 String 字符串  如果key值在模版中有那么返回修改后的模版,如果key在模版中没有那么返回传入的模版
	 */
	public String PutNewValue(String jsonMode, String key, String value) {
		JSONObject jsonObject = JSONObject.parseObject(jsonMode);
		// 把接收到的json格式的字符串模板转换为json对象
		// 切分 遍历key 拿出前面节点 和最后一个key值
		String[] keys = key.split("\\.");
		List<JSONObject> list = new ArrayList<JSONObject>();
		list.add(jsonObject);
		for (int i = 0; i < keys.length - 1; i++) {
			try {
				jsonObject = jsonObject.getJSONObject(keys[i]);
			} catch (Exception e) {
				return jsonMode;
			}
			list.add(jsonObject);
		}
		jsonObject.put(keys[keys.length - 1], value);
		for (int i = keys.length - 2; i >= 0; i--) {
			list.get(i).put(keys[i], list.get(i + 1));
		}
		jsonObject = list.get(0);
		return formatJson(jsonObject.toString());
	}
	/**
	 * 多个key值 单个value值修改json模版
	 * @param jsonMode
	 * 				jsonString模板
	 * @param keys
	 * 				传入XX.XX.XX.AA(标识要修改那个字段) 这样形式的String数组
	 * @param value
	 * 				要修改的值
	 * @return 
	 * 				json模版 String 字符串  如果key值在模版中有那么返回修改后的模版,如果key在模版中没有那么返回传入的模版
	 */
	public String PutNewValue(String jsonMode, String[] keys, String value) {
		String result = jsonMode;
		for (String key : keys) {
			result = PutNewValue(result, key, value);
		}
		return result;
	}
	/**
	 * 多个key值 多个value值批量修改 json模版
	 * @param jsonMode
	 * @param map
	 * 			key传入XX.XX.XX.AA(标识要修改那个字段) value与key对应的value值
	 * @return
	 */
	public String PutNewValue(String jsonMode,Map<String, String> map) {
		String result = jsonMode;
		for (String key :map.keySet()) {
			result = PutNewValue(result, key, map.get(key));
		}
		return result;
	}
	/**
	 * 格式化Json串
	 * 
	 * @param jsonStr
	 * @return
	 */
	public static String formatJson(String jsonStr) {
		if (null == jsonStr || "".equals(jsonStr)) {
			return "";
		}
		StringBuilder sb = new StringBuilder();
		char last = '\0';
		char current = '\0';
		int indent = 0;
		for (int i = 0; i < jsonStr.length(); i++) {
			last = current;
			current = jsonStr.charAt(i);
			switch (current) {
			case '{':
			case '[':
				sb.append(current);
				sb.append('\n');
				indent++;
				addIndentBlank(sb, indent);
				break;
			case '}':
			case ']':
				sb.append('\n');
				indent--;
				addIndentBlank(sb, indent);
				sb.append(current);
				break;
			case ',':
				sb.append(current);
				if (last != '\\') {
					sb.append('\n');
					addIndentBlank(sb, indent);
				}
				break;
			default:
				sb.append(current);
			}
		}
		return sb.toString();
	}

	/**
	 * 添加space
	 */
	private static void addIndentBlank(StringBuilder sb, int indent) {
		for (int i = 0; i < indent; i++) {
			sb.append('\t');
		}
	}

}

代码中规定好了传入key的规则然后解析字符串让其从层json对象中取出想要对象或者值然后再逐层放回去。

补充

后面我有尝试这做修改jsonArray中的数据的util类和上面的模板类似,不过在其中加入了JsonArray不再是单纯的jsonObject类型的数据。

{
	"一班": {
		"座位2": {
			"studentAge": 13,
			"studentName": "李四"
		},
		"座位1": {
			"studentAge": 12,
			"studentName": "张三"
		}
	},
	"二班": {
		"座位3": {
			"studentAge": 14,
			"studentName": "王五"
		},
		"座位4": {
			"studentAge": 15,
			"studentName": "赵六"
		}
	},
	"三班": [{
		"studentAge": 14,
		"studentName": "王五"
	}, {
		"studentAge": 15,
		"studentName": "赵六"
	}]
}

三班没有二级JosnObject 而是一个Json数组,我写的util是在下面。

/**
	 * 确定是JsonObject还是JsonArray
	 * @param jsonObject
	 * @param firstkey
	 * @return
	 */
	private String ArrOrObj(JSONObject jsonObject, String firstkey) {
		try {
			Object object = jsonObject.getJSONObject(firstkey);
			if (object instanceof JSONObject) {
				return "OBJECT";
			}
		} catch (Exception e) {
			return "ARRAY";
		}
		return "ERROR";
	}

	/**
	 * 这个代码可能用不了只是提供一种思路吧
	 * @param jsonMode
	 * @param key
	 * @param value
	 * @return
	 */
	public String PutNewValue1(String jsonMode,String key,String value) {
		
		//把接收到的json格式的字符串模板转换为json对象
		JSONObject jsonObject = JSONObject.parseObject(jsonMode);
		JSONArray jsonArray = new JSONArray();
		//切分 遍历key 拿出前面节点 和最后一个key值
		String [] keys = key.split("\\.");
		List<JSONObject> list = new ArrayList<JSONObject>();
		list.add(jsonObject);
		for (int i = 0; i < keys.length-1; i++) {
			String result = ArrOrObj(jsonObject,keys[i]);
			try {
				//就得判断这个keys是Object还是Array
				if(result == "ARRAY") {
					jsonArray = jsonObject.getJSONArray(keys[i]);
					String ja = jsonArray.toString();
					List list1  = JSONObject.parseArray(ja, String.class);
					//写到这 就出现了我想不到解决办法的问题,那么,在我上面的模板中,怎么确定待修改的数据是list1中那个对象的值.
					//想到这里 如果说想要知道是那个对象的值.那么在传入key的时候就需要指定. 那么用户用户,或者说其他编码人员怎么知道,就将key 的规则破坏.
					
				}else if(result == "OBJECT") {
					jsonObject=jsonObject.getJSONObject(keys[i]);
				}
			} catch (Exception e) {
				System.out.println("模版文件中找不到节点,或者没有该字段");
			}
			list.add(jsonObject);
		}
		jsonObject.put(keys[keys.length-1], value);
		for (int i = keys.length-2; i >=0; i--) {
			list.get(i).put(keys[i] , list.get(i+1));
		}
		jsonObject = list.get(0);
		
		return formatJson(jsonObject.toString());
	}

首先的判断这个Json对象中的对象是Object还是Array 那么确定这个之后才能进行下面的操作。

你可能感兴趣的:(工作问题)