资讯专栏INFORMATION COLUMN

自定义Json解析工具

DrizzleX / 3301人阅读

摘要:主要实现两个功能将解析为将数据转化为当然,里面的成员变量的名称需要与里面的一样。思路通过反射获取类里面的成员变量名称以及类型通过成员变量的名称与类型去数据中获取该对应的将通过反射赋值给对象。

此博客为博主原创文章,转载请标明出处,维权必究: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 parseJson2Obj(String data, Class tClass) {
        if (TextUtils.isEmpty(data))
            return null;
        try {
            List 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 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  List JsonArrayToList(JSONArray ja) {
        List 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,注意参数json是jsonArray数据,原理类似,就不再多讲

public static  List parseJsonArray2List(String json, Class aClass) {
        //反射获取所有public字段,包括父类
        List list = null;
        List 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;
    }

 

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/2372.html

相关文章

  • 微信小程序富文本解析wxParse Alpha0.1-支持HTML及markdown解析

    摘要:本项目由微信小程序开发论坛会员开发原文地址垂直微信小程序开发交流社区加载慢,等等微信小程序富文本解析自定义组件,支持及解析可能是第一个微信小程序富文本解析组件代码库地址示例版使用地址现状版本号目前还不太适合直接使用目前项目不 本项目由微信小程序开发论坛-WeAppDev http://weappdev.com/ 会员开发 原文地址: http://weappdev.com/t/wxp...

    daydream 评论0 收藏0
  • 深入RxEasyHttp网络库教你3分钟学会定义数据结构

    摘要:而本库就想让你通过简单的改造,快速的接入,满足你的数据结构解析,所以提出了自定义数据结构的概念。注意自定义类时其中必须写举列服务器返回的结构是和默认的标准结构一模一样,只是码为表示成功,而库中表示成功。 github源码地址:https://github.com/zhou-you/RxEasyHttp RxEasyHttp库默认ApiResult简介 在自定义ApiResult之前,先...

    Charles 评论0 收藏0
  • 仿造 Gson 的json 解析

    摘要:在测试当中兼容性表现良好,但是执行效率不如预期不及,笔者一度想要放弃该项目,但是造轮子不易,既然造了就稍微聊一聊吧,欢迎探讨进步。是一个中的接口,使用者可以自行实现该接口用以解析需要的类型,作用类似中的自定义的功能仅为预留,暂未做支持。 零 引子 0 源码 已上传 github https://github.com/mikylin-pr... 1 开发依赖 Maven : 3.3.9 ...

    tianren124 评论0 收藏0
  • 追踪解析Gson源码(1)

    摘要:版本版本简介是谷歌开源的解析工具。其实几款产品的差别都很细微,有谷歌的信仰加成,所以在这里进行一次源码分析。至于和会在后续进行追踪。 零 前期准备 0 FBI WARNING 文章异常啰嗦且绕弯。 1 版本 Gson 版本 : gson 2.8.5 IDE : idea 2018.3 2 Gson 简介 Gson 是谷歌开源的 java json 解析工具。市场上同类的开源产品还有 F...

    sewerganger 评论0 收藏0
  • node命令行小工具开发【翻译小工具

    摘要:命令行工具开发有许多命令行工具。现在我们就用来开发一个实用的命令行小工具一初探一个最简单的命令行工具首先我们新建一目录,然后执行生成文件新建一目录并在目录下创建一个执行我们可以看到终端输出。。 node命令行工具开发 NodeJs有许多命令行工具。它们全局安装,并提供一个命令供我们使用,完成相应的功能。 现在我们就用node来开发一个实用的命令行小工具 一.初探 一个最简单的命令行工具...

    Yang_River 评论0 收藏0

发表评论

0条评论

DrizzleX

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<