欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

自定义Json解析工具

程序员文章站 2022-05-07 23:50:03
此博客为博主原创文章,转载请标明出处,维权必究:https://www.cnblogs.com/tangZH/p/10689536.html fastjson是很好用的json解析工具,只可惜项目中要求apk体积尽量小,所以并不打算引入fastJson,只好自己写一个,遗憾的是写出的这个并没法解析所 ......

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

 

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;
    }