利用Java反射机制实现对象与json字符串互相转化

一、json字符串转Java对象

/**
     * 接地json字符串到实例对象
     *
     * @param clazz 和JSON对应的类的Class,必须拥有setXxx()函数,其中xxx为属性
     * @param json  被解析的JSON字符串
     * @return 返回传入的Object对象实例
     */
    public static  T parseJson2Object(Class clazz, String json) {
        JSONObject jsonObject = null;
        try {
            jsonObject = new JSONObject(json);
        } catch (Exception e) {
            e.printStackTrace();
            LogUtil.loge(TAG, "Exception:" + e.getMessage());
        }
        return parseJson2Object(clazz, jsonObject);
    }

    /**
     * 解析JSONObject对象到具体类,递归算法
     *
     * @param clazz      和JSON对应的类的Class,必须拥有setXxx()函数,其中xxx为属性
     * @param jsonObject 被解析的JSON对象
     * @return 返回传入的Object对象实例
     */
    private static  T parseJson2Object(Class clazz, JSONObject jsonObject) {
        T obj = null;
        try {
            //获取clazz的实例
            obj = clazz.newInstance();
            // 获取属性列表
            Field[] fields = clazz.getDeclaredFields();
            // 遍历每个属性,如果为基本类型和String则直接赋值,如果为List则得到每个Item添加后再赋值,如果是其它类则得到类的实例后赋值
            for (Field field : fields) {
                // 设置属性可操作
                field.setAccessible(true);
                // 获取字段类型
                Class typeClazz = field.getType();
                // 是否基础变量
                if (typeClazz.isPrimitive()) {
                    setProperty(obj, field, jsonObject.opt(field.getName()));
                } else {
                    // 得到类型实例
                    Object typeObj;
                    if (typeClazz.isInterface() && typeClazz.getSimpleName().contains("List")) {//Field如果声明为List接口,由于接口的Class对象不能newInstance(),此时需要转化为ArrayList
                        typeObj = ArrayList.class.newInstance();
                    } else {
                        typeObj = typeClazz.newInstance();
                    }
                    // 是否为List
                    if (typeObj instanceof List) {
                        // 得到类型的结构,如:java.util.ArrayList
                        Type type = field.getGenericType();
                        ParameterizedType pt = (ParameterizedType) type;
                        // 获得List元素类型
                        Class dataClass = (Class) pt.getActualTypeArguments()[0];
                        // 得到List的JSONArray数组
                        JSONArray jArray = jsonObject.getJSONArray(field.getName());
                        // 将每个元素的实例类加入到类型的实例中
                        for (int i = 0; i < jArray.length(); i++) {
                            //对于数组,递归调用解析子元素
                            ((List) typeObj).add(parseJson2Object(dataClass, jsonObject.getJSONArray(field.getName()).getJSONObject(i)));
                        }
                        setProperty(obj, field, typeObj);
                    } else if (typeObj instanceof String) {// 是否为String
                        setProperty(obj, field, jsonObject.opt(field.getName()));
                    } else {//是否为其它对象
                        //递归解析对象
                        setProperty(obj, field, parseJson2Object(typeClazz, jsonObject.getJSONObject(field.getName())));
                    }
                }
            }
        } catch (Exception e) {
            LogUtil.loge(TAG, "Exception:" + e.getMessage());
        }
        return obj;
    }

    /**
     * 给实例对象的成员变量赋值
     *
     * @param obj      实例对象
     * @param field    要被赋值的成员变量
     * @param valueObj 要被赋值的成员变量的值
     */
    private static void setProperty(Object obj, Field field, Object valueObj) {
        try {
            Class clazz = obj.getClass();
            //获取类的setXxx方法,xxx为属性
            Method method = clazz.getDeclaredMethod("set" + field.getName().substring(0, 1).toUpperCase(Locale.getDefault()) + field.getName().substring(1), field.getType());
            //设置set方法可访问
            method.setAccessible(true);
            //调用set方法为实例对象的成员变量赋值
            method.invoke(obj, valueObj);
        } catch (NoSuchMethodException e) {
            LogUtil.loge(TAG, "method [set" + field.getName().substring(0, 1).toUpperCase(Locale.getDefault()) + field.getName().substring(1) + "] not found");
        } catch (IllegalArgumentException e) {
            LogUtil.loge(TAG, "method [set" + field.getName().substring(0, 1).toUpperCase(Locale.getDefault()) + field.getName().substring(1) + "] illegal argument:" + valueObj + "," + e.getMessage());
        } catch (IllegalAccessException e) {
            LogUtil.loge(TAG, "IllegalAccessException:" + e.getMessage());
        } catch (InvocationTargetException e) {
            LogUtil.loge(TAG, "IllegalAccessException:" + e.getMessage());
        }
    } 
  

 

