package com.xiaoleilu.hutool.json; import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.nio.charset.Charset; import java.util.Collection; import java.util.Enumeration; import java.util.Map; import java.util.ResourceBundle; import com.xiaoleilu.hutool.io.IORuntimeException; import com.xiaoleilu.hutool.io.file.FileReader; import com.xiaoleilu.hutool.util.ArrayUtil; import com.xiaoleilu.hutool.util.ObjectUtil; import com.xiaoleilu.hutool.util.StrUtil; /** * JSON工具类 * * @author Looly * */ public final class JSONUtil { private JSONUtil() {} //-------------------------------------------------------------------- Pause start /** * 创建JSONObject * @return JSONObject */ public static JSONObject createObj(){ return new JSONObject(); } /** * 创建 JSONArray * @return JSONArray */ public static JSONArray createArray(){ return new JSONArray(); } /** * JSON字符串转JSONObject对象 * @param jsonStr JSON字符串 * @return JSONObject */ public static JSONObject parseObj(String jsonStr) { return new JSONObject(jsonStr); } /** * JSON字符串转JSONObject对象 * @param obj Bean对象或者Map * @return JSONObject */ public static JSONObject parseObj(Object obj) { return new JSONObject(obj); } /** * JSON字符串转JSONArray * @param jsonStr JSON字符串 * @return JSONArray */ public static JSONArray parseArray(String jsonStr) { return new JSONArray(jsonStr); } /** * 转换对象为JSON<br> * 支持的对象:<br> * String: 转换为相应的对象<br> * Array Collection:转换为JSONArray<br> * Bean对象:转为JSONObject * @param obj 对象 * @return JSON */ public static JSON parse(Object obj){ if(null == obj){ return null; } JSON json = null; if(obj instanceof JSON){ json = (JSON) obj; }else if(obj instanceof String){ String jsonStr = ((String)obj).trim(); if(jsonStr.startsWith("[")){ json = parseArray(jsonStr); }else{ json = parseObj(jsonStr); } }else if(obj instanceof Collection || obj.getClass().isArray()){//列表 json = new JSONArray(obj); }else{//对象 json = new JSONObject(obj); } return json; } /** * XML字符串转为JSONObject * @param xmlStr XML字符串 * @return JSONObject */ public static JSONObject parseFromXml(String xmlStr){ return XML.toJSONObject(xmlStr); } /** * Map转化为JSONObject * @param map {@link Map} * @return JSONObject */ public static JSONObject parseFromMap(Map<?, ?> map){ return new JSONObject(map); } /** * ResourceBundle转化为JSONObject * @param bundle ResourceBundle文件 * @return JSONObject */ public static JSONObject parseFromResourceBundle(ResourceBundle bundle){ JSONObject jsonObject = new JSONObject(); Enumeration<String> keys = bundle.getKeys(); while (keys.hasMoreElements()) { String key = keys.nextElement(); if (key != null) { InternalJSONUtil.propertyPut(jsonObject, key, bundle.getString(key)); } } return jsonObject; } //-------------------------------------------------------------------- Pause end //-------------------------------------------------------------------- Read start /** * 读取JSON * * @param file JSON文件 * @param charset 编码 * @return JSON(包括JSONObject和JSONArray) * @throws IORuntimeException */ public static JSON readJSON(File file, Charset charset) throws IORuntimeException { return parse(FileReader.create(file, charset).readString()); } /** * 读取JSONObject * * @param file JSON文件 * @param charset 编码 * @return JSONObject * @throws IORuntimeException */ public static JSONObject readJSONObject(File file, Charset charset) throws IORuntimeException { return parseObj(FileReader.create(file, charset).readString()); } /** * 读取JSONArray * * @param file JSON文件 * @param charset 编码 * @return JSONArray * @throws IORuntimeException */ public static JSONArray readJSONArray(File file, Charset charset) throws IORuntimeException { return parseArray(FileReader.create(file, charset).readString()); } //-------------------------------------------------------------------- Read end //-------------------------------------------------------------------- toString start /** * 转为JSON字符串 * @param json JSON * @param indentFactor 每一级别的缩进 * @return JSON字符串 */ public static String toJsonStr(JSON json, int indentFactor) { return json.toJSONString(indentFactor); } /** * 转为JSON字符串 * @param json JSON * @return JSON字符串 */ public static String toJsonStr(JSON json) { return json.toJSONString(0); } /** * 转为JSON字符串 * @param json JSON * @return JSON字符串 */ public static String toJsonPrettyStr(JSON json) { return json.toJSONString(4); } /** * 转换为JSON字符串 * @param obj 被转为JSON的对象 * @return JSON字符串 */ public static String toJsonStr(Object obj){ return toJsonStr(parse(obj)); } /** * 转换为格式化后的JSON字符串 * @param obj Bean对象 * @return JSON字符串 */ public static String toJsonPrettyStr(Object obj){ return toJsonPrettyStr(parse(obj)); } /** * 转换为XML字符串 * @param json JSON * @return XML字符串 */ public static String toXmlStr(JSON json){ return XML.toString(json); } //-------------------------------------------------------------------- toString end //-------------------------------------------------------------------- toBean start /** * 转为实体类对象,转换异常将被抛出 * @param json JSONObject * @param beanClass 实体类对象 * @return 实体类对象 */ public static <T> T toBean(JSONObject json, Class<T> beanClass) { return toBean(json, beanClass, false); } /** * 转为实体类对象 * @param json JSONObject * @param beanClass 实体类对象 * @return 实体类对象 */ public static <T> T toBean(JSONObject json, Class<T> beanClass, boolean ignoreError) { return null == json ? null : json.toBean(beanClass, ignoreError); } //-------------------------------------------------------------------- toBean end /** * 对所有双引号做转义处理(使用双反斜杠做转义)<br> * 为了能在HTML中较好的显示,会将</转义为<\/<br> * JSON字符串中不能包含控制字符和未经转义的引号和反斜杠 * * @param string A String * @return A String correctly formatted for insertion in a JSON text. */ public static String quote(String string) { StringWriter sw = new StringWriter(); synchronized (sw.getBuffer()) { try { return quote(string, sw).toString(); } catch (IOException ignored) { // will never happen - we are writing to a string writer return ""; } } } /** * 对所有双引号做转义处理(使用双反斜杠做转义)<br> * 为了能在HTML中较好的显示,会将</转义为<\/<br> * JSON字符串中不能包含控制字符和未经转义的引号和反斜杠 * @param string A String * @param writer Writer * @return A String correctly formatted for insertion in a JSON text. * @throws IOException */ public static Writer quote(String string, Writer writer) throws IOException { if (StrUtil.isEmpty(string)) { writer.write("\"\""); return writer; } char b; //back char char c = 0; //current char String hhhh; int i; int len = string.length(); writer.write('"'); for (i = 0; i < len; i++) { b = c; c = string.charAt(i); switch (c) { case '\\': case '"': writer.write('\\'); writer.write(c); break; case '/': if (b == '<') { writer.write('\\'); } writer.write(c); break; case '\b': writer.write("\\b"); break; case '\t': writer.write("\\t"); break; case '\n': writer.write("\\n"); break; case '\f': writer.write("\\f"); break; case '\r': writer.write("\\r"); break; default: if (c < ' ' || (c >= '\u0080' && c < '\u00a0') || (c >= '\u2000' && c < '\u2100')) { writer.write("\\u"); hhhh = Integer.toHexString(c); writer.write("0000", 0, 4 - hhhh.length()); writer.write(hhhh); } else { writer.write(c); } } } writer.write('"'); return writer; } /** * 在需要的时候包装对象<br> * 包装包括: * <ul> * <li><code>null</code> -> <code>JSONNull.NULL</code></li> * <li>array or collection -> JSONArray</li> * <li>map -> JSONObject</li> * <li>standard property (Double, String, et al) -> 原对象</li> * <li>来自于java包 -> 字符串</li> * <li>其它 -> 尝试包装为JSONObject,否则返回<code>null</code></li> * </ul> * * @param object The object to wrap * @return The wrapped value */ public static Object wrap(Object object) { try { if (object == null) { return JSONNull.NULL; } if (object instanceof JSON || JSONNull.NULL.equals(object) || object instanceof JSONString || object instanceof CharSequence || object instanceof Number || ObjectUtil.isBasicType(object)) { return object; } if (object instanceof Collection) { Collection<?> coll = (Collection<?>) object; return new JSONArray(coll); } if (ArrayUtil.isArray(object)) { return new JSONArray(object); } if (object instanceof Map) { Map<?, ?> map = (Map<?, ?>) object; return new JSONObject(map); } Package objectPackage = object.getClass().getPackage(); String objectPackageName = objectPackage != null ? objectPackage.getName() : ""; if (objectPackageName.startsWith("java.") || objectPackageName.startsWith("javax.") || object.getClass().getClassLoader() == null) { return object.toString(); } return new JSONObject(object); } catch (Exception exception) { return null; } } }