/*Copyright (C) 2020 Tencent. All rights reserved. This source code is licensed under the Apache License Version 2.0.*/ package apijson; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /**JSON工具类 防止解析时异常 * @author Lemon */ public class JSON { static final String TAG = "JSON"; public static JSONParser, ? extends List> DEFAULT_JSON_PARSER; static { //DEFAULT_JSON_PARSER = new JSONParser, List>() { // // @Override // public LinkedHashMap createJSONObject() { // throw new UnsupportedOperationException(); // } // // @Override // public List createJSONArray() { // throw new UnsupportedOperationException(); // } // // @Override // public String toJSONString(Object obj, boolean format) { // throw new UnsupportedOperationException(); // } // // @Override // public Object parse(Object json) { // throw new UnsupportedOperationException(); // } // // @Override // public LinkedHashMap parseObject(Object json) { // throw new UnsupportedOperationException(); // } // // @Override // public T parseObject(Object json, Class clazz) { // throw new UnsupportedOperationException(); // } // // @Override // public List parseArray(Object json) { // throw new UnsupportedOperationException(); // } // // @Override // public List parseArray(Object json, Class clazz) { // throw new UnsupportedOperationException(); // } // //}; } // public static JSONCreator, ? extends List> DEFAULT_JSON_CREATOR = DEFAULT_JSON_PARSER; // public static > M newObj() { // return createJSONObject(); // } // public static > M newObj(String key, Object value) { // return createJSONObject(key, value); // } // public static > M newObj(Map map) { // return createJSONObject(map); // } public static > M createJSONObject() { return (M) DEFAULT_JSON_PARSER.createJSONObject(); } public static > M createJSONObject(String key, Object value) { return (M) DEFAULT_JSON_PARSER.createJSONObject(key, value); } public static > M createJSONObject(Map map) { return (M) DEFAULT_JSON_PARSER.createJSONObject(map); } //public static > L newArr() { // return createJSONArray(); //} //public static > L newArr(Object obj) { // return createJSONArray(obj); //} //public static > L newArr(List list) { // return createJSONArray(list); //} public static > L createJSONArray() { return (L) DEFAULT_JSON_PARSER.createJSONArray(); } public static > L createJSONArray(Object obj) { return (L) DEFAULT_JSON_PARSER.createJSONArray(obj); } public static > L createJSONArray(Collection list) { return (L) DEFAULT_JSON_PARSER.createJSONArray(list); } public static Object parse(Object json) { return DEFAULT_JSON_PARSER.parse(json); } public static > M parseObject(Object json) { String s = toJSONString(json); if (StringUtil.isEmpty(s, true)) { return null; } return (M) DEFAULT_JSON_PARSER.parseObject(s); } public static T parseObject(Object json, Class clazz) { String s = toJSONString(json); if (StringUtil.isEmpty(s, true)) { return null; } return DEFAULT_JSON_PARSER.parseObject(s, clazz); } /** * @param json * @return */ public static > L parseArray(Object json) { String s = toJSONString(json); if (StringUtil.isEmpty(s, true)) { return null; } try { L arr = (L) DEFAULT_JSON_PARSER.parseArray(s); return arr; } catch (Exception e) { Log.i(TAG, "parseArray catch \n" + e.getMessage()); } return null; } public static List parseArray(Object json, Class clazz) { String s = toJSONString(json); if (StringUtil.isEmpty(s, true)) { return null; } try { return DEFAULT_JSON_PARSER.parseArray(s, clazz); } catch (Exception e) { Log.i(TAG, "parseArray catch \n" + e.getMessage()); } return null; } /** * @param obj * @return */ public static String format(Object obj) { return toJSONString(obj, true); } /** * @param obj * @return */ public static String toJSONString(Object obj) { return toJSONString(obj, false); } public static String toJSONString(Object obj, boolean format) { if (obj == null) { return null; } if (obj instanceof String) { return (String) obj; } //if (obj instanceof Map) { // // Simple JSON object format // StringBuilder sb = new StringBuilder("{"); // @SuppressWarnings("unchecked") // Map map = (Map) obj; // boolean first = true; // for (Map.Entry entry : map.entrySet()) { // if (! first) { // sb.append(","); // } // // first = false; // sb.append("\"").append(entry.getKey()).append("\":"); // Object value = entry.getValue(); // if (value instanceof String) { // sb.append("\"").append(value).append("\""); // } else { // sb.append(toJSONString(value)); // } // } // sb.append("}"); // return sb.toString(); //} // //if (obj instanceof List) { // StringBuilder sb = new StringBuilder("["); // @SuppressWarnings("unchecked") // List list = (List) obj; // boolean first = true; // for (Object item : list) { // if (! first) { // sb.append(","); // } // first = false; // if (item instanceof String) { // sb.append("\"").append(item).append("\""); // } else { // sb.append(toJSONString(item)); // } // } // sb.append("]"); // return sb.toString(); //} return DEFAULT_JSON_PARSER.toJSONString(obj, format); } /**判断是否为JSONObject或JSONArray的isXxx方法名 * @param key * @return */ public static boolean isJSONType(String key) { return key != null && key.startsWith("is") && key.length() > 2 && key.contains("JSON"); } public static boolean isBoolOrNumOrStr(Object obj) { return obj instanceof Boolean || obj instanceof Number || obj instanceof String; } /** * Get a value from a Map and convert to the specified type * @param map Source map * @param key The key * @param Target type * @return The converted value */ @SuppressWarnings("unchecked") public static T get(Map map, String key) { return map == null || key == null ? null : (T) map.get(key); } /** * Get a value from a Map and convert to the specified type * @param map Source map * @param key The key * @param Target type * @return The converted value */ @SuppressWarnings("unchecked") public static > M getJSONObject(Map map, String key) { Object obj = get(map, key); return (M) obj; } /** * Get a value from a Map and convert to the specified type * @param map Source map * @param key The key * @param Target type * @return The converted value */ @SuppressWarnings("unchecked") public static > L getJSONArray(Map map, String key) { Object obj = get(map, key); return (L) obj; } /** * Get a value from a Map and convert to the specified type * @param list Source map * @param index The key * @param Target type * @return The converted value */ @SuppressWarnings("unchecked") public static T get(List list, int index) { return list == null || index < 0 || index >= list.size() ? null : (T) list.get(index); } @SuppressWarnings("unchecked") public static > M getJSONObject(List list, int index) { Object obj = get(list, index); return (M) obj; } @SuppressWarnings("unchecked") public static > L getJSONArray(List list, int index) { Object obj = get(list, index); return (L) obj; } // /** // * Get a value from a Map and convert to the specified type // * @param map Source map // * @param key The key // * @param Target type // * @return The converted value // */ // @SuppressWarnings("unchecked") // public static T get(List list, int index) { // return list == null || index < 0 || index >= list.size() ? null : list.get(index); // } /** * Get a Map value from a Map * @param map Source map * @param key The key * @return The Map value * @throws IllegalArgumentException If value is not a Map and cannot be converted */ @SuppressWarnings("unchecked") public static Map getMap(Map map, String key) throws IllegalArgumentException { Object value = map == null || key == null ? null : map.get(key); if (value == null) { return null; } if (value instanceof Map) { return (Map) value; } throw new IllegalArgumentException("Value for key '" + key + "' is not a Map: " + value.getClass().getName()); } /** * Get a List value from a Map * @param map Source map * @param key The key * @return The List value * @throws IllegalArgumentException If value is not a List and cannot be converted */ @SuppressWarnings("unchecked") public static List getList(Map map, String key) throws IllegalArgumentException { Object value = map == null || key == null ? null : map.get(key); if (value == null) { return null; } if (value instanceof List) { return (List) value; } throw new IllegalArgumentException("Value for key '" + key + "' is not a List: " + value.getClass().getName()); } /** * Get an int value from a Map * @param map Source map * @param key The key * @return The int value * @throws IllegalArgumentException If value cannot be converted to int */ public static Integer getInteger(Map map, String key) throws IllegalArgumentException { Object value = map == null || key == null ? null : map.get(key); if (value == null) { return null; } if (value instanceof Number) { return ((Number) value).intValue(); } if (value instanceof String) { try { return Integer.parseInt((String) value); } catch (NumberFormatException e) { throw new IllegalArgumentException("Cannot convert String value '" + value + "' to int: " + e.getMessage()); } } throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to int"); } /** * Get an int value from a Map * @param map Source map * @param key The key * @return The int value * @throws IllegalArgumentException If value cannot be converted to int */ public static int getIntValue(Map map, String key) throws IllegalArgumentException { Object value = map == null || key == null ? null : map.get(key); if (value == null) { return 0; } if (value instanceof Number) { return ((Number) value).intValue(); } if (value instanceof String) { try { return Integer.parseInt((String) value); } catch (NumberFormatException e) { throw new IllegalArgumentException("Cannot convert String value '" + value + "' to int: " + e.getMessage()); } } throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to int"); } /** * Get an int value from a Map * @param map Source map * @param key The key * @return The int value * @throws IllegalArgumentException If value cannot be converted to int */ public static Long getLong(Map map, String key) throws IllegalArgumentException { Object value = map == null || key == null ? null : map.get(key); if (value == null) { return null; } if (value instanceof Number) { return ((Number) value).longValue(); } if (value instanceof String) { try { return Long.parseLong((String) value); } catch (NumberFormatException e) { throw new IllegalArgumentException("Cannot convert String value '" + value + "' to int: " + e.getMessage()); } } throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to int"); } /** * Get a long value from a Map * @param map Source map * @param key The key * @return The long value * @throws IllegalArgumentException If value cannot be converted to long */ public static long getLongValue(Map map, String key) throws IllegalArgumentException { Object value = map == null || key == null ? null : map.get(key); if (value == null) { return 0; } if (value instanceof Number) { return ((Number) value).longValue(); } if (value instanceof String) { try { return Long.parseLong((String) value); } catch (NumberFormatException e) { throw new IllegalArgumentException("Cannot convert String value '" + value + "' to long: " + e.getMessage()); } } throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to long"); } /** * Get a double value from a Map * @param map Source map * @param key The key * @return The double value * @throws IllegalArgumentException If value cannot be converted to double */ public static Float getFloat(Map map, String key) throws IllegalArgumentException { Object value = map == null || key == null ? null : map.get(key); if (value == null) { return null; } if (value instanceof Number) { return ((Number) value).floatValue(); } if (value instanceof String) { try { return Float.parseFloat((String) value); } catch (NumberFormatException e) { throw new IllegalArgumentException("Cannot convert String value '" + value + "' to double: " + e.getMessage()); } } throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to double"); } /** * Get a double value from a Map * @param map Source map * @param key The key * @return The double value * @throws IllegalArgumentException If value cannot be converted to double */ public static float getFloatValue(Map map, String key) throws IllegalArgumentException { Object value = map == null || key == null ? null : map.get(key); if (value == null) { return 0; } if (value instanceof Number) { return ((Number) value).floatValue(); } if (value instanceof String) { try { return Float.parseFloat((String) value); } catch (NumberFormatException e) { throw new IllegalArgumentException("Cannot convert String value '" + value + "' to double: " + e.getMessage()); } } throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to double"); } /** * Get a double value from a Map * @param map Source map * @param key The key * @return The double value * @throws IllegalArgumentException If value cannot be converted to double */ public static Double getDouble(Map map, String key) throws IllegalArgumentException { Object value = map == null || key == null ? null : map.get(key); if (value == null) { return null; } if (value instanceof Number) { return ((Number) value).doubleValue(); } if (value instanceof String) { try { return Double.parseDouble((String) value); } catch (NumberFormatException e) { throw new IllegalArgumentException("Cannot convert String value '" + value + "' to double: " + e.getMessage()); } } throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to double"); } /** * Get a double value from a Map * @param map Source map * @param key The key * @return The double value * @throws IllegalArgumentException If value cannot be converted to double */ public static double getDoubleValue(Map map, String key) throws IllegalArgumentException { Object value = map == null || key == null ? null : map.get(key); if (value == null) { return 0; } if (value instanceof Number) { return ((Number) value).doubleValue(); } if (value instanceof String) { try { return Double.parseDouble((String) value); } catch (NumberFormatException e) { throw new IllegalArgumentException("Cannot convert String value '" + value + "' to double: " + e.getMessage()); } } throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to double"); } /** * Get a boolean value from a Map * @param map Source map * @param key The key * @return The boolean value * @throws IllegalArgumentException If value cannot be converted to boolean */ public static Boolean getBoolean(Map map, String key) throws IllegalArgumentException { Object value = map == null || key == null ? null : map.get(key); if (value == null) { return null; } if (value instanceof Boolean) { return (Boolean) value; } if (value instanceof String) { String str = ((String) value).toLowerCase(); if (str.equals("true") || str.equals("false")) { return Boolean.parseBoolean(str); } throw new IllegalArgumentException("Cannot convert String value '" + value + "' to boolean"); } if (value instanceof Number) { int intValue = ((Number) value).intValue(); if (intValue == 0 || intValue == 1) { return intValue != 0; } throw new IllegalArgumentException("Cannot convert Number value '" + value + "' to boolean. Only 0 and 1 are supported."); } throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to boolean"); } /** * Get a boolean value from a Map * @param map Source map * @param key The key * @return The boolean value * @throws IllegalArgumentException If value cannot be converted to boolean */ public static boolean getBooleanValue(Map map, String key) throws IllegalArgumentException { Object value = map == null || key == null ? null : map.get(key); if (value == null) { return false; } if (value instanceof Boolean) { return (Boolean) value; } if (value instanceof String) { String str = ((String) value).toLowerCase(); if (str.equals("true") || str.equals("false")) { return Boolean.parseBoolean(str); } throw new IllegalArgumentException("Cannot convert String value '" + value + "' to boolean"); } if (value instanceof Number) { int intValue = ((Number) value).intValue(); if (intValue == 0 || intValue == 1) { return intValue != 0; } throw new IllegalArgumentException("Cannot convert Number value '" + value + "' to boolean. Only 0 and 1 are supported."); } throw new IllegalArgumentException("Cannot convert value of type " + value.getClass().getName() + " to boolean"); } /** * Get a string value from a Map * @param map Source map * @param key The key * @return The string value */ public static String getString(Map map, String key) { Object value = map == null || key == null ? null : map.get(key); if (value == null) { return null; } return value.toString(); } public static Object getFromObjOrArr(Object parent, String k) { if (parent instanceof Map) { return ((Map) parent).get(k); } if (parent instanceof List) { int j = Integer.valueOf(k); return ((List) parent).get(j); } return null; } }