Solutions to JSONObject and JSONArray Common Scenarios

problem background

In the actual development process, we sometimes encounter situations where we need to process very complex JSON data. A JSON may nest multiple layers of JSON data, or it may directly contain a JSON array data. However, directly using JSONObject's parseObject to convert it to JSONArray will cause unsupported problems. I generated entities by parsing JSON and found that there were too many entities. More than a dozen entities were generated at once, and one entity only had two or three attributes, resulting in redundancy. So what is the best solution for this situation?

solution

Problem 1: Complex JSON data

For example, we want to process the following JSON data:

{
    
    
	"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
	}
}

Interested students can go to some tools to generate the entities inside, and they will find that it is extremely complicated, but at this time we need to compare the next JSON pass with the JSON parameters of the basic template. If it exists, use the latest data. If the key does not exist, use the value of the basic template parameter and add it. Finally, JSON is output.
If we use a general method, convert JSON into an entity and then compare and save it. A set down is not only cumbersome, but also error-prone. Therefore, we use the mutual conversion between JSONObjects, and use the deep copy method to copy.
The idea is to traverse the key value of JSON through the keySet method, then obtain the value according to the obtained key value, and then judge whether there is a JSON of the next layer according to the obtained value value. If there is, recursive operation is performed, and finally the topmost value is obtained, and then processed.
This is a template solution, you can make slight changes according to your needs.

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

Question 2: Arrays exist in JSON

This is relatively straightforward, that is, there is a data in JSON, and there may be nested JSON in the data. Here is an example for you:

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

You can see that there are not only arrays in this JSON, but also a JSON nested in the array. Others will encounter a problem that JSONArray and JSONObject cannot communicate with each other when parsing JSON, that is, the following error:

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

However, when using JSONArray conversion, it is found that many methods in the process are still closely dependent on JSONObject, and the use of entities will be redundant. What should we do at this time.
The general idea is: use JSONObject to analyze complex JSON layer by layer, use JSONArray to get it when encountering an array, and then use JSONObject to obtain the specific data in it. The general template is as follows:

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

Summarize

When dealing with practical problems, we should try more new methods, strive to break through ourselves, accumulate new knowledge, and acquire new technologies in our work.

Guess you like

Origin blog.csdn.net/qq_43881656/article/details/128914958