package org.voovan.tools.json; import org.voovan.tools.TObject; import org.voovan.tools.TString; import org.voovan.tools.log.Logger; import org.voovan.tools.reflect.TReflect; import java.io.IOException; import java.io.StringReader; import java.text.ParseException; import java.util.*; /** * JSON字符串分析成 Map * * @author helyho * * Voovan Framework. * WebSite: https://github.com/helyho/Voovan * Licence: Apache v2 License */ public class JSONDecode { private static int E_OBJECT = 1; private static int E_ARRAY = -1; public static Object parse(String jsonStr) { return parse(new StringReader(jsonStr.trim()+"\0")); } /** * 解析 JSON 字符串 * 如果是{}包裹的对象解析成 HashMap,如果是[]包裹的对象解析成 ArrayList * @param reader 待解析的 JSON 字符串 * @return 解析后的对象 */ public static Object parse(StringReader reader) { try { if (reader == null) { return null; } int type = 0; Object jsonResult = null; boolean isFirstChar = true; //根据起始和结束符号,决定返回的对象类型 if (type == 0) { char flag = (char) reader.read(); if (flag == '{') { type = E_OBJECT; } if (flag == '[') { type = E_ARRAY; } } //对象类型构造返回的对象 if (E_OBJECT == type) { jsonResult = (Map) new HashMap<String, Object>(); isFirstChar = false; } else if (E_ARRAY == type) { jsonResult = (List) new ArrayList<Object>(); isFirstChar = false; } else { reader.skip(-1); } String keyString = null; Object value = null; int stringWarpFlag = 0; int functionWarpFlag = 0; boolean isString = false; boolean isFunction = false; int isComment = 0; StringBuilder itemString = new StringBuilder(); char currentChar = 0; char nextChar = 0; char prevChar = 0; while (true) { currentChar = (char) reader.read(); nextChar = (char) reader.read(); if (nextChar != 65535) { reader.skip(-1); } if (!isFirstChar) { reader.skip(-2); prevChar = (char) reader.read(); reader.skip(1); } isFirstChar = false; //分析字符串,如果是字符串不作任何处理 if (currentChar == '"') { //i小于1的不是转意字符,判断为字符串(因为转意字符要2个字节),大于2的要判断是否\\"的转义字符 if (nextChar != 0 && prevChar != '\\') { stringWarpFlag++; //字符串起始的" if (stringWarpFlag == 1) { isString = true; } //字符串结束的" else if (stringWarpFlag == 2) { stringWarpFlag = 0; isString = false; } } } //处理注释 if (!isString) { if (currentChar == '/' && (nextChar != 0 && nextChar == '/') && isComment == 0) { isComment = 1; //单行注释 } if (isComment == 1 && currentChar == '\n' && isComment > 0) { isComment = 0; //单行注释 } if (currentChar == '/' && (nextChar != 0 && nextChar == '*') && isComment == 0) { isComment = 2; //多行注释 if(currentChar == 65535){ return jsonResult; } continue; } if (isComment == 2 && currentChar == '/' && (prevChar != 0 && prevChar == '*') && isComment > 0) { isComment = 0; //多行注释 if(currentChar == 65535){ return jsonResult; } continue; } if (isComment != 0) { if(currentChar == 65535){ return jsonResult; } continue; } } //JSON数组字符串分组,以符号对称的方式取 [] if (!isString && !isFunction && currentChar == '[') { reader.skip(-1); //递归解析处理,取 value 对象 value = JSONDecode.parse(reader); if(currentChar == 65535){ return jsonResult; } continue; } else if (!isString && !isFunction && currentChar == ']') { //最后一个元素,追加一个,号来将其附加到结果集 if (itemString.length() != 0 || value != null) { currentChar = ','; reader.skip(-1); } else { return jsonResult; } } //JSON对象字符串分组,以符号对称的方式取 {} else if (!isString && !isFunction && currentChar == '{') { reader.skip(-1); //递归解析处理,取 value 对象 value = JSONDecode.parse(reader); continue; } else if (!isString && !isFunction && currentChar == '}') { //最后一个元素,追加一个,号来将其附加到结果集 if (itemString.length() != 0 || value != null) { currentChar = ','; reader.skip(-1); } else { return jsonResult; } } //如果为字符串则无条件瓶装 //如果不是字符串,则只拼装可见字符 if (isString || (!isString && !Character.isWhitespace(currentChar))) { itemString.append(currentChar); } if (jsonResult == null) { jsonResult = value; } //如果是函数 function 起始 if (!isString && itemString.toString().trim().startsWith("function")) { if (currentChar == '{') { functionWarpFlag++; } else if (currentChar == '}') { functionWarpFlag--; if (functionWarpFlag == 0) { isFunction = false; value = itemString.toString(); itemString = new StringBuilder(); } } else { isFunction = true; } } //JSON对象字符串分组,取 Key 对象,当前字符是:则取 Key if (!isString && !isFunction && (currentChar == ':' || currentChar == '=')) { keyString = itemString.substring(0, itemString.length() - 1).trim(); itemString = new StringBuilder(); } //JSON对象字符串分组,取 value 对象,当前字符是,则取 value if (!isString && !isFunction && currentChar == ',') { if (value == null) { value = itemString.substring(0, itemString.length() - 1).trim(); } itemString = new StringBuilder(); } //返回值处理 if (value != null && jsonResult != null) { //判断取值不是任何对象 if (value instanceof String) { String stringValue = TObject.cast(value); //判断是字符串去掉头尾的冒号 if (stringValue.startsWith("\"") && stringValue.endsWith("\"")) { value = stringValue.substring(1, stringValue.length() - 1); value = value.toString().replace("\\u000a", "\n").replace("\\u000d", "\r").replace("\\u0022", "\""); } //判断不包含.即为整形 else if (TString.isInteger(stringValue)) { Long longValue = Long.parseLong((String) value); if (longValue <= 2147483647 && longValue >= -2147483647) { value = Integer.parseInt((String) value); } else { value = longValue; } } //判断有一个.即为浮点数,转换成 Float else if (TString.isFloat(stringValue)) { value = new Float((String) value); } //判断是否是 boolean 类型 else if (TString.isBoolean(stringValue)) { value = Boolean.parseBoolean((String) value); } else if (value.equals("null")) { value = null; } } //这里 key 和 value 都准备完成了 //判断返回对象的类型,填充返回对象 if (jsonResult instanceof HashMap) { @SuppressWarnings("unchecked") HashMap<String, Object> result = (HashMap<String, Object>) jsonResult; if (keyString != null) { //容错,如果是双引号包裹的则去除首尾的双引号 if (keyString.startsWith("\"") && keyString.endsWith("\"")) { keyString = keyString.substring(1, keyString.length() - 1); } result.put(keyString, value); } } else if (jsonResult instanceof ArrayList && value != null) { @SuppressWarnings("unchecked") ArrayList<Object> result = (ArrayList<Object>) jsonResult; result.add(value); } else { jsonResult = value; } //处理完侯将 value 放空 keyString = null; value = null; } if (currentChar == 65535) { break; } } return jsonResult; }catch(Exception e){ try { int position = ((int) TReflect.getFieldValue(reader,"next") -1); String jsonStr = (String) TReflect.getFieldValue(reader,"str"); jsonStr = jsonStr.substring(0, position)+"^"+jsonStr.substring(position, position+10); Logger.error(jsonStr, e); } catch (ReflectiveOperationException ex) { Logger.error(ex); } return null; } } /** * 解析 JSON 字符串成为参数指定的类 * @param <T> 范型 * @param jsonStr JSON字符串 * @param clazz JSON 字符串将要转换的目标类 * @param ignoreCase 是否在字段匹配时忽略大小写 * @return JSON 转换后的 Java 对象 * @throws ReflectiveOperationException 反射异常 * @throws ParseException 解析异常 */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static <T>T fromJSON(String jsonStr,Class<T> clazz, boolean ignoreCase) throws ReflectiveOperationException, ParseException { if(jsonStr==null){ return null; } Object parseObject = parse(jsonStr); //{}包裹的对象处理 if(parseObject instanceof Map){ Map<String,Object> mapJSON = (Map<String, Object>) parseObject; return (T) TReflect.getObjectFromMap(clazz, mapJSON,ignoreCase); } //[]包裹的对象处理 else if(parseObject instanceof Collection){ return (T) TReflect.getObjectFromMap(clazz, TObject.asMap("value",parseObject),false); } //其他类型处理 else{ return null; } } /** * 解析 JSON 字符串成为参数指定的类,默认严格限制字段大小写 * @param <T> 范型 * @param jsonStr JSON字符串 * @param clazz JSON 字符串将要转换的目标类 * @param clazz 转换的目标 java 类 * @return JSON 转换后的 Java 对象 * @throws ReflectiveOperationException 反射异常 * @throws ParseException 解析异常 * @throws IOException IO 异常 */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static <T>T fromJSON(String jsonStr,Class<T> clazz) throws ParseException, ReflectiveOperationException, IOException { return fromJSON(jsonStr, clazz, false); } }