Java Parsing Json String Lazy Dafa

  Faced with the needs of Java to parse Json strings, there are many open source tools for us to choose, such as Google 's Gson and Alibaba's fastJson . There are plenty of articles online explaining how to use these tools. I also refer to these articles to encapsulate my own Json parsing tool class. This tool class can complete the mutual conversion between Json strings and corresponding entity class objects. It is very convenient to use, so we have been in peace with each other. Until one day I came across a new Json string parsing requirement

Parse the value of " nodesInService " from the Json string below.

{

  "beans" : [ {

    "name" :"Hadoop:service=NameNode,name=BlockStats",

    "modelerType" :"org.apache.hadoop.hdfs.server",

    "StorageTypeStats" : [ {

      "key" : "DISK",

      "value" : {

        "blockPoolUsed" : 26618108614,

        "capacityRemaining" : 204199376575,

        "capacityTotal" : 280360910848,

        "capacityUsed" : 26618108614,

        "nodesInService" : 4

      }

    } ]

  } ]

}

  According to the usual practice, it is necessary to define an entity class according to the structure of the Json string, and then use the Json parsing tool class to map the Json string into the corresponding entity object, and then read the value of " nodesInService " from the object.

  This Json string looks very complex, with arrays and objects nested within each other. In addition, the requirement only wants the value of the " nodesInService " element, and other elements don't care. At this time, my lazy cancer had an incurable attack. It feels like it is necessary for a value: define + map + read ... . It is a little bit inspiring, and there is wood? Is there a big deal? Did you use a knife to kill chickens?

  I just want an interface, pass in the original Json string and the required element name, and the interface automatically parses the value of the element and returns it to me. Fortunately , the structure of the Json string seems complicated, but there are actually only two element types " JSONObject" and "JSONArray". No matter how the two types of data are nested, they can be parsed as long as the element type and name are known. So theoretically, as long as you start from the root element and tell the interface the type and name of each level element, the program can extract the value of the last element according to the map.

 Based on the above ideas, an element description rule is formulated:

  1) Json element description rules:

    " Element Type: Element Name " , separated by ":".

  2)  Type description rules:

    AJSONArray

    E JSONObject

  3)  Use "," interval between element description items . The description items from the root element to the target element are arranged from left to right. For example, the description string of the above " nodesInService " element is " A:beans,A:StorageTypeStats,E:value,E:nodesInService ".

The source code of the Json string parsing function   using the Gson parsing tool is as follows:

    /**

     * json string parsing function

     *

     * @param targetNames

     *             target name, consisting of "target type : target name", separated by " , "

     *             target type: A : JSONArray

     *                       EJSONObject,如{"name":"value"}

     *            例如: "A:beans,A:StorageTypeStats,E:value,E:nodesInService"

     * @param rawJson

     * Json string

     * @return

     *             The value corresponding to the last target

     */

    public static String parseJson(String targetNames, String rawJson) {

        String retValue = null;

 

        String[] names = targetNames.split(",");

        if (names.length <= 0) {

            System.out.println("Error: parameter \"targetNames\" is invalid!");

            return retValue;

        }

 

        try {

            JsonParser parser = new JsonParser(); // Create a json parser

            JsonObject json = (JsonObject) parser.parse(rawJson); // Create a jsonObject object

            JsonArray jarray = null;

            for (int i=0; i < names.length -1; i++) {

                System.out.println(names[i]);

                String[] subName = names[i].split(":");

                if (subName.length != 2) {

                    System.out.println("Error: parameter \""+ names[i] + "\" is invalid!");

                    return retValue;

                }

 

                String type = subName[0];

                String jName = subName[1];

 

                switch (type) {

                    case "A":

                        if (null == jarray && null != json) {

                            jarray = json.getAsJsonArray(jName);

                            json = null;

                        }

                        else if (null != jarray && null == json) {

                            JsonElement element = jarray.get(0);

                            JsonObject json1 = element.getAsJsonObject();

                            jarray = json1.getAsJsonArray (jName);

                            json = null;

                        }

                        else {

                            System.out.println("Error: parse json string failed!");

                            return retValue;

                        }

                        break;

                    case "E":

                        if (null == jarray && null != json) {

                            JsonElement element = json.get(jName);

                            json = element.getAsJsonObject();

                            jarray = null;

                        }

                        else if (null != jarray && null == json) {

                            JsonElement element = jarray.get(0);

                            JsonObject json1 = element.getAsJsonObject();

                            json = json1.getAsJsonObject(jName);

                            jarray = null;

                        }

                        else {

                            System.out.println("Error: parse json string failed!");

                            return retValue;

                        }

                        break;

                    default:

                        System.out.println("Error: json type \"" + type + "\" is invalid!");

                        return retValue;

                }

            }

 

            String[] subName = names[names.length-1].split(":");

            if (subName.length != 2) {

                System.out.println("Error: parameter \"targetNames\" is invalid!");

                return retValue;

            }

 

            String jName = subName[1];

 

            if (null != jarray && null == json) {

                JsonElement ele = jarray.get(0);

                if (null != ele) {

                    JsonObject jo = ele.getAsJsonObject();

                    if (null != jo) {

                        retValue = jo.get(jName).getAsString();

                    }

                }

                return retValue;

            }

            else if (null == jarray && null != json) {

                retValue = json.get(jName).getAsString();

            }

            else {

                System.out.println("Error: parse \"" + jName + "\" failed!");

            }

        }catch (JsonIOException e) {

            e.printStackTrace ();

        } catch (JsonSyntaxException e) {

            e.printStackTrace ();

        }

 

        return retValue;

}

 

The function of this function can meet the needs of this specific scenario. As long as the description information string and the original Json string   from the root element to the target element are passed in, the function can directly parse the value of the target element and return it to the caller. The usage is more concise than the entity class mapping pattern.

  Careful friends looking at the source code may say, "You can't use this function. When the target element I want is an integer or a floating point type, what if you give me a String return value?" In fact, the element type is not unified. The String type is returned to simplify the complexity of describing rules and function implementations. Rather than adding a type description to the description rule, it is simpler for the caller to do a type conversion.

  Another friend said, "Your function has a bug , and the devil number in it limits the value of the array type element to the first element." Yes, the source code does have this limitation. The reason for this phenomenon is that in the requirements I have encountered, all array elements have only one value. So my lazy cancer strikes again, not implementing more preset scenarios, such as parsing out the value of the Nth element in the array, the value of all elements, or the value of an element associated with another element. The requirements of these scenarios can also be achieved using similar ideas.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326434399&siteId=291194637