How to navigate and edit a JSON Document with JSON Pointer API

This tutorial will teach you how to navigate or modify a JSON Document using a JSON Pointer, which is available in javax.json API.

Put it simply, a JSON Pointer is a string that references an element within a JSON document. By using a JSON pointer, an application can retrieve a value, but it can modify as well a JSON document.

To create a pointer, you call the static method Json.createPointer and pass the pointer expression as an argument. The factory method returns an instance of JsonPointer.

Let’s assume you have the following JSON Document:

{
  "Actors": [
    {
      "name": "Tom Cruise",
      "age": 56,
      "Born At": "Syracuse, NY",
      "wife": null,
      "weight": 67.5,
      "hasChildren": true,
      "hasGreyHair": false,
      "children": [
        "Suri",
        "Isabella Jane",
        "Connor"
      ]
    },
    {
      "name": "Robert Downey Jr.",
      "age": 53,
      "Born At": "New York City, NY",
      "wife": "Susan Downey",
      "weight": 77.1,
      "hasChildren": true,
      "hasGreyHair": false,
      "children": [
        "Indio Falconer",
        "Avri Roel",
        "Exton Elias"
      ]
    }
  ]
}

The following snipped from a Servlet will capture the index “0” of the “Actors”Path:

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {

        try {
            PrintWriter writer = resp.getWriter();
            JsonReader jr = Json.createReader(this.getClass().getClassLoader().getResourceAsStream("data.json"));
            JsonStructure js = jr.read();
            JsonPointer jp = Json.createPointer("/Actors/0");

            JsonObject jsonObject = (JsonObject) jp.getValue(js);
            writer.println(jsonObject.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

As you can see, every pointer expression starts with “/” which means the root object. The special “/n” syntax can be used to access the nth element of an array.

The above example will obviously print:

{
  "Actors": [
    {
      "name": "Tom Cruise",
      "age": 56,
      "Born At": "Syracuse, NY",
      "wife": null,
      "weight": 67.5,
      "hasChildren": true,
      "hasGreyHair": false,
      "children": [
        "Suri",
        "Isabella Jane",
        "Connor"
      ]
    }   
  ]

You can use the containsValue to verify if a JsonPointer points to a key that exists in the JSON document. For example, if the Actor n. 0 has the “children” key in it:

JsonPointer jpChildren = Json.createPointer("/Actors/0/children");

boolean hasChildren = jpChildren.containsValue(js);

if (hasChildren)  {
    // iterate over the array
    JsonArray all = (JsonArray) jpChildren.getValue(js);
    writer.println(all.size());
     for (int ii=0;ii<all.size();ii++)
        writer.println(all.get(ii));
}

As we said, you can use a JsonPointer also to add a new value. For example, we will add a new property named “BirthDate” to our Actor n.0 :

JsonPointer jpBirthDate = Json.createPointer("/Actors/0/BirthDate");
JsonString jsBirthDate = Json.createValue("July 3, 1962");
js = jpBirthDate.add(js, jsBirthDate);

When adding elements to an array there’s a caveat though. If just add an element to an array using the above JsonPointer expression that will replace all existing array elements. The solution is to use the special “-” character at the end of the Pointer expression, which will preserve the existing Array elements. For example:

JsonPointer jpChild = Json.createPointer("/Actors/1/children/-");
JsonString jsChild = Json.createValue("New Baby");
js = jpChild.add(js, jsChild);

Then, to replace a value, you can use the replace method to change an element’s value:

JsonPointer activePointer = Json.createPointer("/Actors/0/BirthDate");
modifiedJsonObject = activePointer.replace(jsonObject, "July 3, 1972");

Finally, you can use the remove method to delete a key element from a JSON:

JsonPointer activePointer = Json.createPointer("/Actors/0/BirthDate");
modifiedJsonObject = passwordPointer.remove(jsonObject);

You can find this source code in my Github repository https://github.com/fmarchioni/mastertheboss/tree/master/json which is ready to run on WildFly.

Found the article helpful? if so please follow us on Socials