• 自定义Json解析工具


    此博客为博主原创文章,转载请标明出处,维权必究:https://www.cnblogs.com/tangZH/p/10689536.html

    更多精彩文章:http://77blogs.com/?p=301

    fastjson是很好用的json解析工具,只可惜项目中要求apk体积尽量小,所以并不打算引入fastJson,只好自己写一个,遗憾的是写出的这个并没法解析所有的json数据,不过还是很值得学习的,且听我一一道来。

    主要实现两个功能:

    1、将jsonArray解析为List

    2、将json数据转化为class

    当然,class里面的成员变量的名称需要与json里面的key一样。

    思路:

    1、通过反射获取class类里面的成员变量名称以及类型

    2、通过成员变量的名称与类型去json数据中获取该key对应的value

    2、将value通过反射赋值给class对象。

    具体且看:

    1、定义一个实体类保存class里面的反射获取到的每个成员变量对应字段,名称,类型

    static class ValueHelper {
            String name;
            String type;
            Field field;
        }

    2、将json数据转换为实体类

     public static <T> T parseJson2Obj(String data, Class<T> tClass) {
            if (TextUtils.isEmpty(data))
                return null;
            try {
                List<ValueHelper> listKey;
                //获得自己的所有属性
                Field[] fields = tClass.getFields();
                if (null == fields)
                    return null;
    
                listKey = new ArrayList<>();
    
                for (Field field : fields) {
                    ValueHelper helper = new ValueHelper();
                    helper.name = field.getName();
                    helper.type = field.getGenericType().toString();
                    helper.field = field;
                    listKey.add(helper);
                }
    //将所有的属性保存在keyList集合中
    //实例化给实体类,以便对其进行反射赋值
    Object c
    = tClass.newInstance();
    JSONObject object
    = new JSONObject(data); for (int j = 0; j < listKey.size(); j++) { ValueHelper helper = listKey.get(j);
    //取出实体类中的属性,根据名称与类型去jsonObject中取值,
    //具体实现接下来会讲 Object o
    = getJsonValue(helper, object);
    //赋值给该实体类,具体实现记下来会讲 setProperty(c, helper.field, o); } //返回该实体类
    return (T) c; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } return null; }

    2.1 取出实体类中的属性,根据名称与类型去jsonObject中取值

    public static Object getJsonValue(ValueHelper helper, JSONObject object) throws JSONException {
            switch (helper.type) {
                case "class java.lang.String":
                    return object.optString(helper.name, "");
    
                case "class java.lang.Integer":
                case "int":
                    return object.optInt(helper.name, 0);
    
                case "class java.lang.Double":
                    return object.optDouble(helper.name, 0);
    
                case "class java.lang.Boolean":
                    return object.optBoolean(helper.name, false);
            }
            //如果该成员变量是泛型
            if (helper.field.getGenericType() instanceof ParameterizedType) {
                ParameterizedType pt = (ParameterizedType) helper.field.getGenericType();
                //判断具体类的类型,list集合或者ArrayList
                if (pt.getRawType().equals(List.class) || pt.getRawType().equals(ArrayList.class)) {
    //那么它对应在json中的是一个jsonArray JSONArray array
    = object.getJSONArray(helper.name); //如果集合里面的泛型为String if (pt.getActualTypeArguments()[0].equals(String.class)) {
    //将该jsonArray转化为list,具体实现接下来会讲,
    //其实就相当于多次执行json转化为class,然后放入list中
    //如果泛型参数为class实体类,那我就不知道该怎么解析了,
    //不知道怎么判断里面的泛型参数是否为实体类
    //这也是我所说的没法解析所有的json数据
    List
    <String> sList = JsonArrayToList(array); return sList; } } } return null; }

    2.2 给实体类赋值

    public static void setProperty(Object c, Field field, Object value)
                throws SecurityException,
                IllegalArgumentException, IllegalAccessException {
            if (null == c || null == value)
                return;
            // 取消访问检查(私有成员变量的时候需要)
            field.setAccessible(true);
            // 给对象的成员变量赋值为指定的值--->value
            field.set(c, value);
        }

    2.3 JsonArrayToList方法

    public static <T> List<T> JsonArrayToList(JSONArray ja) {
            List<T> ret = new ArrayList();
            if (ja == null) {
                return ret;
            } else {
                for(int i = 0; i < ja.length(); ++i) {
                    try {
                        Object obj = ja.get(i);
                        if (obj != null) {
                            ret.add(obj);
                        }
                    } catch (JSONException var4) {
                        ;
                    }
                }
    
                return ret;
            }
        }

    3、将jsonArray转为list<class>,注意参数json是jsonArray数据,原理类似,就不再多讲

    public static <T> List<T> parseJsonArray2List(String json, Class<? extends T> aClass) {
            //反射获取所有public字段,包括父类
            List<T> list = null;
            List<ValueHelper> listKey;
            try {
                JSONArray array = new JSONArray(json);
                if (null == array)
                    return list;
    
                //获得自己的所有属性
                Field[] fields = aClass.getFields();
                if (null == fields)
                    return null;
    
                listKey = new ArrayList<>();
    
                for (Field field : fields) {
                    ValueHelper helper = new ValueHelper();
                    helper.name = field.getName();
                    helper.type = field.getGenericType().toString();
                    helper.field = field;
                    listKey.add(helper);
                }
                list = new ArrayList<>();
    
                for (int i = 0; i < array.length(); i++) {
                    JSONObject object = array.getJSONObject(i);
                    Object c = aClass.newInstance();
                    for (int j = 0; j < listKey.size(); j++) {
                        ValueHelper helper = listKey.get(j);
                        Object o = getJsonValue(helper, object);
                        setProperty(c, helper.field, o);
                    }
                    list.add((T) c);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
            return list;
        }
  • 相关阅读:
    How to install Lineage Os ROM on any Android device [2 methods]
    2017 年不可错过的开发工具 Top 50
    (OK) 华为全网通 honor 5x
    (OK) (solved) How restore /cust partition
    (OK) 华为全网通 honor 5x
    (OK) 华为全网通 honor 5x
    Chris Lattner
    (OK) 救砖:华为全网通 honor 5x
    (OK) Linux 平台 CUST.zip 制作方法
    (OK) Linux 下解包华为固件包UPDATE.APP
  • 原文地址:https://www.cnblogs.com/tangZH/p/10689536.html
Copyright © 2020-2023  润新知