二、Java对象转json字符串

 /**
     * 可以解析自定义的对象、map、List、数组、基本数据类型、String
     *
     * @param value
     * @return
     */
    public static String object2JsonString(Object value) {
        if (value == null) return "null";
        if (value instanceof Number) return value.toString();
        if (value instanceof Boolean) return value.toString();
        if (value instanceof String)
            return "\"" + escape((String) value) + "\"";
        if (value instanceof Double) {
            if (((Double) value).isInfinite() || ((Double) value).isNaN()) return "null";
            else return value.toString();
        }
        if (value instanceof Float) {
            if (((Float) value).isInfinite() || ((Float) value).isNaN()) return "null";
            else return value.toString();
        }

        if (value instanceof Map) return map2Json((Map) value);
        if (value instanceof Collection) return coll2Json((Collection) value);
        if (value.getClass().isArray()) return array2Json(value);
        return customObject2Json(value);

    }

    private static String array2Json(Object array) {
        if (null == array) return "null";
        StringBuffer sb = new StringBuffer();
        sb.append('[');
        // 此处减1是为了下面的 逗号 追加
        int len = Array.getLength(array) - 1;
        if (len > -1) {
            int i;
            for (i = 0; i < len; i++) {
                sb.append(object2JsonString(Array.get(array, i))).append(", ");
            }
            sb.append(object2JsonString(Array.get(array, i)));

        }
        sb.append(']');
        return sb.toString();

    }

    private static String coll2Json(Collection coll) {
        if (null == coll) return "null";
        StringBuffer sb = new StringBuffer();
        sb.append('[');
        for (Iterator it = coll.iterator(); it.hasNext(); ) {
            sb.append(object2JsonString(it.next()));
            if (it.hasNext()) sb.append(", ");
        }
        sb.append(']');
        return sb.toString();

    }


    private static String customObject2Json(Object obj) {
        Class type = obj.getClass();
        Field[] fields = type.getDeclaredFields();
        Map map = new HashMap();
        for (Field f : fields) {
            if (Modifier.isStatic(f.getModifiers())) continue;
            String name = f.getName();
            f.setAccessible(true);
            Object value = null;
            try {
                value = f.get(obj);
            } catch (Exception e) {
                value = null;
            }
            map.put(name, value);

        }

        type = null;
        fields = null;

        return map2Json(map);

    }


    private static String map2Json(Map map) {
        if (null == map) return "null";
        StringBuffer sb = new StringBuffer();
        sb.append('{');
        for (Iterator it = map.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry entry = (Map.Entry) it.next();
            String key = (String) entry.getKey();
            if (null == key) continue;
            sb.append('\"');
            escape(key, sb);
            sb.append('\"').append(':').append(object2JsonString(entry.getValue()));
            if (it.hasNext()) sb.append(", ");
        }
        sb.append('}');
        return sb.toString();
    }


    /**
     * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F).
     *
     * @param s
     * @return
     */

    private static String escape(String s) {
        if (s == null) return null;
        StringBuffer sb = new StringBuffer();
        escape(s, sb);
        return sb.toString();

    }

    private static void escape(String s, StringBuffer sb) {
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            switch (ch) {
                case '"':
                    sb.append("\\\"");
                    break;
                case '\\':
                    sb.append("\\\\");
                    break;
                case '\b':
                    sb.append("\\b");
                    break;
                case '\f':
                    sb.append("\\f");
                    break;
                case '\n':
                    sb.append("\\n");
                    break;
                case '\r':
                    sb.append("\\r");
                    break;
                case '\t':
                    sb.append("\\t");
                    break;
                case '/':
                    sb.append("\\/");
                    break;
                default:
                    if ((ch >= '\u0000' && ch <= '\u001F') || (ch >= '\u007F' && ch <= '\u009F') || (ch >= '\u2000' && ch <= '\u20FF')) {
                        String ss = Integer.toHexString(ch);
                        sb.append("\\u");
                        for (int k = 0; k < 4 - ss.length(); k++) {
                            sb.append('0');
                        }
                        sb.append(ss.toUpperCase());
                    } else {
                        sb.append(ch);

                    }

            }

        }

    }

 

三、完成代码

public final class JsonParser {
    private static final String TAG = JsonParser.class.getSimpleName();

