JSONObject和JSONArray常见场景问题解决方案

问题背景

我们在实际的开发过程中有时会遇见需要处理很复杂的JSON数据的情况。一个JSON可能嵌套了多层的JSON数据,也有可能直接包含了一个JSON的数组数据。而直接使用JSONObject的parseObject将其转换为JSONArray又会出现不支持的问题。自己通过解析JSON生成实体又发现实体过多,一下子生成了十几个实体,一个实体只有两三个属性,造成冗余。那这种情况有什么好的处理方案呢?

解决方案

问题一:复杂JSON数据

举例我们要处理一个如下的JSON数据:

{
	"collection": {
		"native": {
			"switch": true,
			"lifecycle": 0,
			"threshold": 0
		},
		"appstart": {
			"switch": true,
			"start": 0
		},
		"battery": {
			"switch": true,
			"time": 3000,
			"interval": 100,
			"count": 1,
			"interval": 30000
		},
		"memory": {
			"switch": true,
			"time": 1500,
			"interval": 100,
			"count": 1,
			"interval": 30000
		},
		"memory2": {
			"switch": true,
			"time": 1500,
			"interval": 100,
			"count": 1,
			"interval": 30000
		},
		"net": {
			"switch": true,
			"regex": "",
			"target": ""
		},
		"web": {
			"switch": true
		},
		"picture": {
			"switch": true
		},
		"offcache": {
			"switch": true
		},
		"api": {
			"switch": true
		},
		"blank": {
			"switch": true
		}
	},
	"report": {
		"strategy": 1,
		"upload": 100,
		"WIFI": false,
		"time": 259200000,
		"onstart": false
	},
	"others": {
		"time": 1800000
	}
}

有兴趣的同学可以去一些工具里面生成一下里面的实体,会发现里面极其复杂,而这时候我们却需要将接下来的JSON通过和基础模版JSON参数比对,存在则用最新的数据,不存在的key则用基础模版参数的value并将其加入。最后产出JSON。
如果我们用通用方法,将JSON转化为实体然后再比对判空存入。一套下来不仅繁琐,而且容易出错。所以我们之间采用JSONObject的之间的相互转化,用深拷贝的方式进行复制。
思路即是,通过keySet的方式遍历JSON的key值然后根据拿到的key值去获取value,然后根据获取到的value值判断是否有下一层的JSON。如果有则进行递归操作,最终获取到最顶层的value,再进行处理。
这是一个模版的解决方法,大家可以根据自己需求稍做改动。

 private JSONObject deepMerge(JSONObject source, JSONObject target) throws JSONException {
        for (String key : source.keySet()) {
            Object value = source.get(key);
            if (!target.containsKey(key)) {
                target.put(key, value);
            } else {
                if (value instanceof JSONObject) {
                    JSONObject valueJson = (JSONObject) value;
                    deepMerge(valueJson, target.getJSONObject(key));
                } else {
                    target.put(key, value);
                }
            }
        }
        return target;
    }

问题二:JSON中存在数组

这个就比较直白了,就是JSON中存在一个数据,数据里面还可能有嵌套的JSON。下面还是来个例子给大家:

{
    "msg": "success",
    "code": 0,
    "data": {
        "results": [
            {
                "value": {
                    "result": ""
                },
                "key": "19"
            },
            {
                "value": {
                    "result": ""
                },
                "key": "18"
            },
            {
                "value": {
                    "result": ""
                },
                "key": "17"
            },
            {
                "value": {
                    "result": "default",
                    "params": ""
                },
                "key": "16"
            }
        ]
    }

可以看到这个JSON里面不仅有数组,数组里面还会嵌套一个JSON,这样的JSON解析其他大家会遇到一个JSONArray和JSONObject无法互通的问题即下面这个错误:

com.alibaba.fastjson.JSONArray cannot be cast to com.alibaba.fastjson.JSONObject

而使用JSONArray转换却发现过程中很多方法还紧紧依赖着JSONObject,使用实体又会冗余。这时候我们该怎么办呢。
大体思路就是:通过JSONObject将复杂的JSON进行逐层解析,遇到数组的时候就用JSONArray拿下来,里面具体的数据再使用JSONObject获取。大体模版如下:

JSONObject result = JSONObject.parseObject(result);
            if (Integer.parseInt(String.valueOf(result.get("code"))) == 0){
                JSONObject abData = result.getJSONObject("data");
                JSONArray tmp = JSONArray.parseArray(String.valueOf(abData.get("results")));
                for (int i = 0; i < tmp.size(); i++) {
                    JSONObject tmpResult = tmp.getJSONObject(i);
                    JSONObject tmpValue = tmpResult.getJSONObject("value");
                    if (tmpValue.containsKey("params")){
                        JSONObject tmpParams = tmpValue.getJSONObject("params");
                        if (Integer.parseInt(String.valueOf(tmpParams.get("panduan"))) >= 14){
                            panduan = Integer.parseInt(String.valueOf(tmpParams.get("panduan")));
                            shuju1 = String.valueOf(tmpParams.get("shuju1"));
                            shuju2 = String.valueOf(String.valueOf(tmpParams.get("shuju2")));
                        }
                    }
                }
            }

总结

我们在处理实际问题的时候应当多尝试新方法,努力突破自我,积累新知识,在工作中获得新的技术。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值