Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.voovan.tools.json.JSONDecode Maven / Gradle / Ivy
package org.voovan.tools.json;
import org.voovan.Global;
import org.voovan.tools.TEnv;
import org.voovan.tools.TObject;
import org.voovan.tools.TString;
import org.voovan.tools.collection.IntKeyMap;
import org.voovan.tools.hashwheeltimer.HashWheelTask;
import org.voovan.tools.log.Logger;
import org.voovan.tools.reflect.TReflect;
import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Type;
import java.math.BigDecimal;
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 {
public final static boolean JSON_CACHE_ENABLE = TEnv.getSystemProperty("JsonCacheEnable", false);
public final static IntKeyMap JSON_DECODE_CACHE = new IntKeyMap(1024);
static {
if(JSON_CACHE_ENABLE) {
Global.getHashWheelTimer().addTask(new HashWheelTask() {
@Override
public void run() {
JSON_DECODE_CACHE.clear();
}
}, 1);
}
}
private static int E_OBJECT = 1;
private static int E_ARRAY = -1;
public static Object parse(String jsonStr) {
Object value;
int jsonHash = jsonStr.hashCode();
if(JSON_CACHE_ENABLE) {
value = JSON_DECODE_CACHE.get(jsonHash);
if (value != null) {
return value;
}
}
value = parse(new StringReader(jsonStr.trim() + "\0"));
if(JSON_CACHE_ENABLE) {
JSON_DECODE_CACHE.put(jsonHash, value);
}
return value;
}
/**
* 解析 JSON 字符串
* 如果是{}包裹的对象解析成 HashMap,如果是[]包裹的对象解析成 ArrayList
* @param reader 待解析的 JSON 字符串
* @return 解析后的对象
*/
private 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 == Global.CHAR_LC_BRACES) {
type = E_OBJECT;
}
if (flag == Global.CHAR_LS_BRACES) {
type = E_ARRAY;
}
}
//对象类型构造返回的对象
if (E_OBJECT == type) {
jsonResult = (Map) new HashMap(1024);
isFirstChar = false;
} else if (E_ARRAY == type) {
jsonResult = (List) new ArrayList(1024);
isFirstChar = false;
} else {
reader.skip(-1);
}
String keyString = null;
Object value = null;
char 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 == Global.CHAR_QUOTE || currentChar == Global.CHAR_S_QUOTE) {
//i小于1的不是转意字符,判断为字符串(因为转意字符要2个字节),大于2的要判断是否\\"的转义字符
if (isComment==0 && nextChar != 0 && prevChar != Global.CHAR_SLASH) {
//字符串起始的"
if (stringWarpFlag == Global.CHAR_EOF) {
stringWarpFlag = currentChar;
isString = true;
}
//字符串结束的"
else if (stringWarpFlag != Global.CHAR_EOF && currentChar == stringWarpFlag) {
stringWarpFlag = Global.CHAR_EOF;
isString = false;
}
}
}
//处理注释
if (!isString) {
if(currentChar == Global.CHAR_BACKSLASH && isComment == 0) {
if (nextChar != 0 && nextChar == Global.CHAR_BACKSLASH){
isComment = 1; //单行注释
}
if (nextChar != 0 && nextChar == Global.CHAR_STAR) {
isComment = 2; //多行注释
if (currentChar == 65535) {
return jsonResult;
}
continue;
}
}
if(isComment > 0) {
if (isComment == 1 && currentChar == Global.CHAR_LF ) {
isComment = 0; //单行注释结束
}
if (isComment == 2 && currentChar == Global.CHAR_BACKSLASH && (prevChar != 0 && prevChar == Global.CHAR_STAR)) {
isComment = 0; //多行注释结束
if (currentChar == 65535) {
return jsonResult;
}
continue;
}
if (currentChar == 65535) {
return jsonResult;
}
continue;
}
}
//处理对象的包裹
if(!isString && !isFunction) {
//JSON数组字符串分组,以符号对称的方式取 []
if (currentChar == Global.CHAR_LS_BRACES) {
reader.skip(-1);
//递归解析处理,取 value 对象
value = JSONDecode.parse(reader);
continue;
} else if (currentChar == Global.CHAR_RS_BRACES) {
//最后一个元素,追加一个,号来将其附加到结果集
if (itemString.length() != 0 || value != null) {
currentChar = Global.CHAR_COMMA;
reader.skip(-1);
} else {
return jsonResult;
}
}
//JSON对象字符串分组,以符号对称的方式取 {}
else if (currentChar == Global.CHAR_LC_BRACES) {
reader.skip(-1);
//递归解析处理,取 value 对象
value = JSONDecode.parse(reader);
continue;
} else if (currentChar == Global.CHAR_RC_BRACES) {
//最后一个元素,追加一个,号来将其附加到结果集
if (itemString.length() != 0 || value != null) {
currentChar = Global.CHAR_COMMA;
reader.skip(-1);
} else {
return jsonResult;
}
}
}
//如果为字符串则无条件拼装
//如果不是字符串,则只拼装可见字符
if (isString || (!isString && !Character.isWhitespace(currentChar))) {
itemString.append(currentChar);
}
if (jsonResult == null) {
jsonResult = value;
}
//处理数据
if(!isString) {
//如果是函数 function 起始
if (!isString && itemString.toString().trim().startsWith("function")) {
if (currentChar == Global.CHAR_LC_BRACES) {
functionWarpFlag++;
} else if (currentChar == Global.CHAR_RC_BRACES) {
functionWarpFlag--;
if (functionWarpFlag == 0) {
isFunction = false;
value = itemString.toString();
itemString = new StringBuilder();
}
} else {
isFunction = true;
}
}
if(!isFunction) {
//JSON对象字符串分组,取 Key 对象,当前字符是:则取 Key
if (currentChar == Global.CHAR_COLON || currentChar == Global.CHAR_EQUAL) {
keyString = itemString.substring(0, itemString.length() - 1).trim();
itemString = new StringBuilder();
}
//JSON对象字符串分组,取 value 对象,当前字符是,则取 value
if (currentChar == Global.CHAR_COMMA) {
if (value == null) {
value = itemString.substring(0, itemString.length() - 1).trim();
}
itemString = new StringBuilder();
}
//JSON对象字符串分组,取 value 对象,当前字符是换行, 则取 value
if (currentChar == '\n') {
itemString.trimToSize();
if (value == null && itemString.length() > 0) {
value = itemString.toString().trim();
}
itemString = new StringBuilder();
}
}
}
//返回值处理
if (value != null && jsonResult != null) {
//判断取值不是任何对象
if (value instanceof String) {
String stringValue = (String)value;
//判断是字符串去掉头尾的包裹符号
if (stringValue.length() >= 2 && stringValue.charAt(0) == Global.CHAR_QUOTE && stringValue.charAt(stringValue.length()-1) == Global.CHAR_QUOTE) {
value = stringValue.substring(1, stringValue.length() - 1);
if(JSON.isConvertEscapeChar()) {
value = TString.unConvertEscapeChar(value.toString());
}
}
//判断是字符串去掉头尾的包裹符号
else if (stringValue.length() >= 2 && stringValue.charAt(0) == Global.CHAR_S_QUOTE && stringValue.charAt(stringValue.length()-1) == Global.CHAR_S_QUOTE) {
value = stringValue.substring(1, stringValue.length() - 1);
if(JSON.isConvertEscapeChar()) {
value = TString.unConvertEscapeChar(value.toString());
}
}
//判断科学技术转换成 BigDecimal
else if (stringValue.indexOf(".")>0 && stringValue.indexOf("E")>0) {
value = new BigDecimal(stringValue);
}
//判断不包含.即为整形
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.isDecimal(stringValue)) {
Object resultValue = new Float((String) value);
if(resultValue.toString().equals(value)){
value = resultValue;
} else {
resultValue = new Double((String) value);
if (resultValue.toString().equals(value)) {
value = resultValue;
} else {
resultValue = new BigDecimal((String) value);
}
}
value = resultValue;
}
//判断是否是 boolean 类型
else if (TString.isBoolean(stringValue)) {
value = Boolean.parseBoolean((String) value);
} else if (value.equals("null")) {
value = null;
} else if(value.equals("")){
value = null;
}
}
//这里 key 和 value 都准备完成了
//判断返回对象的类型,填充返回对象
if (jsonResult instanceof HashMap) {
@SuppressWarnings("unchecked")
HashMap result = (HashMap) jsonResult;
if (keyString != null) {
//判断是字符串去掉头尾的包裹符号
if (keyString.length() >= 2 && keyString.charAt(0) == Global.CHAR_QUOTE && keyString.charAt(keyString.length()-1) == Global.CHAR_QUOTE) {
keyString = keyString.substring(1, keyString.length() - 1);
}
//判断是字符串去掉头尾的包裹符号
if (keyString.length() >= 2 && keyString.charAt(0) == Global.CHAR_S_QUOTE && keyString.charAt(keyString.length()-1) == Global.CHAR_S_QUOTE) {
keyString = keyString.substring(1, keyString.length() - 1);
}
result.put(keyString, value);
}
} else if (jsonResult instanceof ArrayList && value != null) {
@SuppressWarnings("unchecked")
ArrayList result = (ArrayList) jsonResult;
result.add(value);
} else if(jsonResult==null){
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 范型
* @param jsonStr JSON字符串
* @param type JSON 字符串将要转换的目标类
* @param ignoreCase 是否在字段匹配时忽略大小写
* @return JSON 转换后的 Java 对象
* @throws ReflectiveOperationException 反射异常
* @throws ParseException 解析异常
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static T fromJSON(String jsonStr, Type type, boolean ignoreCase) throws ReflectiveOperationException, ParseException {
if(jsonStr==null){
return null;
}
Object parseObject = parse(jsonStr);
if(parseObject == null){
parseObject = jsonStr;
}
if(type == Map.class && parseObject instanceof Map){
return (T)parseObject;
}
//{}包裹的对象处理
else if(parseObject instanceof Map){
Map mapJSON = (Map) parseObject;
return (T) TReflect.getObjectFromMap(type, mapJSON,ignoreCase);
}
//[]包裹的对象处理
else if(parseObject instanceof Collection){
return (T) TReflect.getObjectFromMap(type, TObject.asMap(TReflect.SINGLE_VALUE_KEY, parseObject),false);
}
//如果传入的是标准类型则尝试用TString.toObject进行转换
else if(parseObject instanceof String || parseObject.getClass().isPrimitive()){
return TString.toObject(parseObject.toString(), type);
}
//其他类型处理
else{
return null;
}
}
/**
* 解析 JSON 字符串成为参数指定的类,默认严格限制字段大小写
* @param 范型
* @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 fromJSON(String jsonStr,Class clazz) throws ParseException, ReflectiveOperationException, IOException {
return fromJSON(jsonStr, clazz, false);
}
}