    /**
     * 接地json字符串到实例对象
     *
     * @param clazz 和JSON对应的类的Class,必须拥有setXxx()函数,其中xxx为属性
     * @param json  被解析的JSON字符串
     * @return 返回传入的Object对象实例
     */
    public static  T parseJson2Object(Class clazz, String json) {
        JSONObject jsonObject = null;
        try {
            jsonObject = new JSONObject(json);
        } catch (Exception e) {
            e.printStackTrace();
            LogUtil.loge(TAG, "Exception:" + e.getMessage());
        }
        return parseJson2Object(clazz, jsonObject);
    }

    /**
     * 解析JSONObject对象到具体类,递归算法
     *
     * @param clazz      和JSON对应的类的Class,必须拥有setXxx()函数,其中xxx为属性
     * @param jsonObject 被解析的JSON对象
     * @return 返回传入的Object对象实例
     */
    private static  T parseJson2Object(Class clazz, JSONObject jsonObject) {
        T obj = null;
        try {
            //获取clazz的实例
            obj = clazz.newInstance();
            // 获取属性列表
            Field[] fields = clazz.getDeclaredFields();
            // 遍历每个属性,如果为基本类型和String则直接赋值,如果为List则得到每个Item添加后再赋值,如果是其它类则得到类的实例后赋值
            for (Field field : fields) {
                // 设置属性可操作
                field.setAccessible(true);
                // 获取字段类型
                Class typeClazz = field.getType();
                // 是否基础变量
                if (typeClazz.isPrimitive()) {
                    setProperty(obj, field, jsonObject.opt(field.getName()));
                } else {
                    // 得到类型实例
                    Object typeObj;
                    if (typeClazz.isInterface() && typeClazz.getSimpleName().contains("List")) {//Field如果声明为List接口,由于接口的Class对象不能newInstance(),此时需要转化为ArrayList
                        typeObj = ArrayList.class.newInstance();
                    } else {
                        typeObj = typeClazz.newInstance();
                    }
                    // 是否为List
                    if (typeObj instanceof List) {
                        // 得到类型的结构,如:java.util.ArrayList
                        Type type = field.getGenericType();
                        ParameterizedType pt = (ParameterizedType) type;
                        // 获得List元素类型
                        Class dataClass = (Class) pt.getActualTypeArguments()[0];
                        // 得到List的JSONArray数组
                        JSONArray jArray = jsonObject.getJSONArray(field.getName());
                        // 将每个元素的实例类加入到类型的实例中
                        for (int i = 0; i < jArray.length(); i++) {
                            //对于数组,递归调用解析子元素
                            ((List) typeObj).add(parseJson2Object(dataClass, jsonObject.getJSONArray(field.getName()).getJSONObject(i)));
                        }
                        setProperty(obj, field, typeObj);
                    } else if (typeObj instanceof String) {// 是否为String
                        setProperty(obj, field, jsonObject.opt(field.getName()));
                    } else {//是否为其它对象
                        //递归解析对象
                        setProperty(obj, field, parseJson2Object(typeClazz, jsonObject.getJSONObject(field.getName())));
                    }
                }
            }
        } catch (Exception e) {
            LogUtil.loge(TAG, "Exception:" + e.getMessage());
        }
        return obj;
    }

    /**
     * 给实例对象的成员变量赋值
     *
     * @param obj      实例对象
     * @param field    要被赋值的成员变量
     * @param valueObj 要被赋值的成员变量的值
     */
    private static void setProperty(Object obj, Field field, Object valueObj) {
        try {
            Class clazz = obj.getClass();
            //获取类的setXxx方法,xxx为属性
            Method method = clazz.getDeclaredMethod("set" + field.getName().substring(0, 1).toUpperCase(Locale.getDefault()) + field.getName().substring(1), field.getType());
            //设置set方法可访问
            method.setAccessible(true);
            //调用set方法为实例对象的成员变量赋值
            method.invoke(obj, valueObj);
        } catch (NoSuchMethodException e) {
            LogUtil.loge(TAG, "method [set" + field.getName().substring(0, 1).toUpperCase(Locale.getDefault()) + field.getName().substring(1) + "] not found");
        } catch (IllegalArgumentException e) {
            LogUtil.loge(TAG, "method [set" + field.getName().substring(0, 1).toUpperCase(Locale.getDefault()) + field.getName().substring(1) + "] illegal argument:" + valueObj + "," + e.getMessage());
        } catch (IllegalAccessException e) {
            LogUtil.loge(TAG, "IllegalAccessException:" + e.getMessage());
        } catch (InvocationTargetException e) {
            LogUtil.loge(TAG, "IllegalAccessException:" + e.getMessage());
        }
    }

    /**
     * 可以解析自定义的对象、map、List、数组、基本数据类型、String
     *
     * @param value
     * @return
     */
    public static String object2JsonString(Object value) {
        if (value == null) return "null";
        if (value instanceof Number) return value.toString();
        if (value instanceof Boolean) return value.toString();
        if (value instanceof String)
            return "\"" + escape((String) value) + "\"";
        if (value instanceof Double) {
            if (((Double) value).isInfinite() || ((Double) value).isNaN()) return "null";
            else return value.toString();
        }
        if (value instanceof Float) {
            if (((Float) value).isInfinite() || ((Float) value).isNaN()) return "null";
            else return value.toString();
        }

        if (value instanceof Map) return map2Json((Map) value);
        if (value instanceof Collection) return coll2Json((Collection) value);
        if (value.getClass().isArray()) return array2Json(value);
        return customObject2Json(value);

    }

    private static String array2Json(Object array) {
        if (null == array) return "null";
        StringBuffer sb = new StringBuffer();
        sb.append('[');
        // 此处减1是为了下面的 逗号 追加
        int len = Array.getLength(array) - 1;
        if (len > -1) {
            int i;
            for (i = 0; i < len; i++) {
                sb.append(object2JsonString(Array.get(array, i))).append(", ");
            }
            sb.append(object2JsonString(Array.get(array, i)));

        }
        sb.append(']');
        return sb.toString();

    }

    private static String coll2Json(Collection coll) {
        if (null == coll) return "null";
        StringBuffer sb = new StringBuffer();
        sb.append('[');
        for (Iterator it = coll.iterator(); it.hasNext(); ) {
            sb.append(object2JsonString(it.next()));
            if (it.hasNext()) sb.append(", ");
        }
        sb.append(']');
        return sb.toString();

    }


    private static String customObject2Json(Object obj) {
        Class type = obj.getClass();
        Field[] fields = type.getDeclaredFields();
        Map map = new HashMap();
        for (Field f : fields) {
            if (Modifier.isStatic(f.getModifiers())) continue;
            String name = f.getName();
            f.setAccessible(true);
            Object value = null;
            try {
                value = f.get(obj);
            } catch (Exception e) {
                value = null;
            }
            map.put(name, value);

        }

        type = null;
        fields = null;

        return map2Json(map);

    }


    private static String map2Json(Map map) {
        if (null == map) return "null";
        StringBuffer sb = new StringBuffer();
        sb.append('{');
        for (Iterator it = map.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry entry = (Map.Entry) it.next();
            String key = (String) entry.getKey();
            if (null == key) continue;
            sb.append('\"');
            escape(key, sb);
            sb.append('\"').append(':').append(object2JsonString(entry.getValue()));
            if (it.hasNext()) sb.append(", ");
        }
        sb.append('}');
        return sb.toString();
    }


    /**
     * Escape quotes, \, /, \r, \n, \b, \f, \t and other control characters (U+0000 through U+001F).
     *
     * @param s
     * @return
     */

    private static String escape(String s) {
        if (s == null) return null;
        StringBuffer sb = new StringBuffer();
        escape(s, sb);
        return sb.toString();

    }

    private static void escape(String s, StringBuffer sb) {
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            switch (ch) {
                case '"':
                    sb.append("\\\"");
                    break;
                case '\\':
                    sb.append("\\\\");
                    break;
                case '\b':
                    sb.append("\\b");
                    break;
                case '\f':
                    sb.append("\\f");
                    break;
                case '\n':
                    sb.append("\\n");
                    break;
                case '\r':
                    sb.append("\\r");
                    break;
                case '\t':
                    sb.append("\\t");
                    break;
                case '/':
                    sb.append("\\/");
                    break;
                default:
                    if ((ch >= '\u0000' && ch <= '\u001F') || (ch >= '\u007F' && ch <= '\u009F') || (ch >= '\u2000' && ch <= '\u20FF')) {
                        String ss = Integer.toHexString(ch);
                        sb.append("\\u");
                        for (int k = 0; k < 4 - ss.length(); k++) {
                            sb.append('0');
                        }
                        sb.append(ss.toUpperCase());
                    } else {
                        sb.append(ch);

                    }

            }

        }

    }

}
 
  

 

 

你可能感兴趣的:(Android,Java)